js访问器属性之小问题
看js访问器属性时候 有这样一段代码
var book = { _year: 2004, edition: 1 } Object.defineProperty(book, 'year', { get: function () { return this._year; }, set: function (val) { if (val > 2004) { this._year = val; this.edition += val - 2004; } } }); book.year = 2005; console.log(book.edition); console.log(book.year); console.log(book._year);
书中说’ _year ‘表示是一种常用标记。表示只能通过对象访问的属性。
所以我认为它只是一种标记,可以更改 于是乎我就把'_year' 改成了 ‘year'
var book = { year: 2004, edition: 1 } Object.defineProperty(book, 'year', { get: function () { return this.year; }, set: function (val) { if (val > 2004) { this.year = val; this.edition += val - 2004; } } }); book.year = 2005; console.log(book.edition); console.log(book.year); console.log(book.year2);
可是却爆了这样一个错误
Uncaught RangeError: Maximum call stack size exceeded 翻译过来就是堆栈溢出了。。。
这个问题先搁置,我们再试一下'_year' 改成了 ‘year2’
var book = { year2: 2004, edition: 1 } Object.defineProperty(book, 'year', { get: function () { return this.year2; }, set: function (val) { if (val > 2004) { this.year2 = val; this.edition += val - 2004; } } }); book.year = 2005; console.log(book.edition); console.log(book.year); console.log(book.year2);
这次又好了。所以我认为书中’year‘有些迷惑人
再来一个终极版本
var book = { year: 2004, edition: 1 } Object.defineProperty(book, 'updateAll', { get: function () { return book;//此处可以自定义 别人访问时候返回什么,如果什么都不写 就代表这个属性不让访问 }, set: function (val) { if (val > 2004) { this.year = val; this.edition += val - 2004; } } }); book.updateAll = 2005; console.log(book.edition); console.log(book.year); console.log(book.updateAll);
总结:原来访问器属性,(不是对象属性) 名字随意起名。它的作用就是 决定 你访问或者设置 这个属性的时候 是拒绝,还是做很多事情,比如更新本对象的全部属性,等等。。
至于刚才内存溢出,就是因为我们 访问器属性的名字 和对象属性的名字一样了, 所以在 这一句 <pre>this.year = val;</pre> 的时候 我们本意是打算调用对象属性,但实际上它又调用了 访问器属性,形成了递归。so~~~