资讯专栏INFORMATION COLUMN

详解Object.defineProperty()

HtmlCssJs / 693人阅读

摘要:前言是新增的一个,其作用是给对象的属性增加更多的控制。使用方法提供了一种直接的方式来定义对象属性或者修改已有对象属性。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对函数功能来描述的属性。这也是实现双向数据绑定的关键。

前言

Object.defineProperty是ES5新增的一个API,其作用是给对象的属性增加更多的控制。在我们日常的coding中,这个API用到的地方不多,然而它对于MVVM框架中双向数据绑定(two-ways data binding)来说是至关重要的一个API,目前vue和avalon中的双向数据数据绑定均是通过它来实现的。

使用

Object.defineProperty方法提供了一种直接的方式来定义对象属性或者修改已有对象属性。

语法
Object.defineProperty(obj, prop, descriptor)
参数

obj: 需要定义属性的对象(目标对象)

prop: 需被定义或修改的属性名(对象上的属性或者方法)

descriptor: 需被定义或修改的属性的描述符

descriptor

objprop都比较好理解,我们重点来解析第三个参数属性描述符,它是一个对象,里面有以下取值:

value: 属性的值

var a = {}

Object.defineProperty(a, "b", {
    value: 2
})

console.log(a.b); // => 2

writable: 属性是否能被重写(rewrite),默认为false

var a = {}

Object.defineProperty(a, "b", {
    value: 2,
    writable: false
})

console.log(a.b); // output 2

a.b = 3

console.log(a.b); // still ouput  2

enumerable: 属性是否能在for ... in或者Object.keys中被枚举出,来默认为false

var a = {}

Object.defineProperty(a, "b", {
    value: 2,
    enumerable: false
})

console.log(Object.keys(a)) // output []

Object.defineProperty(a, "c", {
    value: 2,
    enumerable: true
})

console.log(Object.keys(a)) // output ["c"]

configurable: 是否能够配置valuewritableconfigurable,默认为false

var a = {}

Object.defineProperty(a, "b", {
    value: 2,
    enumerable: false
})

console.log(a.b) // output 2

Object.defineProperty(a, "b", {
    value: 3,
    enumerable: true
})

// TypeError: Cannot redefine property: b

get: 一个给属性提供 getter 的方法,默认undefined

set: 一个给属性提供 setter 的方法,默认undefined

属性描述符分为数据描述符和存取描述符。数据描述符是一个拥有可写或不可写值的属性。存取描述符是由一对 getter-setter 函数功能来描述的属性。

数据描述符和存取描述符均具有可选键值:configurable, enumerable

数据描述符同时具有可选键值:value,writable,get,set

用思维导图来表示就是:

get/set

对于setget,我的理解是它们是一对勾子(hook)函数,当你对一个对象的某个属性赋值时,则会自动调用相应的set函数;而当获取属性时,则调用get函数。这也是实现双向数据绑定的关键。

var a = {}
var b

Object.defineProperty(a, "b", {
    get: function() {
        console.log("get b")

        // 我们可以在这里对返回的值做任何操作
        return b + 1
    },
    set: function(newValue) {
        console.log("set b to", newValue)
        b = newValue
    }
})

a.b = 100

console.log(a.b);

/*
output:
  set b to 100
  get b
  101
*/
注意

数据描述符和存取描述符不能混合使用

Object.defineProperty(o, "conflict", {
  // value是数据描述符
  value: 1,
  // get是存取描述符
  get: function() {
    return 2;
  }
});
// throws a TypeError: value appears only in data descriptors, get appears only in accessor descriptors

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/79181.html

相关文章

  • defineProperty详解

    摘要:搁置了几天我还是决定再次重写下边我们来具体聊聊先从开始说起有个定义属性的功能,应该没几个人用,因为相对于这种方式简直不能再难用。 搁置了几天我还是决定再次重写! 下边我们来具体聊聊先从defineProperty开始说起 defineproperty //defineproperty 有个定义object属性的功能,应该没几个人用,因为相对于obj.a = 1这种方式简直不能再难用。 ...

    charles_paul 评论0 收藏0
  • 详解JavaScript之神奇的Object.defineProperty

    摘要:与当与同时为时,属性不能重新使用定义,严格模式下会报错示例云麒报错当或者为时,属性可以重新使用定义,这一点读者不妨自行测试。 摘要: JavaScript有个很神奇的Object.defineProperty(),了解一下? =与Object.defineProperty 为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.definePro...

    baishancloud 评论0 收藏0
  • JavaScript对象详解

    摘要:属性描述符升级打怪必备技能对象有自己的属性和方法,对于我们对象的属性来讲,属性还有自己的属性,又称为属性描述符。这个方法接受三个参数,第一个是指定的对象,第二个是指定的对象参数,第三个当然是要修改的属性描述符了。 对象的声明有俩种: 字面量 通过new一个构造函数Object 两者唯一的区别就是,字面量形式,可以一次赋值多个,通过new Object就得一个一个赋值 数据类型 ...

    fancyLuo 评论0 收藏0
  • Javascript Object方法详解

    摘要:创建对象创建一个普通对象创建一个没有原型的新对象不继承任何属性和方法返回对象中可枚举的自我属性的名称的数组返回对象中所有自我属性的名称的数组属性的特性属性有两种特性数据属性和存取器属性数据属性存取器属性可以获得某个对象特定自有属性的属性描述 Object.create(o) 创建对象 Object.create({x: 1}) //创建一个普通对象 Object.create(null...

    sushi 评论0 收藏0
  • javascript对象原型成员详解

    摘要:和的作用一样,区别在于写法语法对象对象作用判断对象是否在对象的原型链上语法对象构造函数作用判断构造函数的属性是否在对象的原型链上,如果在,就返回属性是否可枚举用于检查给定的属性是否能够使用语句。 ## javascript对象原型成员详解 ## ECMAScript 中的对象就是一组数据和功能的集合,对象可以通过 new 操作符后跟要创建的对象名称来...

    zhkai 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<