属性是由键值对组成的,即属性的名字和属性的值。属性的名字是一个字符串,而值可以为任意的JavaScript对象(JavaScript中的一切皆对象,包括函数)。比如,声明一个对象: 复制代码 代码如下: //声明一个对象 var jack = new Object(); jack.name = "jack"; jack.age = 26; jack.birthday = new Date(1984, 4, 5);
//声明另一个对象 var address = new Object(); address.street = "Huang Quan Road"; address.xno = "135";
//将addr属性赋值为对象address jack.addr = address;
这种声明对象的方式与传统的OO语言是截然不同的,它给了我们极大的灵活性来定制一个对象的行为。
对象属性的读取方式是通过点操作符(.)来进行的,比如上例中jack对象的addr属性,可以通过下列方式取得: 复制代码 代码如下:var ja = jack.addr; ja = jack[addr]; 后者是为了避免这种情况,设想对象有一个属性本身包含一个点(.),这在JavaScript中是合法的,比如说名字为foo.bar,当使用jack.foo.bar的时候,解释器会误以为foo属性下有一个bar的字段,因此可以使用jack[foo.bar]来进行访问。通常来说,我们在开发通用的工具包时,应该对用户可能的输入不做任何假设,通过[属性名]这种形式则总是可以保证正确性的。
复制代码 代码如下:var global = this; 我们在顶级作用域中声明的变量将作为全局对象的属性被保存,从这一点上来看,变量其实就是属性。比如,在客户端,经常会出现这样的代码:
复制代码 代码如下:var v = "global"; var array = ["hello", "world"]; function func(id){ var element = document.getElementById(id); //对elemen做一些操作 } 事实上相当于: 复制代码 代码如下: window.v = "global"; window.array = ["hello", "world"]; window.func = function(id){ var element = document.getElementById(id); //对elemen做一些操作 }
原型对象 原型(prototype),是JavaScript特有的一个概念,通过使用原型,JavaScript可以建立其传统OO语言中的继承,从而体现对象的层次关系。JavaScript本身是基于原型的,每个对象都有一个prototype的属性来,这个prototype本身也是一个对象,因此它本身也可以有自己的原型,这样就构成了一个链结构。 访问一个属性的时候,解析器需要从下向上的遍历这个链结构,直到遇到该属性,则返回属性对应的值,或者遇到原型为null的对象(JavaScript的基对象Object的prototype属性即为null),如果此对象仍没有该属性,则返回undefined. 下面我们看一个具体的例子: 复制代码 代码如下: //声明一个对象base function Base(name){ this.name = name; this.getName = function(){ return this.name; } } //声明一个对象child function Child(id){ this.id = id; this.getId = function(){ return this.id; } } //将child的原型指向一个新的base对象 Child.prototype = new Base("base"); //实例化一个child对象 var c1 = new Child("child"); //c1本身具有getId方法 print(c1.getId()); //由于c1从原型链上"继承"到了getName方法,因此可以访问 print(c1.getName());
得出结果: child base 由于遍历原型链的时候,是有下而上的,所以最先遇到的属性值最先返回,通过这种机制可以完成重载的机制。 this指针 JavaScript中最容易使人迷惑的恐怕就数this指针了,this指针在传统OO语言中,是在类中声明的,表示对象本身,而在JavaScript中,this表示当前上下文,即调用者的引用。这里我们可以来看一个常见的例子: 复制代码 代码如下: //定义一个人,名字为jack var jack = { name : "jack", age : 26 } //定义另一个人,名字为abruzzi var abruzzi = { name : "abruzzi", age : 26 } //定义一个全局的函数对象 function printName(){ return this.name; } //设置printName的上下文为jack, 此时的this为jack print(printName.call(jack)); //设置printName的上下文为abruzzi,此时的this为abruzzi print(printName.call(abruzzi));
运行结果: jack Abruzzi 应该注意的是,this的值并非函数如何被声明而确定,而是被函数如何被调用而确定,这一点与传统的面向对象语言截然不同,call是Function上的一个函数,详细描述在第四章。 使用对象 对象是JavaScript的基础,我们使用JavaScript来完成编程工作就是通过使用对象来体现的,这一小节通过一些例子来学习如何使用JavaScript对象: 对象的声明有三种方式: ◆ 通过new操作符作用域Object对象,构造一个新的对象,然后动态的添加属性,从无到有的构筑一个对象。 ◆ 定义对象的“类”:原型,然后使用new操作符来批量的构筑新的对象。 ◆ 使用JSON,这个在下一节来进行详细说明 这一节我们详细说明第二种方式,如: 复制代码 代码如下: //定义一个"类",Address function Address(street, xno){ this.street = street || "Huang Quan Road"; this.xno = xno || 135; this.toString = function(){ return "street : " + this.street + ", No : " + this.xno; } } //定义另一个"类",Person function Person (name, age, addr) { this.name = name || "unknown"; this.age = age; this.addr = addr || new Address(null, null); this.getName = function () {return this.name;} this.getAge = function(){return this.age;} this.getAddr = function(){return this.addr.toString();} } //通过new操作符来创建两个对象,注意,这两个对象是相互独立的实体 var jack = new Person("jack", 26, new Address("Qing Hai Road", 123)); var abruzzi = new Person("abruzzi", 26); //查看结果 print(jack.getName()); print(jack.getAge()); print(jack.getAddr()); print(abruzzi.getName()); print(abruzzi.getAge()); print(abruzzi.getAddr());
运行结果如下: jack 26 street : Qing Hai Road, No : 123 abruzzi 26 street : Huang Quan Road, No : 135
JSON及其使用
JSON全称为JavaScript对象表示法(JavaScript Object Notation),即通过字面量来表示一个对象,从简单到复杂均可使用此方式。比如: 复制代码 代码如下: var obj = { name : "abruzzi", age : 26, birthday : new Date(1984, 4, 5), addr : { street : "Huang Quan Road", xno : "135" } }