Object类型
大多数引用类型都是Object类型的实例。
创建Object实例
创建Object实例的方法有两种:
- 使用new操作符
var person = new Object();
person.name = "nicholas";
person.age = 29;
- 使用对象字面量
var person = {
name:"nicholas",
age:29
}
属性名也可以使用字符串形式“name”“age”,数值类型的属性名会被自动转换为字符串。
使用对象字面量时,如果留空花括号,可以定义只包含默认属性和方法的对象:
var person = {}; //与 new Object()相同
person.name = "nicholas";
person.age = 29;
通过对象字面量定义对象时实际上不会调用Object构造函数。
另外,对象字面量也是向函数传递大量可选参数的首选方式:
function displayInfo(args){
if(typeof args.name == "string"){
alert(args.name);
}
if(typeof args.age== "number"){
alert(args.age);
}
}
displayInfo({
name:"nicholas",
age:29
});
displayInfo({
name:"greg"
});
这个函数接受一个名为args的参数,这个参数可能带有一个名为name或age的属性也可能两个属性都有或都没有。
这种传递参数的模式最适合需要向函数传入大量可选参数的情形。命名参数虽然容易处理,但在有多个可选参数的情况下就会显示不够灵活。最好的做法是对那些必需值使用命名参数,而使用对象字面量来封装多个可选参数。
减少全局变量污染
最小化使用全局变量的方法之一就是为你的应用只创建一个唯一的全局变量:
var MYAPP = {};
该变量此时变成了你的应用的容器:
MYAPP.stooge = {
"first-name":"joe",
"last-name":"howard"
};
MYAPP.flight = {
airline:"oceanic",
number:815,
depature:{
IATA:"STD",
time:"2004-6-12"
},
arrival:{
IATA:"LAX",
time:"2004-6-19"
},
}
只要把全局性的资源都纳入一个名称空间之下,你的程序与其他应用程序、组件或类库之间发生冲突的可能性就会显著降低。
访问对象属性
- 访问对象属性的方法:
- 点表示法
- 方括号表示法:将要访问的属性以字符串的形式放在方括号中。
person["name"];
person.name;
方括号语法的优点是可以通过变量来访问属性:
var propertyName = "name";
person[propertyName];
如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括号表示法:
person["first name"];
但是通常若不是为了使用变量来访问属性,一般还是推荐使用点表示法。
||
运算符可以用来填充默认值:
var middle = foo["middle-name"] || "hebe";
var status = foo.status || "unknown";
尝试从undefined的成员属性中取值将会导致TypeError异常:
foo.equipment; //undefined
foo.equipment.model; //TypeError!!
这时可以通过&&
来避免错误:
foo.equipment && foo.equipment.model; //undefined
在对象中,属性名永远都是字符串。如果你用string之外的值作为属性名,那么它会首先被转换成一个字符串。
ES6增加了可计算属性名,即在字面量表示法中,可以使用 [ ] 包裹一个表达式来当做属性名:
var prefix = "foo";
var myObject = {
[prefix + "bar"]:"hello",
[prefix + "baz"]:"world"
};
对象属性是函数
注意,如果访问的对象属性是一个函数,那么这个属性访问返回的函数和其他任何函数没有任何区别。因为从技术角度来说,一个函数永远不会“属于”一个对象。
function foo(){}
var someFoo = foo; //对foo的变量引用
var myObject = {
someFoo:foo
}
foo;//function foo(){}
someFoo; //function foo(){}
myObject.someFoo; //function foo(){}
someFoo和myObject.someFoo只是对同一个函数的不同引用,并不能说明这个函数是特别的或者是“属于”某个对象。
如果foo()在定义时有一个内部的this引用,那么这两个函数引用的唯一区别就是myObject.someFoo中的this会被隐式绑定到一个对象。
即使你在对象字面量形式中声明一个函数表达式,这个函数也不会属于这个对象,它们都只是对相同函数对象的多个引用:
var myObject = {
foo:function(){
……
}
}
var someFoo = myObject.foo;
someFoo; //function foo(){……}
myObject.foo; //function foo(){……}