Object defineProperty

6 篇文章 0 订阅

一、简介

defineProperty可以详细的配置一个对象的属性的特性和值
赋值的两种方式:

var time = {}
// 第一种
time.kind1 = 1;  // var test = {kind1:1}
// 第二种
Object.defineProperty(time,"kind2",{
	value:2
})
// ================================分割线===================================
// 第一种等价于
Object.defineProperty(time,"kind1",{
	value:1,
	writable:true,
	enumerable:true,
	configurable:true,
	// get:undefined,
	// set:undefined
})
// 第二种等价于
Object.defineProperty(time,"kind2",{
	value:2,
	writable:false,
	enumerable:false,
	configurable:false,
	// get:undefined,
	// set:undefined
})

1. 属性表

说明defineProperty后的默认值=后的默认值拥有get、set后的默认值
value属性的默认值undefinedundefinedget的return值(不能配置)
writablevalue是否可被重写,作用于等于号赋值和defineProperty赋值。configurable为false时,被设为false后就不能在被设为truefalsetruetrue(不能配置)
enumerable是否可枚举(被循环显示)。configurable为false时,就不能再被更改false(为false时谷歌控制台显示该属性为淡紫色)truefalse
configurable属性的配置项是否可再此被定义,或被delete。configurable为false时,就不能再被更改falsetruefalse
get获取属性值时调用的方法undefinedundefined-
set设置属性值时调用的方法undefinedundefined-
*[配置项]: 除value的选项

2.互斥性

数据描述符:value、writable;存取描述符:get、set

value、writable 不能与get、set共存:
当设置了value,就不需要再从get获取值(该从value取值还是从get取值);当设置了writable为false时,set将没有意义(不允许再修改)


get、set不能与value、writable共存:
当设置了get、set,就不需要从value获取、更改值(有了自定义的存取值方法);当设置set时,writable必须为true(必须允许修改)

3. get、set的简单使用

var time = {
 __date: new Date(),
 __lastEditTime: "",
 __lastReadTime: "",
 __remark: "",
 __copyright: " (GeniusXYT)",
 __getNow: function () {
   return new Date().toLocaleString();
 }
};
Object.defineProperty(time, "createTime", {
 get() {
   return this.__date.toLocaleString();
 },
 set(val) {
   console.warn(`the obj property(now) do not be set ${val}.`);
 },
 enumerable: true
});
// 同时定义多个属性
Object.defineProperties(time, {
 lastReadTime: {
   get() {
     return this.__lastReadTime;
   },
   enumerable: true
 },
 lastEditTime: {
   get() {
     return this.__lastEditTime;
   },
   enumerable: true
 },
 remark: {
   get() {
     this.__lastReadTime = this.__getNow();
     return this.__remark ? this.__remark + this.__copyright : "";
   },
   set(val) {
     this.__lastEditTime = this.__getNow();
     this.__remark = val;
   },
   enumerable: true,
   configurable: true // 可重写 enumerable、configurable、get和set
 }
});
//  将带有__命名的变量(默认代表私有变量)隐藏(不可枚举)
(function hidePrivateVarible(obj) {
 for (let k of Object.keys(obj)) {
   if (k.slice(0, 2) === "__")
     Object.defineProperty(obj, k, { enumerable: false, configurable: false });
 }
})(time);

二、深入

1.定义常量

定义后属性值不能被更改(同const)

var time={};
// 方法一
Object.defineProperty(time,"author",{
    value:"GeniusXYT",
    writable:false,
    enumerable:true,
    configurable:false
})
// 方法二
Object.defineProperty(time,"author2",{
    enumerable:true,
    configurable:false,
    get:function (){return "GeniusXYT"},
    set:function(val){console.error("the obj time do not set property 'author',value '"+val+"'.")}
})
time.author="new name"
console.log(time.author)

2. Object.preventExtensions() 禁止对象拓展(不可逆)

禁止一个对象添加新属性并且保留已有属性
这样对象就不会再有新属性

var time = {};
time.prop = "prop";
console.log(Object.isExtensible(time));
Object.preventExtensions(time);
time.newProperty = "new";
console.log(time); // newProperty undefined
console.log(Object.isExtensible(time));

3. Object.seal() 密封(不可逆)

在对象上调用object.preventExtensions(),并把所有现有属性标记为configurable:false
这样对象就不会再有新属性,无法再配置特性

var time = {};
Object.defineProperty(time,"prop",{
	value:"prop(i can configurable)",
	writable:true,
	enumerable:true,
	configurable:true,
});
console.log(Object.isExtensible(time));
Object.seal(time);
time.newProperty = "new";
console.log(time); // newProperty undefined
console.log(Object.isExtensible(time));
Object.defineProperty(time,"prop",{writable:false}); // configurable为false时,可以将writable设为false;
time.prop = "new prop";
console.log(time.prop);
Object.defineProperty(time,"prop",{writable:true}); // 报错 设为false后将不能再设为true
Object.defineProperty(time,"prop",{enumerable:false}); // 报错 此时configurable已经被seal设置为false
Object.defineProperty(time,"prop",{configurable:true}); // 报错 configurable为false时,就不能再被更改

4. Object.freeze() 冻结(不可逆)

在一个对象上调用Object.seal(),并把所有现有属性标记为writable: false
这样对象就不会再有新属性,无法再配置特性,无法再设置值,对象就永远是那个对象了

var time = {};
Object.defineProperty(time,"prop",{
	value:"prop(i can configurable)",
	writable:true,
	enumerable:true,
	configurable:true,
});
console.log(Object.isExtensible(time));
Object.freeze(time);
time.newProperty = "new";
console.log(time); // newProperty undefined
console.log(Object.isExtensible(time));
Object.defineProperty(time,"prop",{writable:true}); // 报错 设为false后将不能再设为true
Object.defineProperty(time,"prop",{enumerable:false}); // 报错 此时configurable已经被seal设置为false
Object.defineProperty(time,"prop",{configurable:true}); // 报错 configurable为false时,就不能再被更改
time.prop = "new prop"; // 无效 此时的writable: false
console.log(time.prop);

三、应用

vue双向绑定……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值