对象
什么是对象
对象是一个包含相关数据和方法的集合,通常由一些变量和函数组成。
如何定义一个对象
/*字面量式*/
var Person={
}
/*构造函数式*/
var Person = function(){}
这样就定义了一个空的名叫Prson的对象。
试着给这个Person对象加上一些属性和方法:
/*字面量式*/
var Person={
name: 'John',
birthday:'2000.01.01',
id:'1111111',
eat:function(){
alert(this.name+"正在吃饭");
},
run:function(){
alert(this.name+"正在跑步");
}
}
/*构造函数式*/
var Person = function(name,birthday,age){
this.name=name;
this.birthday=birthday;
this.age=age;
this.eat = function(){
console.log(this.name"正在吃饭");
};
}
可以看到,用json式和构造函数式定义的对象,在为其增加属性方法时,语法时不一样的。
json式定义属性和方法的语法格式是:
属性名:参数,
方法名:function(){方法体},
末尾要用逗号隔开,最后一个属性(方法)则不需要逗号。
这时我们调用Person对象的eat方法:
如果我们使用构造函数式定义的类,
则要将它实例化,再进行调用
var p = new Person('Lihua','2000.1.1','22');
console.log(p);
深入对象属性
数据属性
数据属性,即数据的属性。
在ECMAScript中,我们可以通过Object.defineproperty(Object obj, String name,{attributes})
来直接在一个对象上定义一个新数据,或者修改一个已经存在的数据, 并返回这个对象。
数据有4种属性:
-
[[value]] 它可以是任何的类型,表示这个数据的值。默认值:undefined
-
[[writable]] 它是布尔类型,表示这个数据的[[Value]]是否可以被修改。默认值①:false
-
[[enumerable]] 它也是布尔类型,表示这个数据能否用for…in循环或Object.keys来枚举。默认值①:false
-
[[configurable]] 它依然是布尔类型,表示这个数据能否被delete运算符删除。默认值①:false
①这里的默认值是指在Object.defineProperty()中定义属性的时候的默认值
var o =function(){}; // 创建一个新对象
// 在对象中添加一个属性与数据描述符的示例
Object.defineProperty(o, "a", {
value : 37,
writable : true,
enumerable : true,
configurable : true
});
Object.defineproperty(o,"eat",{
value : function(){
console.log("eating!!!");
},
writable:false,
enumerable : true,
configurable : true
});
o.a;
o.eat();
Object.getOwnPropertyDescriptor(Object obj, String data_name)
这个方法会返回数据名称在对象中的属性。
这里依然以上面的o对象为例子
Object.getOwnPropertyDescriptor(o,"eat");
访问器属性
访问器属性跟数据属性大同小异,就是删去了[[Value]]属性,加入了[[get]]和[[set]]属性。
-
[[Get]] 它是函数或者undefined类型
-
[[Get]] 它是函数或者undefined类型
创建访问器
用get和set关键字来创建
语法:
get functionName(){functionBody}
var data={
name:'pad',
get showName(){return this.name;},
set setName(name){this.name=name;}
}
data.showName;
data.setName="newName";
注意,set方法(访问器)只能接受一个参数,并且在调用访问器的时候,不是像调用传统函数funcName(para);
一样用括号包裹,
而是data.setName="newName";
用等号“赋值”
var data={
_name:'pad'
};
Object.defineProperty(data,"name",{
get:function(){
return this._name;
},
set:function(newName){
this._name = newName;
}
});
使用访问器属性
var person={
name:'xiaoming'
}
Object.defineProperty(person,"sayName",{
get:function(){
return this.name;
}
});
person.sayName;
数据属性和访问器属性
上面文章提到了数据的4个属性:
-
[[value]] 数值
-
[[writable]] 可写的
-
[[enumerable]] 可枚举的
-
[[configurable]] 可设置的
下面来看看他们的用法
writeable
var data={
_name:'pad'
};
Object.defineProperty(data,"price",{
value:30,
writeable:false//其实可以不写,默认就是false
});
data.price=9999;//虽然是不可以写的属性,但不会报错
data;
可以看见data对象中的price属性并未发生变化(原因参照注释①),依然是30
当我们对不可写属性进行重复赋值的时候,编译器并不会报错。但是在严格模式,这样的操作是会报错的。
configurable
configurable,意味可设定的。其实它是用来控制这个数据能否被delete操作符删除,以及除 value 和 writable 特性外的其他特性是否可以被修改。
返回值:对于所有情况都是true,除非属性是一个自身的 不可配置的属性,在这种情况下,非严格模式返回 false。
var product={
name:"apple",
price:200
}
Object.defineProperty(procduct,"num",{
value:375,
})
delete product.name;//返回true 可以删除
delete product.num;//返回false 不可删除
product;
由上面代码可知,用Object.defineProperty
添加的属性或访问器(writeable、configurable、enumerable)的默认值都是false
而用字面量法定义的对象的属性,其默认值都是true
enumerable
enumerable
定义了对象的属性是否可以在for...in
循环和 Object.keys()
中被枚举。