首页 > 其他 > 详细

深入理解Object 之 Properties

时间:2020-07-03 13:39:31      阅读:54      评论:0      收藏:0      [点我收藏+]

Data Property

1. Attributes

  数据属性指对象中那些有自己的值的属性(与下文Accessor Property相对),共有四个Attributes :

[[Configurable]] - “可配置的”,默认为True

    1. 标识该属性(Property)是否可以被delete删除
    2. 标识该属性(Property)的特性(attributes)是否可以被修改。具体而言,如果将configurable设置为false:
      configurable不可以修改
      enumerable不可被修改
      writable只能从true改为false,不可从false改为true
    3. 标识是否可以将该属性(Property)从Data Property改为Accessor Property

[[Enumerable]] - “可枚举的”,默认为True

标识该属性(Property)是否可以在for-in循环中被枚举到。

[[Writable]] - “可写的”,默认为True

    标识该属性(Property)的值是否可以被修改

[[Value]] - 值,默认为undefined

 

  在对象中定义一个属性并赋值时,如:

let Person = {
    name: "Nicholas"
};

  该语句为Person对象生成了名为“name”的Data Property,并将name的[[Configurable]],[[Enumerable]],[[Writable]]特性赋值为true,将[[Value]]赋值为"Nicholas"。

 

2. 修改属性(Property)的特性(Attribute)- Object.defineProperty()

参数:属性隶属的对象,属性名称,和一个描述各个特性(attribute)的object

特性:

  1. 使用该函数定义的属性,各attribute默认为false(直接在对象中添加的时,attribute默认为true)
  2. configurable属性一旦设置为false,不可再逆转。

以下语句为person添加了一个完全不可改动的属性Id,和一个只能修改Value的属性Name:

let Person = {};
Object.defineProperty(Person, "name", {
           writable: true,
           configurable: false,
           value: "Jack"
});

console.log(Person.name); //Jack
Person.name = "JackChanged";
console.log(Person.name); //JackChanged

Object.defineProperty(Person, "Id", {
    writable: false,
    configurable: false,
    value:"10101"
});
console.log(Person.Id);   //10101
Person.Id = "20202";     //throw error in strict mode
console.log(Person.Id);   //10101

Object.defineProperty(Person, "Id", {
    writable: true   //throw an error
});

(也就是说,使用defineProperty定义的属性默认是完全不可修改的,因为writable和configurable都默认为false)

 

Accessor Property
      存取属性没有value值,取而代之的是两个函数get()和set()。当存取属性的值被读取时,get()被调用,并返回一个值;当属性的值被写入时,set()被调用,并决定要对传入的值进行什么操作。简言之,该属性没有自己的数据值,是一个用来读取其他data property的媒介。

      存取属性同样有四个Attribute:

[[Configurable]] - “可配置的”,同data property

[[Enumerable]] - “可枚举的”,同data property

[[Get]] - 读取属性值时被调用的函数,需要返回一个值。默认为undefined

[[Set]] - 写入属性值时被调用的函数,需要传入一个值。默认为undefined

 

      利用存取属性可以实现“伪private”属性,对一些我们不希望在对象外部被直接用“=”读写的属性,通过存取属性的getter和setter函数读写。

      以下语句为book添加了year属性,用于读写“类private”属性 year_ 的值,同时会自动更新public属性edition的值:

//定义对象book,year_为“类private”属性
let book = {
    year_ : 2019,
    edition: 1
}
//添加存取属性year用于读写year_的值,同时更新edition
Object.defineProperty(book, "year", {
    get(){
        return this.year_;
    },
    set(newVal){
        this.year_ = newVal;
        this.edition += newVal - 2019;
    }
})

book.year = 2020;
console.log(book.edition); //2

 

 

定义多个属性 - Object.defineProperties()

let book = {};
Object.defineProperty(book, {
    year_:{
        value: 2019
    },
    edition:{
        value: 1
    },
    year:{
        get(){
            return this.year_;
        },
        set(newVal){
            if(newVal > 2019){
                this.year_ = newVal;
                this.edition += newVal - 2019
            }
        }
    }
})

 

读取Properties

Object.getOwnPropertyDescriptor()

let privateYearDescriptor = Object.getOwnPropertyDescriptor(book, "year_");
console.log(privateYearDescriptor.value);//2019
console.log(privateYearDescriptor.configurable);//false(通过defineProperty定义)
console.log(privateYearDescriptor.get); //undefined


let accessorYearDescriptor = Object.getOwnPropertyDescriptor(book, "year");
console.log(accessorYearDescriptor.value);//undefined
console.log(accessorYearDescriptor.configurable);//false(通过defineProperty定义)
console.log(typeof accessorYearDescriptor.get); //function

Object.getOwnPropertyDescriptors()

let bookDescriptors = Object.getOwnPropertyDescriptors(book);
console.log(bookDescriptors);
console.log(bookDescriptors.year_);
console.log(bookDescriptors.year_.value);

 

 

深入理解Object 之 Properties

原文:https://www.cnblogs.com/xintangchn/p/13229729.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!