创建对象
对象直接量
var o = {
a : "value1",
b : 1,
...
};
重点内容
通过new创建对象
var a = new Array();
Object.create()
这是一个静态函数,而不是提供给某个对象调用的方法。使用它的方法很简单,只须传入所需的原型对象即可
// o1继承了属性x和y
var o1 = Object.create({x:1,y:2});
// o2不继承任何属性和方法
var o2 = Object.create(null);
// o3和new Object()一样
var o3 = Object.create(Object.prototype);
通过原型继承和创建一个新对象
function inherit(p){
if(p == null) throw TypeError();
if(Object.create)
return Object.create(p);
var t = typeof p;
if(t !== "object" && t !== "function") throw TypeError();
function f(){}
f.prototype = p;
return new f();
}
属性的查询和设置
属性的访问
// 使用'.'访问对象属性
var bookName = book.name;
// 使用方括号访问对象属性
var bookPrice = book["price"];
属性的设置
// 属性设置就算没有这个属性,设置后就会添加该属性
book.name = "JavaScript";
book["price"] = 100;
属性访问错误
// 返回的是undefined,因为book没有subtitle属性
var subtitle = book.subtitle;
// 失败,在严格模式中出错
var len = book.subtitle.length;
删除属性
delete运算符只能删除属性的自有属性,不能删除继承属性
// delete
delete book.price;
delete不能删除可配置性为false的属性
检测属性
in运算符
判断对象中是否存在属性或方法
var o = {x:1};
"x" in o; //true
"y" in o; //false
"toString" in o; //true
对象的hasOwnProperty()方法用来检测给定的名字是否是对象的自有属性。对于继承属性它将返回false。
var o = {x:1};
o.hasOwnProperty("x"); //true,o中有x属性
o.hasOwnProperty("y"); //false,o中没有y属性
o.hasOwnProperty("toString"); //false,toString是继承属性
对象的propertyIsEnumerable()只检测自有属性且这个属性的可枚举性为true时才返回true。
var o = inherit({y:2});
o.x = 1;
o.propertyIsEnumerable("x"); //true:o有一个可枚举的自由属性x
o.propertyIsEnumerable("y"); //false:y是继承来的
Object.prototype.propertyIsEnumerable("toString"); //false,不可枚举
属性getter和setter
和数据属性不同,存储器属性不具有可写性。如果属性同时具有getter和setter方法,那么它是一个读/写属性。如果只有getter方法,那么它是一个只读属性。如果只有setter方法,那么它是一个只写属性,读取只写属性总是返回undefined。
var o = {
data_prop : value,
get accessor_prop(){...};
set accessor_prop(value){...};
};
属性的特性
数据属性的4个特性分别是它的值(value)、可写性(writable)、可枚举性(enumerable)和可配置性(configurable)。
存储器属性的4个特性有点不同没有值(value)和可写性(writable),用了get和set来代替,这两个特性都是函数,分别代表getter方法和setter方法。
通过调用Object.getOwnPropertyDescriptor() 可以获取某个对象的特定特定属性的属性描述符。
// 返回{value:1,writable:true,enumerable:true,configurable:true}
Object.getOwnPropertyDescriptor({x:1},"x");
// 返回{set:/*func*/,set:*func*/.enumerable:true,configurable:true}
Object.getOwnPropertyDescriptor({
get r(){...},
set r(value){...}
},"r");
要想设置属性的特性,或者让新建属性具有某种特性,则需要调用Object.defineProperty()。
// 添加一个不可枚举的数据属性x,并赋值为1
Object.defineProperty(o, "x", {value:1, writable:true, configurable:true, enumerable:fale});
// 现在对属性x做修改,让它变为只读
Object.defineProperty(o,"x",{writable:false});
传入Object.defineProperty()的属性描述符对象不必包含4个特性。对于新创建的属性来说,默认的特性值是false或undefined。对于修改的已有属性来说,默认的特性没有做任何修改。不能修改继承属性。
如果要同时修改或创建多个属性,则需要使用Object.defineProperties()。第一个参数是要修改的对象,第二个参数是一个映射表,它包含要新建或修改的属性的名称,以及它们的属性描述符,例如:
var p = Object.defineProperties({},{
x : {value:1, writable:true,enumerable:true,configurable:true},
r : {
get : function(){...},
enumerable:true,
configurable:true
}
});
对象的三个属性
- 原型属性
- 类属性
- 可扩展性
原型属性
对象的原型属性是用来继承属性的。
通过对象直接量创建的对象使用Object.prototype作为它们的原型。通过new创建的对象使用构造函数的prototype属性作为它们的原型。通过Object.create()创建的对象使用第一个参数作为它们的原型。
对象使用isPrototypeOf()方法来查看对象是不是该参数的原型
var p = {x:1};
var o = Object.create(p);
p.isPrototypeOf(o); // true
Object.prototype.isPrototypeOf(o); // true
类属性
对象的类属性是一个字符串,用以表示对象的类型信息。ECMAScript 3和ECMAScript 5都为提供这个属性 设置这个属性的方法,并只有一种间接的方法可以查询它。默认的toString()方法(继承自Object.prototype)返回了如下这种格式的字符串:
[object class]
想要获取对象的类,可以调用对象的classof()方法,然后提取已返回字符串的第8个到倒数第二个位置位置的字符。
function classof(o){
if(o == null)
return "Null";
if (o == undefined)
return "Undefined";
return Object.prototype.toString.call(o).slice(8,-1);
}
可扩展性
对象的可扩展性用以表示是否可以给对象添加新属性。所有内置对象和自定义对象都是显示可扩展的。
可以将对象传入Object.isExtensible(),来判断对象是否是可扩展的。如果想将对象转换为不可扩展的,需要调用Object. preventExtensible(),将待转换的对象作为参数传进去。注意,不可扩展对象不能转换为可扩展对象。preventExtensions()只影响到对象本身的扩展性。可以给不可扩展对象的原型添加属性,这个不可扩展对象同样会继承这些新属性。
Object.seal()和Object.preventExtensions()类似,除了将对象设置为不可扩展的,还将对象的所有自有属性都设置为不可配置的。
Object.freeze()将对象设置为不可扩展的,将对象的所有自有属性都设置为不可配置的,还将它自有的数据属性设置为只读。使用OBject.isFreeze()来检测对象是否冻结。
序列化
o = {x:1,y:2};
s = JSON.stringify(o); // 序列化,s是'{x:1,y:2}'
p = JSON.parse(s); // 反序列化
对象方法
toString()方法
tolocaleString()方法
toJSON()方法
Object.prototype实际上没有定义 toJSON()方法,但对于需要只想序列化的对象来说,JSON.stringify()方法会调用toJSON方法。如果待序列化的对象存在该方法,该方法的返回值就是序列化的结果。
valueOf()方法
当JavaScript需要将对象转换为某种原始值而非字符串才会调用它。