• Javascript中对象的Obeject.defineProperty()方法-------------(ES5/个人理解)


    在讲到Obeject.defineProperty()方法之前先得说明一下ECMAScript中有两种属性:数据属性访问器属性 

    两种属性存在的意义:描述对象属性(key)的一些特性,因为这些属性是内部值,一般放到 [[两个中括号]]  中。

    Object.defineProperty(obj , 'key' , {描述信息,是个对象,类似配置项} )  方法接收三个参数,属性所在的对象属性名 和一个描述符对象

    数据属性的描述符是下面的一个或者多个(configurable、enumerable、writable 和 value)

    访问器属性的描述符是以下的一个或多个(configurable、enumerable、get 和 set)

    通过 Object.defineProperty() 方法,可以创建数据属性(并设定其内部属性),也可以创建访问器属性(访问器属性包含 getter 和 setter函数)

    数据属性的各项解释:

    enumerable : 可枚举性,是否能通过for-in或者Object.keys来遍历

    writable : 可修改(可写入),是否能修改value属性值

    value : 属性的属性值  (读出和写入都是从这里读出和保存的),默认undefined    数据属性是可以直接通过  对象.属性obj.key 的形式访问和赋值

    configurable : 是否可配置,当它为false的时候,1、上面三项的true和false值都不能改变了,2、对象本身也不能通过delete来删除3、数据属性和访问器属性也不能来回转化了

    访问器属性的各项解释:

    configurable 、enumerable同上

    get : 读取属性的时候调用,默认值undefined

    set : 设置属性的时候调用,默认值undefined

    对比数据属性和访问器属性的属性异同

    数据属性作用:   修改属性默认的特性 (会新建出数据属性)

    访问器的作用:  访问和设置数据属性的属性值,不会创建出  .

    1、对象属性创建对比-----   这里创建的是数据属性不是访问器属性,访问器属性只有一种创建方式

    A、字面量创建对象的形式:var obj = {key : value }                ------   var person1 = {age : 3}  直接创建了age属性和属性值

    B、Object.defineProperty(obj ,'key' {...} )创建对象               ------   var person2 = {};   Object.defineProperty(person2, "age", { value: 3 }); 

    通过统一的操作 :

    ①  console.log(person1 .name)   ②  person1.age = 4   ③   console.log(person1 .name)   得出  // 3 , 4   赋给了新的值

    ①  console.log(person2 .name)   ②  person2.age = 4   ③   console.log(person2 .name)   得出  // 3 , 3   赋值没有成功

    原理:

    直接在对象上定义的属性var obj = {key : value }(字面量形式和new Object()形式) ,它们的Configurable、Enumerable 和Writable特性都被设置为 true,而Value特性被设置为指定的值

    通过 Object.defineProperty()定义的属性 它们的Configurable、Enumerable 和Writable特性都被设置为 false,而Value特性被设置为指定的值,这时候的属性值是只读的

     

    2、重点:数据属性不仅可以直接访问和设置(对象.属性/obj.key的形式),也可以通过定义的访问器(getter setter)来专门访问和设置

    得出结论:

    ① 通过发现book下面并没有真正的year属性,证明了数据属性并不能根据访问器属性来定义创建,访问器属性只是操作访问器属性,这个属性可以理解为是在get和set这一动态读取和设置的过程中发挥作用。

    setget是一对勾子(hook)函数,要理解触发机制(是根据调用book.year或者设置book.year=2005这个时间点触发的,所以这个year可以随便取值):就是访问器属性在调用时,实际上对应触发访问器属性中定义的 get 方法(最后返回的值是其中return出来的结果),当对一个对象的某个属性赋值时,则会自动触发调用相应的set函数。(如果不了解运行机制,需要打断点走一遍即可)

    ③ book只有_year和edtion两个数据属性(是不是数据属性,要看带不带value属性),year不是数据属性(访问属性不包含数据值,也不会显式的写出来),但是但是book.hasOwnProperty("year"); 确实返回 true。说明了访问器属性也属于对象自己添加的属性。只是读写方式和普通的不一样。

    ④ _year带有下划线的属性,表示只能通过  对象方法 访问的属性。(有待补充。。。。)

     

    3、再来撸一遍代码,看看运行的原理具体是怎样的??

    访问器将真正存值的变量隐藏起来,并提供对外的接口,当你读取或设置属性时,可执行一定的操作:
     
    上列中set的参数就是你设置的值。从外部看,你设置man.age的方式与赋值无异,这与el.style.color = "red"相似:看上去是简单的赋值,却触发了一定行为(设置DOM文本为红色)。

      

    4、怎么区分数据属性还是访问器属性???看里面的描述符对象。两者是不能混用的。

     

    5、js中的属性的理解: 

    javascript中一共有三种属性:

    普通属性:也就是常规的数据属性,这种属性是用户来添加修改等,把它设置成什么样,就返回出来什么样,不会做些额外的事情。 var obj ={name : "yang"};那么console.log(obj.name) //yang

    内部属性:比如数组arr的length属性,函数的prototype属性,DOM节点的innerHTML属性,用户赋完值以后,取值的时候,不一定按预期,有时候还会额外的做一些事情,也难以改变他们的行为。

        比如说某一数组,它的长度为10, 当我们设置它为11时,它就会增加一个undefined元素,再设置为9时,就会从后面删掉两个元素。

        函数的prototype如果被改变,相当于将其父类改变了,会new不同类型的实例。

        DOM的innerHTML,我们赋值时是一个字符串,再取出时,这字符串可能会与原来的不一样, 并且在原元素上生成了不一样的子节点。

    访问器属性,允许用户在赋值或取值都经过预先设定的函数,从而实现内部属性的那一种特殊效果。

    6、应用(可以代替对象中的getter和setter函数)

        ==    

    其他地方:vue框架MVVM的数据双向绑定,数据的实时观察,不同于angular使用的脏检查。

     7、和Object.defineProperty()相关的一些对象方法。

    obj.propertyIsEnumerable('key')

    obj.hasOwnProperty('key')    可以检测出访问器属性

    Obeject.getOwnpropertyDescriptor(obj , 'key')   或者描述符对象  -----   有就返回对象,否则是undefined。

    Object.keys(obj)方法,遍历key值 。   当Object.defineProperty()中enumerable为false的时候,是遍历不出来的。

     

    8、其他

    Obeject.prototype的configurable是false,代表不可配置

    对象obj的toString方法是原型链上的是不可枚举的   obj.propertyIsEnumerable(toString')     // false 

      

    最后:不要再IE8 及以前版本 中使用 Object.defineProperty() 

  • 相关阅读:
    ES6 数值
    ES6 字符串
    ES6 Reflect 与 Proxy
    ES6 Map 与 Set
    es6 Symbol
    新兴的API(fileReader、geolocation、web计时、web worker)
    浏览器数据库 IndexedDB 入门教程
    离线应用与客户端存储(cookie storage indexedDB)
    javascript高级技巧篇(作用域安全、防篡改、惰性载入、节流、自定义事件,拖放)
    ajax与comet
  • 原文地址:https://www.cnblogs.com/faith3/p/6139301.html
Copyright © 2020-2023  润新知