资讯专栏INFORMATION COLUMN

使用 Object.defineProperty

MiracleWong / 2230人阅读

摘要:第一个参数是要修改的对象,第二个参数是属性名,第三个参数是描述,一个可以对属性进行一些设定的键值对。

Object.defineProperty,顾名思义,为对象定义属性,但是疑问是,我们有太多的办法去定义一个对象的属性了,比如foo["bar"] = 100,比如foo.bar = 100,为什么还要用它?会不会是自找麻烦呢?

使用Object.defineProperty的原因很简单,因为只有通过它才能定义一些值得特殊属性,比如是否可写,是否可枚举,接下来我们用例子来看一下。

定义或修改属性

</>复制代码

  1. var demo = {
  2. foo:1,
  3. bar:2
  4. };
  5. Object.defineProperty(demo, "foo",{
  6. value:100
  7. });
  8. Object.defineProperty(demo, "foobar",{
  9. value:"hello"
  10. });

这个例子中,第一个修改了demo的属性foo,第二个创建了foobar属性,属性的值是第三个参数中value。第一个参数是要修改的对象,第二个参数是属性名,第三个参数是“描述”,一个可以对属性进行一些设定的键值对。
所以,如果你想让一个属性变得不可枚举,要这么写

</>复制代码

  1. Object.defineProperty(demo, "foobar",{
  2. value:"hello",
  3. enumerable:false
  4. });
可枚举的属性

上一个例子其实是没有意义的,因为enumerable的默认值就是false,用上述方法创建的属性默认就是不可枚举,那么什么是不可枚举呢?很简单,for...inObject.keys找不到它,用MDN上的栗子

</>复制代码

  1. var o = {};
  2. Object.defineProperty(o, "a", { value : 1, enumerable:true });
  3. Object.defineProperty(o, "b", { value : 2, enumerable:false });
  4. Object.defineProperty(o, "c", { value : 3 }); // enumerable defaults to false
  5. o.d = 4; // 如果使用直接赋值的方式创建对象的属性,则这个属性的enumerable为true
  6. for (var i in o) {
  7. console.log(i);
  8. }
  9. // 打印 "a""d" (in undefined order)
  10. Object.keys(o); // ["a", "d"]
  11. o.propertyIsEnumerable("a"); // true
  12. o.propertyIsEnumerable("b"); // false
  13. o.propertyIsEnumerable("c"); // false

所以,同样你可以定义的属性包括
Writable 是否可写
Configurable 是否能删除

所以,Object.defineProperty相当于 .[]的一个加强版,但是另外一个因素也让他变得更强大。

属性的getter和setter

通过Object.defineProperty可以自定义属性的getter和setter,看栗子

</>复制代码

  1. var demo = {
  2. foobar: "hello"
  3. }
  4. var v;
  5. Object.defineProperty(demo,"foobar",{
  6. get:function(){
  7. console.log("i am been getting")
  8. return v + "?"
  9. },
  10. set:function(e){
  11. v = e + "!";
  12. console.log("i am changing!")
  13. }
  14. }
  15. )
  16. demo.foobar = "bye"
  17. console.dir(demo.foobar)
  18. //"i am changing!"
  19. //"i am been getting"
  20. //"bye!?"

这只是一个恶作剧,让属性在修改和获取的时候都进行了修改,不过这确实是一个很强大的功能,我们可以通过这个方法实现页面展现与数据的绑定,让你的关注点集中在数据而不是数据的展现过程,这就是所谓的"双向绑定"

比如这样:

</>复制代码


  1. var demo = {}
  2. var v;
  3. Object.defineProperty(demo,"foobar",{
  4. get:function(){
  5. return v;
  6. },
  7. set:function(e){
  8. v = e;
  9. sow();
  10. }}
  11. );
  12. function sow(){
  13. $("body").html(demo.foobar)
  14. }
  15. demo.foobar = "hello"
  16. setTimeout(function(){
  17. demo.foobar = "bye"
  18. setTimeout(function(){
  19. demo.foobar = "i am back"
  20. },1000)
  21. },1000)

这个例子中,数据的展现交给了sow()去做,数据这边每次更新demo.foobar的值,展现就会更新,这一切都得益于 Object.defineProperty

最后的话Object.defineProperty是ECS5属性,所以IE8以下无效。

更多请见
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

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

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

相关文章

  • 详解JavaScript之神奇的Object.defineProperty

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

    baishancloud 评论0 收藏0
  • JS属性特性(属性描述符)

    摘要:概念中定义了一个名叫属性描述符的对象,用于描述了的各种特征。只指定则表示属性为只读属性。使用属性描述符对象只能在或中使用。修改已有的属性会抛出类型错误异常添加属性会抛出类型错误异常不能修属性结语我对属性描述符很不熟悉,主要是因为平时用得少。 概念 ECMAScript 5 中定义了一个名叫属性描述符的对象,用于描述了的各种特征。属性描述符对象有4个属性: configurable:可...

    yeyan1996 评论0 收藏0
  • JS进阶篇--JS apply的巧妙用法以及扩展到Object.defineProperty使用

    摘要:的使用对象是由多个名值对组成的无序的集合。目标属性所拥有的特性返回值传入函数的对象。是一种获得属性值的方法是一种设置属性值的方法。参考相关阅读链接基础篇中的可枚举属性与不可枚举属性以及扩展 Math.max 实现得到数组中最大的一项 var array = [1,2,3,4,5]; var max = Math.max.apply(null, array); console.log(m...

    jasperyang 评论0 收藏0
  • JavaScript深入理解对象方法——Object.defineProperty()

    摘要:返回值被传递给函数的对象。描述该方法允许精确添加或修改对象的属性。描述符必须是两种形式之一不能同时是两者。可以是任何有效的值数值,对象,函数等。该方法返回值被用作属性值。该方法将接受唯一参数,并将该参数的新值分配给该属性。 Object.defineProperties() Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性...

    woshicixide 评论0 收藏0
  • 理解Object.defineProperty的作用

    摘要:对象是由多个名值对组成的无序的集合。对象中每个属性对应任意类型的值。目标属性所拥有的特性返回值传入函数的对象。给对象的属性添加特性描述,目前提供两种形式数据描述和存取器描述。兼容性在下只能在对象上使用,尝试在原生的对象使用会报错。 对象是由多个名/值对组成的无序的集合。对象中每个属性对应任意类型的值。定义对象可以使用构造函数或字面量的形式: var obj = new Object; ...

    yexiaobai 评论0 收藏0
  • Object.defineProperty()

    摘要:简介源码地址对象,属性,属性描述符用于在一个对象上定义一个新的属性,或者修改一个对象现有的属性,并返回这个对象。 简介 源码地址showImg(https://segmentfault.com/img/remote/1460000019446680?w=2458&h=610); Object.defineProperty(对象,属性,属性描述符) 用于在一个对象上定义一个新的属性,或者...

    ACb0y 评论0 收藏0

发表评论

0条评论

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