<JS>Object.defineProperty(

作者: 泡沫的快乐 | 来源:发表于2017-06-14 01:24 被阅读30次

只是按照我所理解的进行说明。
该方法运行更加精确控制对象的属性。

>>语法
Object.defineProperty(obj, attr, descriptor)
1: obj:要在其上定义属性的对象。
2: attr:要定义或修改的属性的名称。只能定义一个。
3: descriptor:将被定义或修改的属性描述符(具体看下面👇)。

要同时定义多个属性可使用 Object.defineProperties()

>>属性描述符
属性描述符分为: 数据描述符 和 存取描述符.

>>数据描述符,存取描述符 共有可选键值:
configurable: 当该属性为 true 时,该属性描述符才能够被改变,该属性也能够被删除。默认为 false。
若手动设置为false,那就再也无法修改任何描述符(除writable描述符要设置为false时)!
enumerable: 当该属性 为 true 时,该属性才能够出现在对象的枚举属性中(是否能在for...in, Object.keys()中被枚举)。默认为 false。

>>数据描述符 可选键值:
value: 该属性的值。 (可以是任何JS有效值)。 默认为undefined。
writable: 概述为true时,赋值运算符赋值才会成功。默认为false。

>>存取描述符 可选键值:
get: 在获取该属性的值时 调用的函数,该方法返回值作为属性的值。 默认为undefined。
set: 在修改该属性的值时 调用的函数(默认传入修改的值)。  默认为undefined。
注意

1: 在用Object.defineProperty()设置时,只能同时对一类型描述符进行设置。否则会报错。 测试:

let o = {};
Object.defineProperty(o, 'test', {
    value:1, //数据描述符
    get(){ // 存取描述符.
        return '测试'
    }
});//会报错,因为不能同时对 两种类型的描述符进行操作.

2: 正常创建属性。描述符都会被赋值,而不是默认值。
下面用这个方法——Object.getOwnPropertyDescriptor()
查询描述符信息。测试:

let o = {
    test:1
}// 可能你会以为,描述符会被赋值为上面所写的默认值。
let info = Object.getOwnPropertyDescriptor(o,'test');
console.log(info) 
/* 显示信息如下
 * configurable:true
 * enumerable:true
 * value:1
 * writable:true 
 */
在正常创建属性时,描述符都会被赋值。 大概情况为:
configuraable, enumerable, writable, 赋值为true.
value为所赋的值.

3: 描述符会被赋值为默认值的情况

>>数据描述符 设置为默认值
let o = {}  // 在使用↓方法时,没有写的描述符,会被赋值为默认值。
Object.defineProperty(o, 'test', {}); //默认设置数据描述符
let info = Object.getOwnPropertyDescriptor(o,'test'); //获取描述符信息
console.log(info) 
/* 显示信息如下
 * configurable:false
 * enumerable:false
 * value:undefined
 * writable:false
 */
set, get方法应该还是正常返回值,修改值。

>>存取描述符 设置为默认值
let o = {};
Object.defineProperty(o, 'test', {
    set(){} // 因为默认会设置数据描述符的默认值,所以设置下get, 让set为默认值。
})
let info = Object.getOwnPropertyDescriptor(o,'test');
console.log(info);
/* 显示信息如下
 * configurable:false
 * enumerable:false
 * set:function set() //我手动设置的
 * get:undefined //默认值
 */

重点:如果属性是通过此方法设置的,那么没有主动设置的描述符键值,它会被设置为,默认值(导致属性无法访问,无法修改)。
所以要记得在使用此方法定义属性时,给必要描述符键值进行设置,除非默认值符合你预期。
>>实践
简单写一个数据双向绑定.(不需要记忆,只是展示其功能)
function getAndSet(obj, attr, getFn, setFn){
    let nowVal = obj[attr];
    Object.defineProperty(obj, attr, {
        configurable:true,
        enumerable:true,
        get(){
            getFn(nowVal) // 在获取时调用的方法
            //可以写DOM操作,使其在数据改变的时候,DOM相应改变
            return nowVal
        },
        set(newVal){
            setFn(newVal, nowVal) // 在修改时调用的方法
            //可以写DOM操作,使其在数据改变的时候,DOM相应改变

            nowVal = newVal;
            return newVal
        },
    })
}
let o = {
    test:1
};
getAndSet(o, 'test', function(nowVal){
    console.log(`get方法! 值:${nowVal}`)
},function(newVal, nowVal){
    console.log(`set方法! 新值:${newVal},原值:${nowVal}`)
})
o.test // get方法! 值:1
o.test = 4 // set方法! 新值:4,原值:1

当属性值是对象时,函数就没效果了。毕竟只是简单的实现,你可以让其的所有属性再次去调用此方法。
更加复杂,强大的实现,可以去学Vue框架。

以上是我所知的的东西,有任何错误,请在评论指出!
O(∩_∩)O谢谢你的观看~

相关文章

  • <JS>Object.defineProperty(

    只是按照我所理解的进行说明。该方法运行更加精确控制对象的属性。 >>语法 要同时定义多个属性可使用 Object....

  • <JS>学习笔记(Object)

    新人学习JS的日记。 欢迎各位朋友纠错! 以下内容都在谷歌浏览器进行测试可用一些方法是ES6的,要用babel转码...

  • <JS>学习笔记(String)

    新人学习JS的日记。 欢迎各位朋友纠错! 以下内容都在谷歌浏览器进行测试可用 >>语法 >>属性 >>方法 (1)...

  • <JS>学习笔记(Array)

    新人学习JS的日记。 欢迎各位朋友纠错! 以下内容都在谷歌浏览器进行测试可用一些方法是ES6的,要用babel转码...

  • <JS>手动实现call, apply, bind

    先分析下3个方法的作用 改变this的指向。 传入参数。 call apply返回函数结果, bind 返回新函数...

  • Read a story

    This is a lion. lt's big. lt's strong. lt has big teeth. ...

  • Mybatis中特殊符号转移

    1. 写法1 原符号替换符号<<<=<=>>>=>=<><>&&'&a...

  • <JS>学习笔记(基础:数据类型)

    新人学习JS的日记。 欢迎各位朋友纠错! 以下内容都在谷歌浏览器进行测试可用 声明变量 数据类型 Undefine...

  • object.defineProperty()

    Object.defineProperty()讲解 **Object.defineProperty()** 方法会...

  • Read a story

    lt's hot?? lt's cool here. lt's a hat. What's this? Do yo...

网友评论

    本文标题:<JS>Object.defineProperty(

    本文链接:https://www.haomeiwen.com/subject/owxjqxtx.html