当执行 一个对象赋值操作的时候 JS 引擎会怎样处理呢???
例如 有个 foo 对象 , 要进行这个操作 foo.a=2
1, 首先会在 foo 对象中查找, 如果不存在 a 属性, 就会去原型链上面找, 如果原型链上面也不存在该属性, 就会在 foo 对象中创建一个 a 属性并且值为 2
2 , 如果 foo 对象中不存在, 在原型上层找到了 a 属性, 之后会进行一下三种情况:
1, 如果原型上层的 a 属性是普通数据属性, 且不是只读属性, 那么就会在 foo 对象中创建一个 a 属性并且值为 2, 屏蔽了原型上层的 a 属性
2, 如果原型上层的 a 属性是只读属性, 那么该操作会被忽略, 在严格模式下, 会报错
3, 如果原型上层的 a 属性是存储器属性, 那么就会调用 setter 方法, 不会在 foo 对象中创建 a 属性, 也不会重新定义 a 这个 setter
下面是些例子:
- // var obj={
- // a:1,
- // b:2,
- // }
- // 第一种情况
- var obj1={
- // 数据属性
- c:2,
- d:3,
- e:function(){
- return this.c;
- }
- }
- // obj.__proto__=obj1;
- function f(){
- this.a=1;
- this.b=2;
- }
- f.prototype=obj1;
- var obj=new f();
- console.log(obj.d);//3
- obj.d=6;
- console.log(obj.d);//6
- console.log(obj1.d);//3
- // 第二种情况
- Object.defineProperty(obj1,'ff',{
- value:11,
- writable:false,
- configurable:true,
- enumerable:true
- })
- console.log(obj.ff);//11
- obj.ff=33;
- console.log(obj.ff);//11
- console.log(obj1.ff);//11
- // 第三种情况
- Object.defineProperty(obj1,'g',{// 访问器属性
- get:function(){
- return this.c
- },
- set:function(val){
- console.log("我被执行了");
- this.c=val
- },
- })
- console.log(obj.g);//2
- obj.g=22;
- console.log(obj.g);//22
- console.log(obj1.g);//2
总结的方法:
for...in.. 遍历对象中所有可枚举的属性 (包括自有属性和继承的属性)
Object.keys() 返回值是数组, 由对象中可枚举的自有属性名称组成
Object.getOwnProperty() 返回对象的自有属性 (括可枚举和不可枚举)
Object.hasOwnProperty(x) 检测 x 是否是对象的自有属性, 对于继承的属性它返回 false
Object.isPrototypeof(x) 检测某对象是否是 x 对象的原型 (或处于原型链中)
Object.propertyIsEnumerable(x) 检测 x 属性是自有属性且这个属性是可枚举的它返回 true
Object.getOwnPropertyDescriptor(obj, prop) 可获取某对象的自有属性的属性描述符
Object.getOwnPropertyNames() 返回对象的所有自有属性名称 (包括可枚举和不可枚举)
Object.getPrototypeof(x) 可以查询 x 的原型
数据属性四个特性
1)configurable: 表示能否通过 delete 删除属性从而重新定义属性, 能否修改属性的特性, 或能否把属性修改为访问器属性, 默认为 true
2)enumerable: 表示能否通过 for-in 循环返回属性
3)writable: 表示能否修改属性的值
4)value: 包含该属性的数据值. 默认为 undefined
存储器属性四个特性
1)configurable: 表示能否通过 delete 删除属性从而重新定义属性, 能否修改属性的特性, 或能否把属性修改为访问器属性, 默认为 true
2)enumerable: 表示能否通过 for-in 循环返回属性
3)set: 写入
4)get: 读取
来源: http://www.bubuko.com/infodetail-3064071.html