[Object][进阶]Object.defineProperty(),Object.defineProperties(),Object.getOwnPropertyDescriptor()

vue源码学习双向数据绑定原理前置知识

Object.defineProperty()

Object.defineProperty(obj,prop,descriptor)

接收三个参数:属性所在的对象、属性的名字、描述符对象

1.数据属性

描述符对象必须是:configurableenumerablewritablevalue

使用Object.defineProperty()方法定义的数据属性,configurable、enumerable、writable默认为false

var book = {}
Object.defineProperty(book, 'name', {
    value: 'dange'
})
Object.getOwnPropertyDescriptor(book, 'name').value //"dange"
Object.getOwnPropertyDescriptor(book, 'name').configurable //false
Object.getOwnPropertyDescriptor(book, 'name').writable //false
Object.getOwnPropertyDescriptor(book, 'name').enumerable//false

使用{}或者点方法定义的数据属性,configurable、enumerable、writable默认为true

var book = { name:'dange'}
Object.getOwnPropertyDescriptor(book,'name').value //"dange"
Object.getOwnPropertyDescriptor(book,'name').configurable //true
Object.getOwnPropertyDescriptor(book,'name').writable //true
Object.getOwnPropertyDescriptor(book,'name').enumerable//true

2.访问器属性

描述符对象必须是:configurableenumerablegetset

var book = {
    _year: 2020,
    edition: 1
};
Object.defineProperty(book, 'year', {
    get: function() {
        return this._year;
    },
    set: function(newVal) {
        if(newVal > 2020) {
            this._year = newVal;
            this.edition += newVal - 2020;
        }
    }
})
book.year = 2021; //此时调用set
console.log(book.edition);

访问器属性:设置一个属性的值会导致其他属性发生变化

Object.defineProperties()

定义多个属性

Object.defineProperties(obj, props)

接收两个对象参数:要添加和修改其属性的对象,第二个对象的属性与第一个对象中要添加或修改的属性一一对应

var book = {};
Object.defineProperty(book, {
    _year: 2020,
    edition: 1
    year: {
       get: function() {
        return this._year;
       },
       set: function(newVal) {
        if(newVal > 2020) {
            this._year = newVal;
            this.edition += newVal - 2020;
        }
       }
    }
})

Object.getOwnPropertyDescriptor()

该方法可以去个给定属性的描述符

Object.getOwnPropertyDescriptor(obj, prop)

接收两个参数:属性所在的对象、要读取其描述符的属性名称

返回值是一个对象, 如果是数据属性,这个对象的属性有:configurable、enumerable、writable、value;如果对象是访问器属性,这个对象的属性有:configurable、enumerable、get、set

var book = {
    name: 'dange',
    _year: 2020,
    edition: 1
};
Object.defineProperty(book, 'year', {
    get: function() {
        return this._year;
    },
    set: function(newVal) {
        if(newVal > 2020) {
            this._year = newVal;
            this.edition += newVal - 2020;
        }
    }
})
Object.getOwnPropertyDescriptor(book, 'name').value //"dange"
Object.getOwnPropertyDescriptor(book, 'name').configurable //true
Object.getOwnPropertyDescriptor(book, 'name').writable //true
Object.getOwnPropertyDescriptor(book, 'name').enumerable //true
Object.getOwnPropertyDescriptor(book, 'name').get() //Uncaught TypeError: Object.getOwnPropertyDescriptor(...).get is not a function
Object.getOwnPropertyDescriptor(book, 'name').set() //Uncaught TypeError: Object.getOwnPropertyDescriptor(...).set is not a function
typeof Object.getOwnPropertyDescriptor(book, 'name').get //"undefined"

Object.getOwnPropertyDescriptor(book, 'year').value //undefined
typeof Object.getOwnPropertyDescriptor(book, 'year').get //"function"
坚持,坚持,坚持。再坚持坚持!
原文地址:https://www.cnblogs.com/danker/p/12567417.html