资讯专栏INFORMATION COLUMN

Object.defineProperty()

ACb0y / 3081人阅读

摘要:简介源码地址对象,属性,属性描述符用于在一个对象上定义一个新的属性,或者修改一个对象现有的属性,并返回这个对象。

简介

源码地址

Object.defineProperty(对象,属性,属性描述符) 用于在一个对象上定义一个新的属性,或者修改一个对象现有的属性,并返回这个对象。

demo01 - 属性描述符默认值
属性 默认值 说明
configurable false 描述属性是否可以被删除,默认为 false
enumerable false 描述属性是否可以被for...in或Object.keys枚举,默认为 false
writable false 描述属性是否可以修改,默认为 false
get undefined 当访问属性时触发该方法,默认为undefined
set undefined 当属性被修改时触发该方法,默认为undefined
value undefined 属性值,默认为undefined
// demo01-default.html

// Object.defineProperty(对象,属性,属性描述符)
  var obj = {};
  console.log("obj:", obj);
  // 默认不可删除,不可枚举,不可修改
  Object.defineProperty(obj, "name", {
    value: "Jameswain"
  });
  console.log("obj默认值:", obj);
  delete obj.name;
  console.log("obj删除后:", obj);
  console.log("obj枚举:", Object.keys(obj));
  obj.name = "詹姆斯,韦恩";
  console.log("obj修改后:", obj);
  // 不能重新定义,会报重复定义错误: Uncaught TypeError: Cannot redefine property: name
  Object.defineProperty(obj, "name", {
    value: "詹姆斯,韦恩"
  });

运行结果:

​ 从运行结果可以发现,使用Object.defineProperty()定义的属性,默认是不可以被修改,不可以被枚举,不可以被删除的。可以与常规的方式定义属性对比一下:如果不使用Object.defineProperty()定义的属性,默认是可以修改、枚举、删除的:

 const obj = {};
 obj.name = "Jameswain";
 console.log("枚举:", Object.keys(obj));
 obj.name = "詹姆斯-韦恩";
 console.log("修改:", obj);
 delete obj.name;
 console.log("删除:", obj);

demo02 - 属性描述符
// JavaScript/Object.defineProperty/demo02-descriptor.html
  const o = {};
  Object.defineProperty(o, "name", {
    value: "Jameswain",   // name属性值
    writable: true,       // 可以被修改
    enumerable: true,     // 可以被枚举
    configurable: true,   // 可以被删除
  });
  console.log(o);
  console.log("枚举:", Object.keys(o));
  o.name = "詹姆斯-韦恩";
  console.log("修改:", o);
  Object.defineProperty(o, "name", {
    value: "Po"
  });
  console.log("修改:", o);
  delete o.name;
  console.log("删除:", o);

运行结果:

⚠️注意:如果writable为false,configurable为true时,通过o.name = "詹姆斯-韦恩"是无法修改成功的,但是使用Object.defineProperty()修改是可以成功的代码如下:

 const o = {};
  Object.defineProperty(o, "name", {
    value: "Jameswain",   // name属性值
    writable: false       // 不可被修改
    enumerable: true,     // 可以被枚举
    configurable: true,   // 可以被删除
  });
  console.log(o);
  console.log("枚举:", Object.keys(o));
  o.name = "詹姆斯-韦恩";
  console.log("修改:", o);
  Object.defineProperty(o, "name", {
    value: "Po"
  });
  console.log("修改:", o);
  delete o.name;
  console.log("删除:", o);

⚠️注意:如果writable和configurable都为false时,如果使用Object.defineProperty()修改属性值会报错:Cannot redefine property: name

const o = {};
  Object.defineProperty(o, "name", {
    value: "Jameswain",   // name属性值
    writable: false,       // 不可被修改
    enumerable: true,     // 可以被枚举
    configurable: false,   // 不可被删除
  });
  console.log(o);
  console.log("枚举:", Object.keys(o));
  o.name = "詹姆斯-韦恩";
  console.log("修改:", o);
  Object.defineProperty(o, "name", {
    value: "Po"
  });
  console.log("修改:", o);
  delete o.name;
  console.log("删除:", o);

demo03 - enumerable
// JavaScript/Object.defineProperty/demo03-enumerable.html
const o = {};
Object.defineProperty(o, "name", { value: "Jameswain", enumerable: true });
Object.defineProperty(o, "trim", { value: (str) => { return str.trim() }, enumerable: false });
Object.defineProperty(o, "email", { value: "Jameswain@163.com" });
o.skill = "node.js";
console.log("枚举:", Object.keys(o));
console.log("trim: ", o.trim("      8888       ") + "1")
console.log(`o.propertyIsEnumerable("name"): `, o.propertyIsEnumerable("name"));
console.log(`o.propertyIsEnumerable("trim"): `, o.propertyIsEnumerable("trim"));
console.log(`o.propertyIsEnumerable("email"): `, o.propertyIsEnumerable("email"));

demo04 - set 和 get

⚠️注意:设置set或者get,就不能在设置value和wriable,否则会报错

 const o = {
    __name: ""
  };
  Object.defineProperty(o, "name", {
    enumerable: true,
    configurable: true,
    // writable: true,    // 如果设置了get或者set,writable和value属性必须注释掉
    // value: "",         // writable和value无法与set和get共存
    get: function () {    // 如果设置了get 或者 set 就不能设置writable和value
      console.log("get", this);
      return "My name is " + this.__name;
    },
    set: function (newVal) {
      localStorage.setItem("name", newVal);
      console.log("set", newVal);
      this.__name = newVal;
    }
  });
  console.log(o);
  o.name = "Jameswain";
  o.name;
  console.log(o);
  o.name = "詹姆斯-韦恩";
  console.log(o);

demo05 - set 和 get 数据驱动视图

​ 我们可以利用set和get实现数据驱动视图变化功能,主要通过监听属性,属性变化时更新视图,获取数据从视图中获取:




  
  set & get 数据驱动视图


  

运行结果:

​ 从运行结果中,我们可以发现profile.skills属性是一个数组,如果直接更新整个数组内容是可以驱动视图变化的,但是如果更新数组对象中的某个元素是不会触发set函数的。

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

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

相关文章

  • 详解JavaScript之神奇的Object.defineProperty

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

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

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

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

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

    woshicixide 评论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
  • 理解Object.defineProperty的作用

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

    yexiaobai 评论0 收藏0

发表评论

0条评论

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