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~~~


 

posted @ 2017-01-11 20:48  _白马非马  阅读(916)  评论(0编辑  收藏  举报