对象我们都知道是什么,但是对象当我们想对对象做些限制,该怎么办呢,可以用对象的内置属性
内置属性——数据属性
Object.defineProperty()
mdn上是这么定义的: Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,
语法
obj.defineProperty(obj,prop,descriptor)
参数
1.obj:要执行操作的对象
2.prop:操作的对象需要定义或修改的属性的名称
3.descriptor:具体的操作内容
return
传递给函数的对象。
configurable
是否可以删除或者修改目标对象属性的特性(就是我们现在要说的这几个) 默认值为false,设置为true的时候可以被修改或删除, 一旦被设置为false,就不能再把它变为可配置的,这一点很重要
举个栗子
当首先设置为true的时候可以被删除
var obj = {
name:'clearlove'
}
Object.defineProperty(obj,'name',{
configurable:true
})
//删除属性
delete obj.name
console.log(obj.name) //undefined
设置为false的时候不可以被删除
var obj = {
name:'clearlove'
}
Object.defineProperty(obj,'name',{
configurable:false
})
//删除属性
delete obj.name
console.log(obj.name) //clearlove
当设置为true的时候可以被修改特性
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj, "name", {
writable: false,
enumerable: true,
configurable: true
});
//重新修改特性
Object.defineProperty(obj, "name", {
writable: true,
enumerable: true,
configurable: true
});
console.log(obj.name); //clearlove
当设置为false的时候不可以修改特性
var obj = {
name: 'clearlove'
}
//重新修改特性
//重新修改特性
Object.defineProperty(obj, "name", {
writable: false,
enumerable: false,
configurable: false
});
Object.defineProperty(obj, "name", {
writable: true,
enumerable: true,
configurable: false
});
console.log(obj.name);
enumerable
是否可以被再次枚举(使用for...in或Object.keys())默认为fasle,设置为true可以被枚举;设置为false,不能被枚举
举个栗子
var obj = {}
// 第一种情况:enumerable设置为false,不能被枚举。
Object.defineProperty(obj, "newKey", {
value: "hello",
writable: false,
enumerable: false
});
// 枚举对象的属性
for( var attr in obj ){
console.log( attr ); // undefined
}
// 第二种情况:enumerable设置为true,可以被枚举。
Object.defineProperty(obj, "newKey", {
value: "hello",
writable: false,
enumerable: true
});
// 枚举对象的属性
for( var attr in obj ){
console.log( attr ); //newKey
}
value
对应属性的值
var obj = {
name: 'clearlove'
}
//重新修改特性
//重新修改特性
Object.defineProperty(obj, "name", {
value:'Meiko'
});
console.log(obj.name); //Meiko
Wrirable
属性值是否可以被修改,默认为false
设置为false,不能被修改
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj, "name", {
writable:false
});
//修改name的值
obj.name = 'Meiko'
console.log(obj.name); //clearlove
设置为true可以被修改
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj, "name", {
writable:true
});
//修改name的值
obj.name = 'Meiko'
console.log(obj.name); //Meiko
关于默认值
在使用Object.defineProperty时,三个属性默认都为fasle,当不使用时默认都是为true
访问器属性
重点来说说get和set
get
在属性值被获取的时候进行的操作
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj,'name',{
//在属性被读取时,执行的操作
get:function(){
console.log('我被读取了')
//return value
}
})
console.log(obj.name) //我被读取了
在属性设置时进行的操作
//在非严格模式下只设置set会打印undefined
var obj = {
name: 'clearlove'
}
Object.defineProperty(obj,'name',{
//在属性被读取时,执行的操作
set:function(){
console.log('我被修改了')
return value
}
})
obj.name = 'Meiko'
console.log(obj.name)
基于上述特性我们是否可以做一个类似vue计算属性的东西呢
举个栗子
//根据年龄计算出生日期
//1.获取现在的年份
var myDate = new Date();
var tYear = myDate.getFullYear();
//2.新建对象赋予年份
var obj = {
nowyear:tYear,
_oldyear:22,
birthdyear:0
}
//3.输入年龄计算,根据年龄出生年
Object.defineProperty(obj,'oldyear',{
get:function(){
return this._oldyear
},
set:function(newValue){
this._oldyear = newValue
this.birthdyear = this.nowyear - newValue
}
})
//设置oldyear的值,得到出生年
obj.oldyear = 25
console.log(obj.birthdyear)//1994