邳州瞧仓盅电子科技亚博国际可信吗_es5的小方法Object.defineProperty

es5 的Object.defineProperty() 用来给一个对象定义一个属性。vue的双向绑定原理就是基于defineProperty的访问器属性实现的。

使用语法

Object.defineProperty(obj, key, descriptor)?需要定义传入三个参数,这样就可以给对象obj定义一个key。

  • obj: object类型,需要定义属性的对象
  • key: string类型,属性的名称
  • descriptor: object类型, 一个描述符,也是重点关注的参数

descriptor 参数

第三个参数是一个对象有六个键值。分别是: configurable(boolean, 默认true), enumerable(boolean, 默认true), writable(boolean, 默认true), value(any, 默认undefined), get(function, 默认undefined), set(function, 默认undefined) 。其中writable, value任意一个和get, set任一一个都不可以同时存在。为什么呢? 关于红宝书上的介绍,一上来就是一段教科书的描述,比较晦涩。将defineProperty方法定义的属性分为两种类型:数据属性和访问器属性。 所以descriptor参数的不同决定了相应的属性的类型。 故descriptor有两种方式

描述数据属性(平时用obj.name = "123", 其实就是默认用这种方式定义的):

{
    configurable: false, // 默认为true, 描述能否被改变,比如delete或者修改成访问器属性
    enumerable: false, // 默认为true, 描述能否被 in 枚举,比如for-in
    writable: false, // 默认true, 描述是否能被更改
    value: [1, 2, 3], // 默认undefined, 就是属性的值
}

描述访问器属性

configurable: false, mo ren wei true, miao shu neng fou bei gai bian, bi ru delete huo zhe xiu gai cheng fang wen qi shu xing enumerable: false, mo ren wei true, miao shu neng fou bei in mei ju, bi ru forin writable: false, mo ren true, miao shu shi fou neng bei geng gai value: 1, 2, 3, mo ren undefined, jiu shi shu xing de zhi miao shu fang wen qi shu xing

{
    configurable: false, // 默认为true, 描述能否被改变,比如delete或者修改成访问器属性
    enumerable: false, // 默认为true, 描述能否被 in 枚举,比如for-in
    get: function() {  return this.name }, // 默认undefined, getter函数
    set: function(newVal) { this.name = newVal }, // 默认undefined, setter函数
}

简单实操

直接在chrome下进行:

var obj = {};
Object.defineProperty(obj, "name", {
    configurable: false, // 默认为true, 描述能否被改变,比如delete或者修改成访问器属性
    enumerable: false, // 默认为true, 描述能否被for-in枚举
    writable: false, // 默认true, 描述是否能被更改
    value: "wython" // 默认undefined, 就是属性的值
});

运行结果?image?可以看到是定义了一个属性name.这种方式和obj.name = "wython"; 其实没啥区别。在这里面我把configrable, enumerable, writable改成false。 所以如果参数去改值,或者遍历, 都是不行的。

for(const i in obj) { console.log(i) }  // 结果: undefined
delete obj.name; // 无效
obj.name = "Another wython"; // 无效
尝试下访问器属性的定义方式
Object.defineProperty(obj, "_name", {
    configurable: true,
    enumerable: true,
    get: function() { return this.name },
    set: function(newVal) {
        // 我们可以尝试更改name的值,因为是不可更改所以是无效的
        this.name = newVal;
    }
})
// 验证
obj._name  = 1; // 无效,原因是访问器属性监听的是不可更改的name属性

所以说访问器属性监听的是另一个属性,如果监听的是自身,会报堆栈溢出的错误。

比如:

Object.defineProperty(obj, "_self", {
    configurable: true,
    enumerable: true,
    get: function() { return this._self },
    set: function(newVal) {
        // 我们可以尝试更改name的值,因为是不可更改所以是无效的
        this._self = newVal;
    }
})
obj._self;

image

更多的实例,可以自己尝试。

总结

说实话,defineProperty方法平时几乎不用。毕竟现在工作上很多东西已经实现好了。我们可以用setter的这种方式触发notity。类似于观察者模式的方式监听属性,实现双向数据绑定的作用。小中见大,细节的东西也是很重要的。这个方法的兼容性是IE9. IE8下面有些问题。

当前文章:http://www.kmb-web.com/in28d8rdh/395315-413667-73533.html

发布时间:09:28:35

06633开奖结果??2017香港历史开奖记录??香港挂牌之全篇资料??开奖直播??31844六神算??马会开奖结果991993??铁算盘香港正版挂牌??水果奶奶论坛??正版挂牌??香港马会开码结果直播 开奖结果??