Skip to content

[[get]]、[[put]]以及getter,setter

camiler edited this page Feb 10, 2017 · 6 revisions

Getter和Setter

js对象中的**属性存取(access)**描述符,如果某个对象的属性定义了存取描述符,value 和 writable会被忽略(也就是说,如果你同时定义value&&(getter||setter),或者是(getter||setter)&&writable将会报错或者忽略),JavaScript 只会考虑 Getter, Setter, configurable, 和 enumerable。

[[get]]机制

JavaScript 内置的 Get 操作首先根据属性名称检查对象本身是否有该属性,如果这时候找到了,那么就返回它的值;如果没找到,那么会通过该对象的 Prototype 链继续向上查找,直到顶层的 Object.prototype.

[[put]]机制

  1. 该属性是否已经定义了 Setter,如果已经定义了,那么调用它;
  2. 该属性的属性描述符 (Property Descriptor)是否定义了 writable: false,如果是,那么赋值操作被忽略,如果是 strict mode,那么会抛出TypeError 异常;
  3. 如果没有上述情况,那么给已存在的属性赋值。

代码说明

var obj = {
  a: 1,
  get b(){
    return this._b;
  },
  set b(val){
    this._b = val + 2;
  }
}
console.log(obj.a); //1
obj.b = 3;
console.log(obj.b); //5
Object.defineProperty(obj, 'x', {
  enumerable: true,
  get: function(){
    return this.b * 2;
  },
  set: function(val){
    console.log('put时判断是否有setter,进入setter:');
    this._x = val * 3;
    console.log("调用setter结果:" + this._x);
  }
})
console.log(obj.x); //10
obj.x = 2; // 参考[[put]]操作规则1
console.log(obj.x); //10  上面虽然进行了[[put]]操作,但是[[get]]时返回的是b*2, 只和b有关。

(function(obj){
  'use strict';
  Object.defineProperty(obj, 'y', {
    value: 'y',
    writable: false
  })
  console.log(obj.y); //'y'
  obj.y = 3; //非严格模式下,这里会被忽略;严格模式下,抛出TypeError异常
  console.log(obj.y); //非严格模式:'y',上一句[[put]]被忽略了
})(obj);

上面代码运行结果查看jsbin