第三章 属性高级

您所在的位置:网站首页 mathcopy 第三章 属性高级

第三章 属性高级

2023-02-06 14:14| 来源: 网络整理| 查看: 265

一、属性描述符 1.获取对应属性的描述符 属性描述符:属性的特征;也叫元属性;修饰属性的属性

Object.getOwnPropertyDescriptor(obj,"name"); 第一个参数:对应的对象 第二个参数:对应对象的属性

  var obj={   name:"wql",   age:38,   wife:"lss"   }   var res=Object.getOwnPropertyDescriptor(obj,"wife");   console.log(res) //res是一个对象 { configurable: true enumerable: true value: "lss" writable: true __proto__: Object }

 

2.为对象新增或修改属性 var obj={ name:"snw" }; Object.defineProperty(obj,"age",{ value:18, writable:true, configurable:true, emumerable:true }); console.log(obj); //Object {name: "snw", age: 18} console.log(obj.age);//18 属性描述符的默认值都是false

 

3.writable(可写的) writable决定是否可以修改属性的值 当writable为false时,对应的属性的值是无法修改的。 // writable为false 时 configurable一般也为false 在默认情况下: 继续修改的话会静默失败 在严格模式下: 会报错

var obj={ name:"Lebron", age:33, team:"湖人"}//obj.team="骑士"; 位置在这儿能被修改Object.defineProperty(obj,"team",{ writable:false})obj.team="热火";console.log(obj);

 

4.configurable(可配置的) configurable来决定属性是否可以配置可配置:属性能否重新定义 属性能否删除 当configurable为false时,对应的属性是无法重新定义的,无法删除的。但该对象是还可以继续添加属性的。 默认情况下 进行重新定义会报错 进行删除会静默失败 注意一个小小的例外: 当configurable为false时,writable可以进行重新定义,但只满足由writable:true ==> writable:false

   var obj={        name:"zyy",        age:20,        hobby:"eat"      }      Object.defineProperty(obj,"hobby",{       //value:"play",         writable:true,         configurable:false,         enumerable:false     })      delete obj.hobby;      console.log(obj);

 

5.enumerable //enumerable可枚举:控制了属性的可枚举权限 //可枚举:能否出现在对象的for in 循环中 var obj={ name:"zyy", age:26, behavior:"play basketball" } Object.defineProperty(obj,"behavior2",{ value:"eat", enumerable:false }) for(var item in obj){ console.log(item); } 6.严格模式 function test() { "use strict" inner(); function inner() { console.log(this) } } (function () { "use strict" test() })()

 

7.属性的指定方式 /*属性的指定方式: 1. 字面量初始化的时候直接通过 键值对的形式指定 属性描述符的默认值基本都是true 2. 通过对象点的形式来指定 属性描述符的默认值基本都是true 3. 原始的指定形式的方式 ` 属性描述符的默认值基本都是false value:undefined 4. var a = "a"; 给window添加的属性 configurable: false enumerable: true writable: true 5. b="b";给window添加的属性 属性描述符的默认值基本都是true */ var a = "a"; b="b"; console.log(Object.getOwnPropertyDescriptor(window,"a")) console.log(Object.getOwnPropertyDescriptor(window,"b")) delete a; delete b; console.log(a); console.log(b);

 

8.存在性检查 var obj={ a:undefined, wife:{ name:"xxx" } }; console.log(obj.a); //in关键字 会影响对象的直接属性 也访问原型链 可是不访问对象的深层属性 console.log("a" in obj) console.log("b" in obj) console.log("toString" in obj) console.log("name" in obj,"------") //在js中所有的方法都是 浅不变形 的;只会影响对象的直接属性 不访问原型链 也不访问对象的深层属性 console.log(obj.hasOwnProperty("a")); console.log(obj.hasOwnProperty("b")); console.log(obj.hasOwnProperty("toString")); console.log(obj.hasOwnProperty("name")); var res = Object.getOwnPropertyNames(obj); console.log(res);

 

9.访问描述符(get&&set) // 属性描述符 : 属性的特征 属性的属性 // 数据描述符 : 具有writable 和 value属性描述符 的属性! // 访问描述符 : 具有set 和 get属性描述符 的属性!

    var obj={        get age(){        return obj.__age__;         },       set age(val){            if (val > 150){               val =150;       }else if(val < 0){               val =0;         }

      obj.__age__=val;       }   }

obj.age=33; console.log(obj.age);

 

二、对象不变性 1.对象常量属性 将属性的writable和configurable设置为false

      var MathCopy = {};      Object.defineProperty(MathCopy,"PI",{           value:3.141592654,           writable:false,           configurable:false,           enumerable:true      })       MathCopy.PI=1;      console.log(MathCopy.PI)

 

2.禁止对象扩展 由于属性描述符是对属性的管理 所以想禁止对象扩展不能使用属性描述符来控制,而是需要调用Object.preventExtensions(obj); 参数:要求禁止扩展的对象 默认情况下 为对象添加新的属性会静默失败 严格模式底下 报错 注意:禁止对象扩展只是禁止了对象去扩展属性, 而之前的属性是可以进行重新定义或者删除的, 属性值也是可以修改的 3.密封对象 在禁止对象扩展(Object.preventExtensions(obj);的基础上把现有属性的configurable都调整为false 调用Object.seal(obj)密封一个对象 密封之后禁止了对象去扩展属性,原有的属性不可以进行重新定义或者删除,但属性值是可以修改的

 var obj = {        a:"a",        b:'b'    };    Object.seal(obj);

       delete obj.a;       obj.c="c";       obj.a="aa";    console.log(obj);

输出:{a: "aa", b: "b"} 没有被删除,也没有添加c

 

4.冻结对象(浅)

    在密封对象(Object.seal(obj))的基础上把现有属性的writable都调整为false

    调用Object.freeze(obj)密封一个对象

   冻结之后禁止了对象去扩展属性,原有的属性不可以进行重新定义或者删除,属性值不可以进行修改

var

obj = { a:"a", b:'b' }; Object.freeze(obj); delete obj.a; obj.c="c"; obj.a="aa"; console.log(obj);

 

5.冻结对象(深) var obj = { name: "zyy", age: 20, hobby: { No1: "playball", No2: "eat", No3: "sleep" } } function deep(obj) { var keys = Object.getOwnPropertyNames(obj); keys.forEach(function (key) { var val = obj[key] if (Object.prototype.toString.call(val) === "[object Object]") { deep(val) } }); return Object.freeze(obj) } deep(obj); obj.hobby.No1="watch"; console.log(obj) 三、属性查找和设置 1.基本规则 /* 数据描述符 configurable: true enumerable: true writable: true */ // 查找: 先在对象的直接属性中找 找到了就返回 找不到上原型链 整体原型链都没有 返回 undefined // 设置: 只影响对象的直接属性

 

2.完整的规则(查找) // [[Get]]:代表的属性查找的算法 // [[Get]]: // 1.在对象中查找是否具有相同名称的属性,如果找到,就会返回这个属性的值。 // 2.如果没有找到,则遍历原型链 // 3.无论如何都没找到,返回undefined // 4.访问描述符具体看get方法的逻辑

 

3.完整的规则(设置) /* [[Put]]:代表的属性设置的算法 obj.a="a"; [[put]]: 1. 如果属性直接存在于对象中 不在原型链上 找到直接存在于对象中的属性 -数据描述符(没有setter/getter) 直接修改对象中的属性(注意writbale的值) -访问描述符 直接调用set方法 4. 如果属性直接存在于对象中 也在原型链上 找到直接存在于对象中的属性 -数据描述符(没有setter/getter) 直接修改对象中的属性(注意writbale的值) -访问描述符 直接调用set方法 2. 如果属性不直接存在于对象中也不在原型链上 在对象的直接属性中添加一个属性(数据描述符) value:"a" writable:true configurable:true enumerable:true 3. 如果属性不直接存在于对象中 在原型链上 ①.该属性是数据描述符(没有setter/getter) -writbale为true 直接在对象中添加一个属性,我们称之为屏蔽属性 (√)(√)(√)(√)-writbale为false 报错,不会生成屏蔽属性 (√)(√)(√)(√) ②.该属性是访问描述符 调用set,不会生成屏蔽属性 */ // Object.prototype.a="a"; Object.defineProperty(Object.prototype,"a",{ set:function(val){ } }) var obj={}; obj.a="aaaa"; console.log(obj,Object.prototype)

 

object

静态方法 Object.create() Object.defineProperty() Object.getOwnPropertyDescriptor() Object.getOwnPropertyNames() Object.preventExtensions() Object.seal() Object.freeze() Object.keys() 实例方法 Object.prototype.toString() Object.prototype.valueOf() Object.prototype.propertyIsEnumerable()

 



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3