属性的设置和获取

来源:互联网 发布:崩坏学园3外传知返 编辑:程序博客网 时间:2024/06/04 18:37

属性描述符(元属性)

含义:对象的属性的属性(可读,可写,可更改),也可以称之为 对象的属性的属性描述符。
- 属性描述符:

Object.getOwnPropertyDescriptor(obj,"name");

第一个参数:对应的对象
第二个参数:对应对象的属性
返回得到的值,为这个对象属性的属性状态 writable,enumberable,configurable,value
- writable:可读写+value(写在对象中)
- enumberable:可枚举
表示属性能不能出现在对象的for in循环中
- configurable :可配置
可用来重定义

为对象新增或修改属性

  • 使用字面量定义对象,属性描述符的默认值都是true
var obj={    name:"snw"};//获取对象属性的属性var result = Object.getOwnPropertyDescriptor(damu,"wife");console.log(result);//返回值为configurable:true enumerable:true value:"snw" writable:true 
  • 使用定义属性的方法,属性描述符的默认值都是false
Object.defineProperty(对象,"对象的属性",{            value:"xiaohua"  //属性值            <!--可定义属性的属性状态-->        })var result = Object.getOwnPropertyDescriptor(llc,"wife");console.log(result);//返回值为configurable:false enumerable:false value:"snw" writable:false      
  • 使用var定义和没有使用var定义的属性描述符,的区别就是使用var定义configurable:false
var a =2;b=3;var result1 = Object.getOwnPropertyDescriptor(window,"a");//它的返回值中configurable:false,其余的都是trueconsole.log(result1);var result2 = Object.getOwnPropertyDescriptor(window,"b");//它的返回值属性描述符全都是trueconsole.log(result2);
  • writable
    当writable为false时,对应的属性的值是无法修改的。
    在默认情况下:
    继续修改的话会静默失败
    在严格模式下(“use strict”):
    会报错
  • configurable来决定属性是否可以配置
    当configurable为false时,对应的属性是无法重新定义和无法删除的。但该对象是还可以继续添加属性的。不管是默认情况还是严格模式底下,进行重新定义和删除都会报错
    • 注意一个小小的例外:
      当configurable为false时,writable可以进行重新定义,但只满足由writable:true ==> writable:false
      configurable:不能修改
      enumerable:不能修改
  • enumerable 枚举(可遍历)
Object.defineProperty(obj,"a",{//将属性a设置为可以枚举的对象            enumerable:true        })//判断这个对象的属性是否可枚举,返回值为ture/false对象.propertyIsEnumerable("属性"));不会遍历原型链//将对象中可以枚举的属性,全都输出Object.keys(对象);不会遍历原型链//将对象中的属性全都输出Object.getOwnPropertyNames(对象);不会遍历原型链
  • 对象常量属性
    将属性的writable和configurable设置为false
    但在这个情况下,虽然不能配置和修改,但是还可以增加新的属性。
  • 禁止对象扩展
Object.preventExtensions(obj);

由于属性描述符是对属性的管理,所以想禁止对象扩展不能使用属性描述符来控制,而是需要调用Object.preventExtensions(obj);
参数(obj):要求禁止扩展的对象

默认情况下:
为对象添加新的属性会静默失败
严格模式底下:报错
* 注意:禁止对象扩展只是禁止了对象去扩展属性,而之前的属性是可以进行重新定义或者删除的,属性值也是可以修改的。
- 密封对象(也可以禁止对象扩展)

Object.seal(obj)  

在禁止对象扩展(Object.preventExtensions(obj);的基础上把现有属性的configurable调整为false

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

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

Object.freeze(obj)

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

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

冻结之后禁止了对象去扩展属性,原有的属性不可以进行重新定义或者删除,属性值也不可以进行修改
- 注意:在js中,所有方法的创建都是浅不变形的,他们只会影响目标对象和他的直接属性。只能影响对象的直接属性。没有办法作用到对象的深层属性,没有办法作用到对象隐式原型链上的属性
例如:

var obj={    arr:{        num1:1,        num2:2,        num3:3        }    };/*Js操作的对象都是他的目标对象和直接属性,当密封和冻结这个对象的时候,只是对直接属性arr做的操作,num的属性还是可以操作*/
  • 有length属性的均为伪数组
//创建一个长度为3的伪数组var arr={length:3,        num1:1,        num2:2,        num3:3}
  • 将伪数组转变为数组
var arr =Array.prototype.slice.call(伪数组名);或var arr =[].slice.call(伪数组名);
  • 属性
    • 属性描述符:描述属性的属性(元属性)
    • 数据描述符:带有value和writable属性描述符的属性
    • 访问描述符:带有set和get属性描述符的属性,对于访问描述符来说,Javascript会忽略他们的value和writable特性。取而代之的是set和get
      具有set和get属性描述符的属性我们称为访问描述符
      作用:
      使用属性的操作更安全可控(封装)
      函数。
  • 存在性检查

    • in操作符:会遍历原型链

    • obj.hasOwnProperty(“a):不会遍历原型链,只在对象中查找

  • 属性的查找 get属性查找的算法
    1,在对象中查找是否具有相同名称的属性,如果找到了,就会返回这个属性的值。
    2,如果没有找到,则遍历原型链
    3,无论·如何都没找到,返回undefined
    • 注意点:如果是访问描述符,就看get函数,返回的值为get函数中的相关内容。
  • 属性的设置 put属性设置的算法
    • 如果属性直接存在于对象中,不在原型链上
      找到直接存在于对象中的属性
      • 数据描述符(没有setter/getter):
        直接修改对象中的属性(注意writbale的值)
      • 访问描述符:
        直接调用set方法
    • 如果属性直接存在于对象中 , 也在原型链上
      找到直接存在于对象中的属性
      • 数据描述符(没有setter/getter):
        直接修改对象中的属性(注意writbale的值)
      • 访问描述符
        直接调用set方法
    • 如果属性不直接存在于对象中也不在原型链上
      在对象的直接属性中添加一个属性(数据描述符)默认情况下,它的属性描述符都是true
value:"a"writable:trueconfigurable:trueenumerable:true

    • 如果属性不直接存在于对象中 , 在原型链上
      • 该属性(原型链)是数据描述符(没有setter/getter)
        • writbale为true:
          直接在对象中添加一个属性,我们称之为屏蔽属性
        • writbale为false:
          不会生成屏蔽属性
Object.prototype.age=10;/*原型对象默认情况下都是true,将对象中的属性进行了重新定义*/Object.defineProperty(Object.prototype,"age",{    writable:false});console.log(Object.getOwnPropertyDescriptor(Object.prototype,"age"));    var obj={};/*当都为true时,可以向对象中添加数据;当writable:false时,添加不上属性,添加属性的语句会静默失败*/    obj.age=50;//静默失败console.log(obj);console.log(Object.prototype);

      • 该属性是访问描述符
        调用set,不会生成屏蔽属性
        当有get时,才会向对象中添加属性。
原创粉丝点击