Data Property
1. Attributes
数据属性指对象中那些有自己的值的属性(与下文Accessor Property相对),共有四个Attributes :
[[Configurable]] - “可配置的”,默认为True
[[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
特性:
以下语句为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);
原文:https://www.cnblogs.com/xintangchn/p/13229729.html