对象咱们都知道是什么,可是对象当咱们想对对象作些限制,该怎么办呢,能够用对象的内置属性
vue
Object.defineProperty()
复制代码
mdn上是这么定义的: Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,bash
语法
obj.defineProperty(obj,prop,descriptor)函数
参数
1.obj:要执行操做的对象 2.prop:操做的对象须要定义或修改的属性的名称 3.descriptor:具体的操做内容 return
传递给函数的对象。ui
是否能够删除或者修改目标对象属性的特性(就是咱们如今要说的这几个) 默认值为false,设置为true的时候能够被修改或删除, 一旦被设置为false,就不能再把它变为可配置的,这一点很重要this
举个栗子
spa
当首先设置为true的时候能够被删除code
var obj = {
name:'clearlove'
}
Object.defineProperty(obj,'name',{
configurable:true
})
//删除属性
delete obj.name
console.log(obj.name) //undefined
复制代码
设置为false的时候不能够被删除cdn
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的时候不能够修改特性blog
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);
复制代码
是否能够被再次枚举(使用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
}
复制代码
对应属性的值
var obj = {
name: 'clearlove'
}
//从新修改特性
//从新修改特性
Object.defineProperty(obj, "name", {
value:'Meiko'
});
console.log(obj.name); //Meiko
复制代码
属性值是否能够被修改,默认为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
在属性值被获取的时候进行的操做
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
复制代码