1、对象数据属性的类型
[Configurable]能否通过delete删除属性,能否修改属性特征,能够将数据属性改为访问器属性,默认值为true,一旦将变为false则不能修改其属性
[Enumberable]能否采用for-in循环返回属性,默认true
[Writable]是否可写
[Value]值 默认undefined
eg:
2、访问器属性
[Configurable]
[Enumberable]
[Get]
[Configurable]能否通过delete删除属性,能否修改属性特征,能够将数据属性改为访问器属性,默认值为true,一旦将变为false则不能修改其属性
[Enumberable]能否采用for-in循环返回属性,默认true
[Writable]是否可写
[Value]值 默认undefined
eg:
2、访问器属性
[Configurable]
[Enumberable]
[Get]
[Set]
<!doctype>
<html>
<head>
<meta charset="UTF8">
</head>
<script type="text/javascript">
var person = {
name:"guoxiaofen"
};
//writable属性
Object.defineProperty(person,"name",{
writable:false//将属性设置为不可修改
})
console.log(person.name);
person.name = "amry";
console.log("After write " + person.name);
//configurable
Object.defineProperty(person,"name",{//调用defineProperty属性若不指名属性名则默认均为false
configurable:false
});
console.log(person.name);
delete person.name;
console.log("After delete " + person.name);
person.name = "小明";
console.log("After write name " + person.name);
// Object.defineProperty(person,"name",{//报错了
// writable:true
// });
person.name = "小明";
console.log("After write name " + person.name);
//******************************************定义访问器属性*********************
var book = {
_year:2004,//标识只能通过访问器访问的属性
edition:1
}
Object.defineProperty(book,"year",{
set:function(newYear) {
this._year = newYear;
this.edition++;
},
get:function(){
return this._year;
}
});
book.year = 2005;
console.log(book.edition);
//或者通过如下方法定义访问器属性
book.__defineGetter__('year1',function(){
return this._year;
});
book.__defineSetter__('year1',function(newValue){
this._year = newValue;
this.edition++;
});
book.year1 = 2000;
console.log(book.edition);
//另一种定义数据和访问器属性的格式
var myBook = {
person:{
value:"guoxiaofen"
},
_year:{
value:2004
},
year:{
get:function(){
return this._year;
},
set:function(newValue){
this._year = newValue;
}
}
}
//***************************************读取属性的特性
var despriptor = Object.getOwnPropertyDescriptor(myBook,"year");
console.log(despriptor.value.get);
console.log(despriptor.configurable);
//***************************************创建对象的方法
//***************************************1.工厂模式,
//*******缺点是下面的sayName函数就重复创建多次,而且不能很好地解决类别判断的问题
function createPerson(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
alert(this.name);
}
return o;
}
var Bob = createPerson('Lilei',29,'worker');
var MeiMei = createPerson('HanMeimei',28,'computer');
console.log(Bob instanceof Object);
//*********************************构造函数模式
//缺点是如果忘记new,则会把属性创建在全局作用域
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
}
}
var person1 = new Person('Lilei',20,"job");
var person2 = new Person('HanMeimei',20,'getOwnPropertyDescriptor');
console.log(person2.constructor == Person);//相当于对对象类别进行判断
console.log(person1 instanceof Person);//true
console.log(person1.sayName == person2.sayName);//false
//若将构造函数当成普通函数来使用,则在全局域创建属性
Person('world',30,'learning');
console.log(window.name);
//对某一个函数使用
var p = new Object();
Person.call(p,'Lilei',40,'happy');
console.log(p.age);
//**********************************************原型模式
//此类型对象可共享的内容最好放在原型链上
function Per(){}
Per.prototype.name = "guoxiaofen";
Per.prototype.age = 23;
Per.prototype.job = 'computer';
Per.prototype.sayName = function(){
alert(this.name);
}
var a = new Per();
var b = new Per();
console.log(a.name);
a.name = "mada";//在自己的链上创建一个name属性,和prototype上的不是一个
console.log(b.name);
console.log(a.name);
console.log(a.__proto__);
console.log(Per.prototype.isPrototypeOf(a));
//true, 虽然不能访问某个特定对象的[[prototype]],但是可以根据如上形式加以判断
//EMACscript新增访问prototype的方法,如下
console.log(Object.getPrototypeOf(a) == Per.prototype);//true
console.log(Object.getPrototypeOf(a));
//hasOwnProperty()函数,判断自己是否有某个属性
a.name = "天才";
console.log(a.hasOwnProperty("name"));
console.log(b.hasOwnProperty("name"));
//原型模式与in操作符
console.log(a.name);//天才
console.log("name" in a); //true 自己的属性
delete a.name;
console.log("name" in a);//true 原型链上的属性
console.log(a.name);//guoxiaofen
//for-in() 所有可枚举属性,包括原型链上的
for(c in a){
console.log("a 的 " + c);
}
</script>
</html>