javascript——属性

ECMAScript 中有两种属性:数据属性和访问器属性。

数据属性

数据属性有4个描述其行为的特性:

属性都是用两个方括号定义的,比如上面的value,其实是[[value]]。[[Configurable]]为false不能通过delete删除其属性。

例子:

var person = { 
 name: "pyc" 
};

比如上面这段代码,[[value]]特性将被设置为'pyc',其他的特性都默认变为true,这就是对象表达式的默认。

有图有真相。这里的对象函数ECMAScript 5 的Object.getOwnPropertyDescriptor()就是获取给定属性的描述。接收两个参数:属性所属对象(name所属对象为person)和要读取其描述符的属性名称(name)。当然这是ECMAScript 5的方法,兼容性IE9+。

既然上面一定义属性就有默认特性,如果要修改某些特性值呢?

ECMAScript 5 的 Object.defineProperty()方法,就用来干这件事(vue框架里面经常用到哦,响应式变化。虽然据说3.0要用Proxy来代替,后面再说吧)。

三个参数:属性所在对象,属性的名字和一个描述符对象。(在谁上面改,改哪个属性,改动点是什么)。拿上面的继续举例:

Object.defineProperty(person, "name", { 
 writable: false, 
 value: "pyc" 
});
console.log(person.name); //"pyc" 
person.name = "Greg"; 
console.log(person.name); //"pyc"

其他属性根据各自的作用也是一样的。比如configurable设为false,那么就不能delete删除属性,否则会被忽略,严格模式下报错

最上面我们定义name属性通过对象字面量。如果我们通过Object.defineProperty()方法来定义属性,那么如果里面的值没指定就是上面的表格里的默认值。

访问器属性

访问器属性同样有四个特性:


最前面两个和数据属性是一样的。

还是上面的person例子,这是时候我们先用对象字面量加一个age属性。然后用定义方法加一个year属性。

person.age = 23;
Object.defineProperty(book, "year", { 
 get: function(){ 
     return this._year; 
 }, 
 set: function(newValue){ 
     if (newValue < 1995) { 
         this.age += 1995 - year; 
     } 
 } 
});

当我们获取year这个属性的时候,就会调用get方法,同理,设置year属性的时候,就会调用set方法,设置的值就会传递个newValue。set和get不一定都要指定,只是说指定其中一个另一个不可用。

有人就要问了,你这都是定义一个属性,那么我同时要设置多个属性的特性怎么弄呢?(懒惰是最大的生产力)

ECMAScript 5 又定义了一个 Object.defineProperties()方法。

接收两个参数:要修改属性所在的对象,第二个对象的属性与第一个对象中要添加或修改的属性一一对应。例如:

Object.defineProperties(person, { 
 interest: { 
     value: 'music'
 }
});

等等,一次列举就好。

其实明白一点:上面说的所有东西,其实都是对一个对象属性的描述。比如一个name属性,可不可读呢,可不可删呢之类的。

一些特性说明:

[[Configurable]]

 关于这个特性,有几个需要注意的地方。

1、使用var生命的变量,此特性默认为false。看下图

这也是为什么全局变量不能通过delete删除,而直接在window对象上的定义属性就可以。(特性这些小妖在作怪)

2、一旦此特性设置为false,再修改除writable之外的属性都会报错

[[value]]

只要 writable 和 configurable 有一个为 true,就允许改动。

[[writable]]

writable 只有在从 false 改为 true 会报错,从 true 改为 false 则是允许的。

最后:一个属性只能是数据属性或者访问器属性,所以均拥有 [[Configurable]] 和 [[Enumerable]] 两个特性,但是对于其他两个属性,则分别拥有,所以不可能同时有 [[Value]] 和 [[Set]],[[Writable]] 和 [[Set]] 等(如果同时定义则会报错)。

参考资料:

https://msdn.microsoft.com/zh-cn/library/hh965578(v=vs.94).aspx

https://www.cnblogs.com/zichi/p/5879291.html

猜你喜欢

转载自blog.csdn.net/viewyu12345/article/details/82994688
今日推荐