javascript的简单数据类型包括:null,undefined,boolean,number,string.
Number,String,Boolean貌似对象,因为它们拥有方法。
对象字面量
var empty_object={};
var stooge={
"first-name":"jone",
"last-name":"hello"
}
一个对象字面量就是包围在一对花括号中的零或多个“名/值”对。
属性名可以是包括空字符串在内的任何字符串。
逗号用来分隔多个“名/值”对。
属性值可以从包括另一个对象字面量在内的任意表达式中获得,对象是可嵌套的:
var flight={
airline:"oracle",
number:815,
departtrue:{
IATA:"syd",
time: "2017-6-22",
city: "sydney"
},
arrival:{
IATA:"LAX",
time: "2004-6-22",
city: "LOS Angeles"
}
}
检索
要检索对象中包含的值,可以采用[]后缀括住一个字符串表达式的方法,也可以用.表示法代替。这种更紧凑而且可读性更好。
stooge[“first-name”] //”jone”
flight.departure.IATA//”hello”
如果你尝试检索一个并不存在的成员属性,将返回undefined.
||运算符可以用来填充默认值:
var middle=stooge["middle-name"]||"(none)";
var status=flight.status||"unkonwn";
尝试从undefined成员属性中取值将会导致TypeError异常。这时可以通过&&运算符来避免错误。
flight.equipment //undefined
flight.equipment.model //throw “TypeError”
flight.equipment&&flight.equipment.model //undefined
更新
对象里的值可以通过赋值语句来更新。如果属性名已经存在于对象里,那么这个属性的值就会被替换。如果对象之前没有拥有这个属性,那么该属性就会被扩充到对象中。
stooge['first-name']='Jerome';
stooge["middle-name"]="Lester";
flight.equipment={
model:"Boeing 777"
};
flight.status="overdue";
引用
对象通过引用来传递,他们永远不会被复制:
var x=stooge;
x.nickname='curly';
var nick=stooge.nickname;
//因为x和stooge是指向同一个对象的引用,所以nick为curly
var a={},b={},c={};
//a,b,c都引用不同的对象
a=b=c={};
//a,b和c都引用同一个空对象
原型
每个对象都连接到一个原型对象,并且它可以从中继承属性。所有通过对象字面量创建的对象都连接到object.prototype,它是javascript中的标配对象。
当你创建一个新对象时,你可以选择某个对象作为它的原型。我们将给object增加一个create方法。创建一个使用原对象作为其原型的新对象。
if(typeof object.beget!=='function'){
Object.create=function(o){
var F=function(){};
F.prototype=o;
return new F();
}
}
var another_stooge=Object.create(stooge);
原型只有在检索值时候才被用到,如果我们尝试去获得对象的某个属性值。但该对象没有此属性名,那么Javascript会试着从原型对象中获取属性值。如果那个原型对象也没有该属性,那么再从它的原型中寻找,以此类推,直到该过程最后到达终点object.prototype.
如果想要的属性完全不存在于原型链中,那么结果就是undefined值,这个过程称为委托。
原型关系是一种动态的关系,如果我们添加一个新的属性到原型中,该属性会基于该原型创建的对象可见。
stooge.professin=’actor’;
anther_stooge.profession //’actor’
反射
检查对象并确定对象有什么属性是很容易的事情,只要试着去检索该属性并验证取得的值。
typeof操作符对确定属性的类型很有帮助:
typeof flight.number //'number'
typeof flight.status //'string'
typeof flight.arrival //'object'
typeof flight.manifest //'undefined'
请注意原型链中的任何属性都会产生值:
typeof flight.toString //'function'
typeof flight.constructor //'function'
有两种方法去处理掉这些不需要的属性。第一个是让你的程序做检查并丢弃值为函数的属性。一般而言,当你想让对象在运行时动态获取自身信息时,你关注更多的是数据,而你应该意识到另外一些值可能会是函数。
另一种方法是使用hasOwnProperty方法,如果对象拥有独有的属性,它将返回true。而hasOwnProperty方法不会检查原型。
flight.hasOwnProperty(‘number’);//true
flight.hasOwnProperty(‘constructor’);//false
枚举
for in语句可用来遍历一个对象中的所有属性。该枚举过程将会列出所有的属性-包括你函数和你可能不关心的原型中的属性-所以有必要过滤掉那些你不想要的值。最为常用的过滤器是hasOwnProperty方法。以及使用typeof来排除函数:
var name;
for(name in another_stooge){
if(typeof another_stooge[name]!=='function'){
document.writeln(name+':'+another_stooge[name]);
}
}
属性名的出现顺序是不确定的,因此要对任何可能出现的顺序有所准备。如果你确保属性以特定的顺序出现,最好的办法就是完全避免使用for in语句,而是创建一个数组,在其中以正确的顺序包括属性名:
var i;
var properties={
'first-name',
'middle-name',
'last-name',
'profession'
};
for(i=0;i<properties.length;i++){
document.write(properties[i]+':'+another_stooge[i]);
}
删除
delete运算符可以用来删除对象的属性。如果对象包含该属性,那么该属性就会被移除。它不会触及原型链中的任何对象。
删除对象的属性可能会让来自原型链中的属性透漏出来:
another_stooge.nickname //’Moe’
//删除another_stooge的nickname属性,从而暴露出原型的nickname属性。
delete another_stooge.nickname;
another_stooge.nickname//’curly’
减少全局变量污染
javascript可以随意地定义全局变量来容纳你的应用的所有资源。
最小化使用全局变量的方法之一是为你的应用只创建一个唯一的全局变量:
var MYAPP={};
该变量此时变成了你的应用的容器:
var MYAPP={};
MYAPP.stooge={
"first-name":"joe",
"last-name":"howard"
};
MYAPP.flight={
airline:"ocean",
number:815,
departtrue;{
IATA:"SYD",
time: "2004",
city: "sydney"
},
arrival:{
IATA:"lax",
time: "2014",
city: "los angeles"
}
}
只要把全局性的资源都纳入一个名称空间之下,你的程序与其他应用程序,组件之间的发生冲突的可能性就会显著降低。
因为明显MYAPP.stooge指向的是顶层结构。在下一章我们会看到闭包来进行信息隐藏的方式,它是另一种有效减少全局污染的方法。