js中除数字、字符串、布尔值、null值、undefined之外都是对象。
对象是属性的容器,属性包含属性名和值,属性名可以是包括空字符串在内的任意字符串(个人想法还是使用js标识符好,省的麻烦),值可以是除undefined外任何值。
对象是class-free的,对新的属性键值没有限制。
对象可以套嵌,允许继承。
对象字面量:
对象字面量提供了非常方便创建新对象值得方法。
//空对象 var empty_object = {}; //多个键值对 var object1 = { "first-name":"党兴明", "last-name":"周林" }; //可以套嵌 var object2 = { first_name:"党兴明", //属性名是合法标识符可以不用引号 last_name:"周林", another_obj1:{ time:"2016-11-09", city:"hangzhou" }, another_obj2{ home:"shengzhou" } };
检索:
要检索对象里包含的值可以用[] 或 .
优先考虑使用 .
object1["first-name"] //党兴明 //如果[]中是合法的js标识符,可以 object1.first_name; //党兴明
//object.first_name = "张三";
//如果你检索不存在的属性,会返回undefined object1.second_name; //undefined //运算符||可以用来填充默认值 var name = object1.first_name || "unknow" //尝试从undefined的属性中取值,会导致TypeError的错误,可以通过 && 运算符来解决 object1.equipment; //undefined object1.equipment.model; //TypeError object1.equipment && object.equipment.model; //undefined
引用:
对象通过引用来传递,他们永远不会被复制。
var stooge = { first_name:"dangxingming", last_name:"zhoulin" } var x = stooge; x.nickname = "Curly"; var nick = stooge.nickname; //因为x 和 stooge指向同一个对象的引用,所以nick为“Curly” var a = {}, var b = {}, var c = {}; //a b c 都引用不同的空对象 var a = b = c = {}; //a b c 都引用同一个空对象
原型:
每个对象都链接到一个原型对象,并且可以从中继承属性。所有通过对象字面量创建的对象都连接到Object.prototype,它是js中的标配对象。
当你创建一个对象时,可以选择某个对象作为它的原型。我们将给Object增加一个create方法。这个方法创建一个使用原对象作为其原型的新对象。
委托:原型对象只有在检索值时才用到,当我们尝试去获取某对象的值时,但该对象没有该值,那么js就会试着从原型对象中获取属性值。如果再没有,继续向上追溯,直到到达终点Object.prototype。如果还没有,那就是undefined值。
var stooge = { first_name:"dangxingming", last_name:"zhoulin" } if(typeof Object.beget !=="function"){ Object.create = function(o){ var F = function (){}; F.prototype = o; return new F(); }; } var another_stooge = Object.create(stooge); //当我们对某对象做出改变时,不会触及该对象的原型 another_stooge.first_name = "Harry"; stooge.first_name; //依然是dangxingming //原型关系是一种动态关系,当我们添加一个新属性到原型中去时,该属性立即对所有基于该原型创建的对象可见 stooge.first_name = "zhangsan"; another_stooge.first_name;//也变成zhangsan
反射:
确定对象的属性类型,typeof操作符和hasOwnProperty()方法var object2 = { first_name:"党兴明", //属性名是合法标识符可以不用引号 last_name:"林", another_obj1:{ time:"2016-11-09", city:"hangzhou" }, another_obj2{ home:"shengzhou" } }; //typeof typeof object2.first_name; //string typeof object2.another_obj1; //Object //原型链中的任何属性都会产生值 typeof Object2.toString; //function typeof Object2.constructor; //function //hasOwnProperty,如果对象拥有独有属性,它将返回true,此方法不会检查原型链 object2.hasOwnProperty("first_name");//true object2.hasOwnProperty("constructor");//false
枚举:
for in 语句可以用来遍历一个对象中的所有属性名。包括原型中的属性,可以通过hasOwnProperty方法,以及typeof来排除函数:
//for in属性名出现的顺序是不确定的 var name; for(name in another_stooge){ if(typeof another_stooge.name !== "function"){ document.writeln(name + ":" + another_stooge.name); } }
删除:
delete运算符可以用来删除对象的属性。如果对象包含该属性,那么该属性就会被移除,它不会触及原型链中的任何对象。
删除对象的属性可能让原型链中的属性暴露出来another_stooge.nickname; //"Moe" //删除another_stooge属性可能暴露出原型的nickname属性 delete another_stooge.nickname; another_stooge.nickname; //"Curly"
减少全局变量污染:
最小化使用全局变量的方法是为应用只创建唯一一个全局变量:
var MYAPP = {};
该变量此时变成你的应用的容器:
var MYAPP = {}; MYAPP.stooge = { first_name:"dangxingming", last_name:"zhoul" } MYAPP.object2 = { first_name:"党兴明", //属性名是合法标识符可以不用引号 last_name:"林", another_obj1:{ time:"2016-11-09", city:"hangzhou" }, another_obj2{ home:"shengzhou" } };
只要把全局性资源纳入一个命名空间下,程序与其他程序、组件、类库发生冲突的可能性会显著降低。
并且更容易阅读,因为很明显MYAPP.stooge指向的是顶层结构。下一章的闭包来进行信息隐藏。