JavaScrpit高级程序设计之访问器属性踩坑

94 阅读1分钟

书上的例子

var book = {
    _year: 2004,      // ①
    edition: 0
}
Object.defineProperty(book,"year",{  // ②
    get: function(){
        return this._year;
    },
    set: function(newValue){
        if(newValue > 2004){
            this._year = newValue;
            this.edition += newValue - 2004
        }
    }
});
book.year=2005;
console.log(book.year);  // 2005
console.log(book.edition); // 1

菜鸡的我在这里,被①处的_year和②处的year给迷惑了,书上还加了一句"_year前面的下划线是一种常用的记号,用于表示只能通过对象方法访问的属性",弄得我还以为_year和year是同一个东西

首先_year和year不是同一个东西,year是在_year,edition之后又新加的一个属性

验证

var book = {
    _year: 2004,
    edition: 0
}
Object.defineProperty(book,"year",{
    get: function(){
        console.log("get ");  // 新加语句
        return this._year;
    },
    set: function(newValue){
        if(newValue > 2004){
            console.log("set "); // 新加语句
            this._year = newValue;
            this.edition += newValue - 2004
        }
    }
});
book.year=2005;
console.log(book.year);
console.log(book.edition);
结果:
set 
get 
2005
1
/* 进入了get  set */


// 将上面的book.year换成book._year  
book._year=2005;
console.log(book._year);
console.log(book.edition);
结果:
2005
0
/**  根本就没有进入get 和 set 说明book.year,book._year就不是同一个东西 **/

将Object.defineProperty(book,"year",{...})中的"year"替换成"_year"在测试

var book = {
    _year: 2004,
    edition: 0
}
Object.defineProperty(book,"_year",{
    get: function(){
        console.log("get ");
        return this._year;
    },
    set: function(newValue){
        if(newValue > 2004){
            console.log("set ");
            this._year = newValue;  // ③
            this.edition += newValue - 2004
        }
    }
});
book._year=2005;
console.log(book._year);
console.log(book.edition);
结果:
一直打印 set 到爆栈
说明在代码③处 this._year = 导致一直访问set

书上说 是使用访问器属性的常见方式,即设置一个属性的值会导致其他属性发生变化
我的理解: 设置的属性A 若对象里已有A 在使用get方法 不要获取A的值,要不然一直访问get方法 在set方法里面 不要对A复制 要不然一直访问set方法