设置前Javascript setter覆盖值

时间:2016-12-11 20:06:05

标签: javascript

我基本上想做的是:

Blog.prototype = {
  set content(content) {
    this.content = JSON.parse(content);
  }
}

但是,这会导致无限递归。

我知道我可以这样做:

  set content(content) {
    this._content = JSON.parse(content);
  },

  get content() {
    return this._content;
  }

但是,当我执行JSON.stringify(blog)时,它不会包含content,但包括_content,这是不受欢迎的。

我该怎么做呢?

3 个答案:

答案 0 :(得分:4)

使“_content”变量不可枚举。

Blog.prototype = {
  set content(newContent) {
    Object.defineProperty(this, "_content", { 
      value: JSON.parse(newContent), 
      writable: true 
    });
  },
  get content() {
    return this._content;
  }
};

默认情况下,如果未在false的调用中明确提供,则对象属性的“enumerable”标志为defineProperty()

有一天,Symbol类型将得到普遍支持,并且它是更好的选择,因为你可以通过这种方式创建一个有保证的唯一属性键。如果您不需要IE支持并且可以使用符号:

Blog.prototype = () => {
  const internalContent = Symbol("content key");
  return {
    set content(newContent) {
      this[internalContent] = newContent;
    },
    get content() {
      return this[internalContent];
    }
  };
}();

JSON.stringify()会忽略符号键控属性,因此您无需担心defineProperty()。 Symbol方法的优点在于您不必担心碰撞。从Symbol()返回的每个Symbol实例都是不同的。

答案 1 :(得分:1)

使用设置和获取_content,并实施.toJson()JSON.stringify代替content提供_content

toJSON() {
  return {
    content: this._content
  }
}

根据MDN .toJSON()角色是:

  

如果要进行字符串化的对象具有名为toJSON的属性,其值为   是一个函数,然后toJSON()方法自定义JSON   字符串化行为:而不是被序列化的对象,   调用时toJSON()方法返回的值将被序列化。

使用构造函数



function Blog() {}

Blog.prototype = {
  set content(content) {
    this._content = JSON.parse(content);
  },

  get content() {
    return this._content;
  },
  
  toJSON() {
    return {
      content: this._content
    }
  }
};

var blog = new Blog();

blog.content = '{ "a": "5" }';

console.log(blog.content);

console.log(JSON.stringify(blog));




使用ES6课程



class Blog {
  set content(content) {
    this._content = JSON.parse(content);
  }

  get content() {
    return this._content;
  }
  
  toJSON() {
    return {
      content: this._content
    }
  }
};

const blog = new Blog();

blog.content = '{ "a": "5" }';

console.log(blog.content);

console.log(JSON.stringify(blog));




答案 2 :(得分:1)

我能够通过建立Pointy的答案来解决这个问题:

var Blog = function () {
  var content;

  Object.defineProperty(this, "content", {
    get: function() {
      return content;
    },
    set: function(value) {
      content = JSON.parse(value);
    },
    enumerable: true,
  });
};

这里的诀窍是enumerable标志,默认为false。