<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>defineProperty</title>
</head>
<body>
<script>
/*
ECMA中有两种属性:数据属性和访问器属性
数据属性有4个描述其行为的特性:
configurable:表示能否通过delete删除,能否修改属性特性或者能否把属性修改为访问器属性
enumerable:表示能否通过for-in循环返回属性
writable:表示能否修改属性的值
value:读取属性的时候从这个位置读,写入属性的时候把新值保存在这个位置。这个属性的默认值为undefined
要修改属性默认的特性,必须使用ECMAScript5中的Object.defineProperty(obj, prop, descriptor)方法
Object.defineProperty有三个参数:属性所在的对象,属性的名字,描述符对象
*/
var person={};
Object.defineProperty(person,'name',{
writeble:false,
value:'leo'
});
alert(person.name);
person.name='miaov';
alert(person.name);
/*
上面的例子在person对象中创建了一个名name的属性,它的值"leo"是只读的。这个属性的值是不可修改的,如果尝试为它指定新值,在非严格模式下赋值操作将被忽略;在严格模式下,赋值操作导致错误。
特别要注意的是一旦configurable设置为false,属性就会被定义为不可配置的,就不能把它变回可配置的了,此时,再调用Object.defineProperty()方法除了修改writable之外的特性在严格模式下都会导致错误,在非严格模式下会被忽略
*/
////////////////////////////////////////////////////////////////////////////////////////////////////
/*
访问器属性不包含数据值,它们包含一对getter和setter函数,在读取访问器属性时,会调用getter函数,这个函数负责返回有效的值;在写入访问器属性的时候,会调用setter函数并传入新的值,这个函数负责处理数据。
访问器属性也有4个描述其行为的特性:
configurable:表示能否通过delete删除,能否修改属性特性或者能否把属性修改为访问器属性
enumerable:表示能否通过for-in循环返回属性
get:读取属性时调用的函数,默认值为undefined
set:在写入属性时调用的函数,默认为undefined
*/
var book={
_year:2004,
edition:1
}
Object.defineProperty(book,"year",{
get:function (){
return this._year;
},
set:function (newValue){
if (newValue>2004) {
this._year=newValue;
this.edition+=newValue-2004;
}
}
})
book.year=2005;
alert(book.edition);//2
/*
以上代码创建了一个book对象,并给它定义两个默认属性:_year和edition。_year前面的下划线是一种常用记号
,表示该属性只能通过.的方式访问。而访问器属性year则包含一个getter函数和setter函数。getter函数返回_year的值,setter函数通过计算来确定正确的版本。因此,把year属性修改为2005会导致_year变成2005,而edition变为2。这是访问器属性常见的方式,即设置一个属性值会导致其他属性发生变化。这也正是vue.js实现数据双向绑定的原理。
在defineProperty()方法之前,要创建访问器属性,一般要使用两个非标准的方法
__defineGetter__()
__defineSetter__()
var book={
_year:2004,
edition:1
}
book.__defineGetter__("year",function (){
return this._year;
});
book.__defineSetter__("year",function (newValue){
if (newValue>2004) {
this._year=newValue;
this.edition+=newValue-2004;
}
});
book.year=2005;
alert(book.edition);
*/
</script>
</body>
</html>