深入理解 Object.defineProperty

2021-01-21  本文已影响0人  DavyJones1

Object.defineProperty() 可以用来给对象添加属性,并控制对属性的访问操作。在我们访问或者修改某个对象的某个属性的时候,可以然后进行额外的操作。

Object.defineProperty 总览

首先,一个普通的对象是由多个名/值对组成的无序集合。对象中每个属性对于任意类型的值。例如:

const obj = {
    name: '孩子',
    age: 10,
    run: function() {
        console.log('Run');
    }
};

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

基本语法:

Object.defineProperty(obj, prop, descriptor);

实例:

const object1 = {};

Object.defineProperty(object1, 'property1', {
  value: 42,
  writable: false
});

object1.property1 = 77;
// throws an error in strict mode

console.log(object1.property1);
// expected output: 42

参数

第一个参数obj 和 prop参数很容易理解,重点说第三个参数
descriptor由两部分组成,数据描述符和访问器描述符,

描述符默认值

返回值

被传递给函数的对象。

描述

该方法允许精确地添加或修改对象的属性。通过赋值操作添加的普通属性是可枚举的,在枚举对象属性时会被枚举到(for...in 或 [Object.keys])方,可以改变这些属性的值,也可以[删除]这些属性。这个方法允许修改默认的额外选项(或配置)。默认情况下,使用 Object.defineProperty() 添加的属性值是不可修改(immutable)的。

对象里目前存在的属性描述符有两种主要形式:数据描述符存取描述符数据描述符是一个具有值的属性,该值可以是可写的,也可以是不可写的。存取描述符是由 getter 函数和 setter 函数所描述的属性。一个描述符只能是这两者其中之一;不能同时是两者。

使用

添加普通属性

const obj = {};

let initValue = 'init';

Object.defineProperty(obj, 'name', {
    // 当我们使用 obj.name 获取该值的时候,会自动调用 get 函数
    get: function() {
        console.log("custom-get")
        return initValue;
    },
    set: function(value) {
        console.log("custom-set " + value)
        initValue = value;
    }
});
console.log(obj.name); //获取值, 会调用get方法
obj.name = 'changeValue'; // 设置值,会调用set方法。
console.log(obj.name); // 获取值, 会调用get方法

添加数组属性

const obj = {};
let initValue = [];
Object.defineProperty(obj, 'array', {
    set: function(value) {
        console.log('set called' + JSON.stringify(value));
        initValue = value;
    },
    get: function() {
        return initValue;
    }
});

console.log(obj.array); //执行get方法
obj.name = []; // 执行set方法
obj.name = [1, 2, 3]; // 执行set方法
obj.name[0] = 11;//  【对数组中的某一项进行改变值,不执行set方法】
console.log(obj.array);  // 执行get方法
obj.name.push(4); // 【使用push方法对 obj.name数组添加属性 不执行set方法】
obj.name.length = 5; // 不会执行set方法

参考:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

上一篇下一篇

猜你喜欢

热点阅读