`
abruzzi
  • 浏览: 444503 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

JavaScript内核系列 第3章 对象与JSON

阅读更多

第三章 对象与JSON

JavaScript对象与传统的面向对象中的对象几乎没有相似之处,传统的面向对象语言中,创建一个对象必须先有对象的模板:类,类中定义了对象的属性和操作这些属性的方法。通过实例化来构筑一个对象,然后使用对象间的协作来完成一项功能,通过功能的集合来完成整个工程。而Javascript中是没有类的概念的,借助JavaScript的动态性,我们完全可以创建一个空的对象(而不是类),通过像对象动态的添加属性来完善对象的功能。

JSONJavaScript中对象的字面量,是对象的表示方法,通过使用JSON,可以减少中间变量,使代码的结构更加清晰,也更加直观。使用JSON,可以动态的构建对象,而不必通过类来进行实例化,大大的提高了编码的效率。

3.1 Javascript对象

JavaScript对象其实就是属性的集合,这里的集合与数学上的集合是等价的,即具有确定性,无序性和互异性,也就是说,给定一个JavaScript对象,我们可以明确的知道一个属性是不是这个对象的属性,对象中的属性是无序的,并且是各不相同的(如果有同名的,则后声明的覆盖先声明的)

一般来说,我们声明对象的时候对象往往只是一个空的集合,不包含任何的属性,通过不断的添加属性,使得该对象成为一个有完整功能的对象,而不用通过创建一个类,然后实例化该类这种模式,这样我们的代码具有更高的灵活性,我们可以任意的增删对象的属性。

如果读者有python或其他类似的动态语言的经验,就可以更好的理解JavaScript的对象,JavaScript对象的本身就是一个字典(dictionary),或者Java语言中的Map,或者称为关联数组,即通过键来关联一个对象,这个对象本身又可以是一个对象,根据此定义,我们可以知道JavaScript对象可以表示任意复杂的数据结构。

3.1.1 对象的属性

属性是由键值对组成的,即属性的名字和属性的值。属性的名字是一个字符串,而值可以为任意的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]来进行访问。通常来说,我们在开发通用的工具包时,应该对用户可能的输入不做任何假设,通过[属性名]这种形式则总是可以保证正确性的。

3.1.2属性与变量

在第二章,我们讲解了变量的概念,在本章中,读者可能已经注意到,这二者的行为非常相似,事实上,对象的属性和我们之前所说的变量其实是一回事。

JavaScript引擎在初始化时,会构建一个全局对象,在客户端环境中,这个全局对象即为window。如果在其他的JavaScript环境中需要引用这个全局对象,只需要在顶级作用域(即所有函数声明之外的作用域)中声明:

 

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做一些操作  
}
 

 

 

3.1.3原型对象

原型(prototype),是JavaScript特有的一个概念,通过使用原型,JavaScript可以建立其传统OO语言中的继承,从而体现对象的层次关系。JavaScript本身是基于原型的,每个对象都有一个prototype的属性来,这个prototype本身也是一个对象,因此它本身也可以有自己的原型,这样就构成了一个链结构。

访问一个属性的时候,解析器需要从下向上的遍历这个链结构,直到遇到该属性,则返回属性对应的值,或者遇到原型为null的对象(JavaScript的基对象Objectprototype属性即为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
 

 

 

由于遍历原型链的时候,是有下而上的,所以最先遇到的属性值最先返回,通过这种机制可以完成重载的机制。

 

3.1.4 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的值并非函数如何被声明而确定,而是被函数如何被调用而确定,这一点与传统的面向对象语言截然不同,callFunction上的一个函数,详细描述在第四章。

3.2使用对象

对象是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
 

 

3.3 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"
    }
}
 

 

 

这种方式,显然比上边的例子简洁多了,没有冗余的中间变量,很清晰的表达了obj这样一个对象的结构。事实上,大多数有经验的JavaScript程序员更倾向与使用这种表示法,包括很多JavaScript的工具包如jQueryExtJS等都大量的使用了JSONJSON事实上已经作为一种前端与服务器端的数据交换格式,前端程序通过Ajax发送JSON对象到后端,服务器端脚本对JSON进行解析,还原成服务器端对象,然后做一些处理,反馈给前端的仍然是JSON对象,使用同一的数据格式,可以降低出错的概率。

         而且,JSON格式的数据本身是可以递归的,也就是说,可以表达任意复杂的数据形式。JSON的写法很简单,即用花括号括起来的键值对,键值对通过冒号隔开,而值可以是任意的JavaScript对象,如简单对象StringBooleanNumberNull,或者复杂对象如DateObject,其他自定义的对象等。

         JSON的另一个应用场景是:当一个函数拥有多个返回值时,在传统的面向对象语言中,我们需要组织一个对象,然后返回,而JavaScript则完全不需要这么麻烦,比如:

 

function point(left, top){
    this.left = left;
    this.top = top;
    //handle the left and top
    return {x: this.left, y:this.top};
}
 

 

 

直接动态的构建一个新的匿名对象返回即可:

 

var pos = point(3, 4);
//pos.x = 3;
//pos.y = 4;
 

 

 

使用JSON返回对象,这个对象可以有任意复杂的结构,甚至可以包括函数对象。

在实际的编程中,我们通常需要遍历一个JavaScript对象,事先我们对对象的内容一无所知。怎么做呢?JavaScript提供了for..in形式的语法糖:

 

for(var item in json){
    //item为键
    //json[item]为值
}
 

 

 

这种模式十分有用,比如,在实际的WEB应用中,对一个页面元素需要设置一些属性,这些属性是事先不知道的,比如:

 

var style = {
    border:"1px solid #ccc",
    color:"blue"
};
 

 

 

然后,我们给一个DOM元素动态的添加这些属性:

 

for(var item in style){
    //使用jQuery的选择器
    $("div#element").css(item, style[item]);
}
 

 

 

当然,jQuery有更好的办法来做这样一件事,这里只是举例子,应该注意的是,我们在给$("div#element")添加属性的时候,我们对style的结构是不清楚的。

 

另外比如我们需要收集一些用户的自定义设置,也可以通过公开一个JSON对象,用户将需要设置的内容填入这个JSON,然后我们的程序对其进行处理。

 

function customize(options){
    this.settings = $.extend(default, options);
}
 

 

 附:由于作者本身水平有限,文中难免有纰漏错误等,或者语言本身有不妥当之处,欢迎及时指正,提出建议,参与讨论,谢谢大家!

分享到:
评论
38 楼 wmz12389 2012-08-16  
abruzzi 写道
weiqingfei 写道
abruzzi 写道
weiqingfei 写道
abruzzi 写道
weiqingfei 写道
以面向对象的特性来解释javascript特别容易让人困惑。


怎么说呢,JavaScript本身就是面向对象的,一般这个特性叫做基于对象。同时,它又是“可编程”的,而大部分可以见到的代码都或多或少的体现了其函数式思想,所以JavaScript看起来让人觉得很混乱,代码风格千奇百怪,但是却都能工作。所以,我的建议是既不要把它看成OO的,也不要将其看成FP的,而是完全将其当作一门新的语言来学习,避免盲目的类比。


既然这样就不要提继承的概念,基于对象也不是面向对象。就像虽然同样适用new关键字,但是不看function的内容,你完全不知道它要返回的是什么类型的东西。


呵呵,不要偏颇,用继承的概念没有什么不好,帮助理解而已。基于对象就不能提用面向对象的概念吗?那如果我用诸如柯里化,闭包之类的函数式编程的概念来讲JS的函数式特性,也不行吗?


如果你理解里面的内部机制,怎么说都行,怎么说也觉得没什么问题,可是对于初学者,尤其对于接触过oo的初学者来讲,确实容易混淆。
就像这句话一样“每个对象都有一个prototype的属性来,这个prototype本身也是一个对象”,我想其实你自己是明白这句话的意思的,可是对于初学者来讲,这里的两个“对象”是一个意思么,是,指的是什么,不是,又分别指的什么?


哦,也对,文字上有些地方还是要好好琢磨琢磨,谢谢你的建议!



基于对象是从javascript的代码构成来说的,面向对象是从编程的思维方式来说的,二者没有多大的关系,java不是基于对象的,但是是面向对象的,javascript是基于对象的,但是是面向过程的。
37 楼 luolonghao 2010-06-12  
楼主对JavaScript对象的理解有些问题,{}和new Object()是等价的,{}是new Object()的简写。

var jack = new Object();
jack.name = "jack";
jack.age = 26;

这段代码可以这么写,做完全相同的事情,只是写法不一样。

var jack = {
    name : "jack",
    age : 26
};

还有,JSON是一种文本数据格式,和xml、yaml一个概念,只是它的格式直接用了JavaScript的object写法而已,除此之外和JavaScript一点关系都没有。
36 楼 t42dw 2010-06-11  
又重新温习了一个对象与json,哈哈看样子我js水平还行呢大部分都有过实战经验了!
继续拜读你的大作,写的真是不错
35 楼 Wanghuidong 2010-05-26  
abruzzi 写道
Wanghuidong 写道
中间有点代码有问题吧

var abruzzi = new Person('abruzzi', 26);
结果 getAdr()都出错啊 明明为null啊


不知道你用什么测试的,这个系列的前几篇几乎都是在rhino上测的,你也可以试试这个执行器:
http://www.squarefree.com/shell/shell.html
没有问题的,浏览器我暂时尽量不涉及,谢谢。




我测试了
结果是
JavaScript Shell 1.4
Features: autocompletion of property names with Tab, multiline input with Shift+Enter, input history with (Ctrl+) Up/Down, Math, help
Values and functions: ans, print(string), props(object), blink(node), clear(), load(scriptURL), scope(object)
Using bookmarklet version of shell: commands will run in opener's context.

这有什么影响吗 ?
34 楼 abruzzi 2010-05-24  
meiowei 写道
address.street = "Huang Quan Road";

黄泉路?真幽默


呵呵,看的很仔细,以前在javaeye上看到有个朋友,好像是湖北的,说上班路上看到一个路牌,写着“黄泉路”,我就经常拿来开玩笑。
33 楼 abruzzi 2010-05-24  
Eduardo 写道
纠正楼主一个错误,
# var ja = jack.addr; 
#   
# ja = jack[addr];
应该是ja=jack["addr"],我是在ie里测试的,不知道在别的浏览器效果是怎样的,这个我在javasceipt精粹里看到好像也是要加引号的


嗯,是要加引号的,一时疏忽,谢谢了。
32 楼 meiowei 2010-05-24  
address.street = "Huang Quan Road";

黄泉路?真幽默
31 楼 Eduardo 2010-05-23  
纠正楼主一个错误,
# var ja = jack.addr; 
#   
# ja = jack[addr];
应该是ja=jack["addr"],我是在ie里测试的,不知道在别的浏览器效果是怎样的,这个我在javasceipt精粹里看到好像也是要加引号的
30 楼 liushilang 2010-05-19  
你一系列的资料很不错,有的章节,我是看了好几遍,因为有的地方,看一次看不懂,学习了
29 楼 fengfantasy 2010-05-18  
看了几章了

写得很不错

支持LZ

28 楼 wangdongsong 2010-05-08  
<div class="quote_title">abruzzi 写道</div>
<div class="quote_div">
<h2>
<a name="_Toc252397755"><span>第三章</span> </a><span><span>对象与</span><span lang="EN-US">JSON</span></span>
</h2>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span lang="EN-US">JavaScript</span><span>对象与传统的面向对象中的对象几乎没有相似之处,传统的面向对象语言中,创建一个对象必须先有对象的模板:类,类中定义了对象的属性和操作这些属性的方法。通过实例化来构筑一个对象,然后使用对象间的协作来完成一项功能,通过功能的集合来完成整个工程。而</span><span lang="EN-US">Javascript</span><span>中是没有类的概念的,借助</span><span lang="EN-US">JavaScript</span><span>的动态性,我们完全可以创建一个空的对象</span><span lang="EN-US">(</span><span>而不是类</span><span lang="EN-US">)</span><span>,通过像对象动态的添加属性来完善对象的功能。</span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span lang="EN-US">JSON</span><span>是</span><span lang="EN-US">JavaScript</span><span>中对象的字面量,是对象的表示方法,通过使用</span><span lang="EN-US">JSON</span><span>,可以减少中间变量,使代码的结构更加清晰,也更加直观。使用</span><span lang="EN-US">JSON</span><span>,可以动态的构建对象,而不必通过类来进行实例化,大大的提高了编码的效率。</span></p>
<h3>
<a name="_Toc252397756"><span lang="EN-US">3.1 Javascript</span></a><span><span>对象</span></span>
</h3>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span lang="EN-US">JavaScript</span><span>对象其实就是属性的集合,这里的集合与数学上的集合是等价的,即具有确定性,无序性和互异性,也就是说,给定一个</span><span lang="EN-US">JavaScript</span><span>对象,我们可以明确的知道一个属性是不是这个对象的属性,对象中的属性是无序的,并且是各不相同的</span><span lang="EN-US">(</span><span>如果有同名的,则后声明的覆盖先声明的</span><span lang="EN-US">)</span><span>。</span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span>一般来说,我们声明对象的时候对象往往只是一个空的集合,不包含任何的属性,通过不断的添加属性,使得该对象成为一个有完整功能的对象,而不用通过创建一个类,然后实例化该类这种模式,这样我们的代码具有更高的灵活性,我们可以任意的增删对象的属性。</span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span>如果读者有</span><span lang="EN-US">python</span><span>或其他类似的动态语言的经验</span><span lang="EN-US">,</span><span>就可以更好的理解</span><span lang="EN-US">JavaScript</span><span>的对象,</span><span lang="EN-US">JavaScript</span><span>对象的本身就是一个字典</span><span lang="EN-US">(dictionary)</span><span>,或者</span><span lang="EN-US">Java</span><span>语言中的</span><span lang="EN-US">Map</span><span>,或者称为关联数组,即通过键来关联一个对象,这个对象本身又可以是一个对象,根据此定义,我们可以知道</span><span lang="EN-US">JavaScript</span><span>对象可以表示任意复杂的数据结构。</span></p>
<h4>
<a name="_Toc252397757"><span lang="EN-US">3.1.1 </span></a><span><span>对象的属性</span></span>
</h4>
<p class="MsoNormal"><span>属性是由键值对组成的,即属性的名字和属性的值。属性的名字是一个字符串,而值可以为任意的</span><span lang="EN-US">JavaScript</span><span>对象</span><span lang="EN-US">(JavaScript</span><span>中的一切皆对象,包括函数</span><span lang="EN-US">)</span><span>。比如,声明一个对象:</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #808000; font-size: small;"><span style="font-size: 13px;">
</span></span></p>
<pre name="code" class="js">//声明一个对象
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;</pre>
 
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>这种声明对象的方式与传统的<span lang="EN-US">OO</span>语言是截然不同的,它给了我们极大的灵活性来定制一个对象的行为。</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span>对象属性的读取方式是通过点操作符<span lang="EN-US">(.)</span>来进行的,比如上例中<span lang="EN-US">jack</span>对象的<span lang="EN-US">addr</span>属性,可以通过下列方式取得:</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">var ja = jack.addr;

ja = jack[addr];</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>后者是为了避免这种情况,设想对象有一个属性本身包含一个点<span lang="EN-US">(.)</span>,这在<span lang="EN-US">JavaScript</span>中是合法的,比如说名字为<span lang="EN-US">foo.bar</span>,当使用<span lang="EN-US">jack.foo.bar</span>的时候,解释器会误以为<span lang="EN-US">foo</span>属性下有一个<span lang="EN-US">bar</span>的字段,因此可以使用<span lang="EN-US">jack[foo.bar]</span>来进行访问。通常来说,我们在开发通用的工具包时,应该对用户可能的输入不做任何假设,通过<span lang="EN-US">[</span>属性名<span lang="EN-US">]</span>这种形式则总是可以保证正确性的。</span></p>
<h4>
<a name="_Toc252397758"><span lang="EN-US">3.1.2</span></a><span><span>属性与变量</span></span>
</h4>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span>在第二章,我们讲解了变量的概念,在本章中,读者可能已经注意到,这二者的行为非常相似,事实上,对象的属性和我们之前所说的变量其实是一回事。</span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span lang="EN-US">JavaScript</span><span>引擎在初始化时,会构建一个全局对象,在客户端环境中,这个全局对象即为</span><span lang="EN-US">window</span><span>。如果在其他的</span><span lang="EN-US">JavaScript</span><span>环境中需要引用这个全局对象,只需要在顶级作用域</span><span lang="EN-US">(</span><span>即所有函数声明之外的作用域</span><span lang="EN-US">)</span><span>中声明:</span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left; text-indent: 21.0pt;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">var global = this;</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span>我们在顶级作用域中声明的变量将作为全局对象的属性被保存,从这一点上来看,变量其实就是属性。比如,在客户端,经常会出现这样的代码:</span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">var v = "global";

var array = ["hello", "world"];

function func(id){
    var element = document.getElementById(id);
    //对elemen做一些操作
}</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>事实上相当于:</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0064c8; font-size: small;"><span style="font-size: 13px;">
</span></span></p>
<pre name="code" class="js">window.v = "global";

window.array = ["hello", "world"];

window.func = function(id){
    var element = document.getElementById(id);
    //对elemen做一些操作 
}</pre>
 
<p> </p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<h4>
<a name="_Toc252397759"><span lang="EN-US">3.1.3</span></a><span><span>原型对象</span></span>
</h4>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span>原型</span><span lang="EN-US">(prototype)</span><span>,是</span><span lang="EN-US">JavaScript</span><span>特有的一个概念,通过使用原型,</span><span lang="EN-US">JavaScript</span><span>可以建立其传统</span><span lang="EN-US">OO</span><span>语言中的继承,从而体现对象的层次关系。</span><span lang="EN-US">JavaScript</span><span>本身是基于原型的,每个对象都有一个</span><span lang="EN-US">prototype</span><span>的属性来,这个</span><span lang="EN-US">prototype</span><span>本身也是一个对象,因此它本身也可以有自己的原型,这样就构成了一个链结构。</span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span>访问一个属性的时候,解析器需要从下向上的遍历这个链结构,直到遇到该属性,则返回属性对应的值,或者遇到原型为</span><span lang="EN-US">null</span><span>的对象</span><span lang="EN-US">(JavaScript</span><span>的基对象</span><span lang="EN-US">Object</span><span>的</span><span lang="EN-US">prototype</span><span>属性即为</span><span lang="EN-US">null)</span><span>,如果此对象仍没有该属性,则返回</span><span lang="EN-US">undefined.</span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span>下面我们看一个具体的例子:</span></p>
<p class="MsoNormal" style="text-indent: 21.0pt;"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #808000; font-size: small;"><span style="font-size: 13px;">
</span></span></p>
<pre name="code" class="js">//声明一个对象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());</pre>
 
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>得出结果:</span></p>
<p class="MsoNormal"><span style="" lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; font-size: small;"><span style="font-size: 13px;">
</span></span></p>
<div class="quote_div">child<br>base</div>
 
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>由于遍历原型链的时候,是有下而上的,所以最先遇到的属性值最先返回,通过这种机制可以完成重载的机制。</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<h4>
<a name="_Toc252397760"><span lang="EN-US">3.1.4 this</span></a><span><span>指针</span></span>
</h4>
<p class="MsoNormal"><span lang="EN-US"><span>         </span>JavaScript</span><span>中最容易使人迷惑的恐怕就数</span><span lang="EN-US">this</span><span>指针了,</span><span lang="EN-US">this</span><span>指针在传统</span><span lang="EN-US">OO</span><span>语言中,是在类中声明的,表示对象本身,而在</span><span lang="EN-US">JavaScript</span><span>中,</span><span lang="EN-US">this</span><span>表示当前上下文,即调用者的引用。这里我们可以来看一个常见的例子:</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #808000; font-size: small;"><span style="font-size: 13px;">
</span></span></p>
<pre name="code" class="js">//定义一个人,名字为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));</pre>
 
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>运行结果:</span></p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; font-size: small;"><span style="font-size: 13px;">
</span></span></p>
<div class="quote_div">jack<br>Abruzzi</div>
 
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>应该注意的是,</span><span style="font-size: 10.0pt;" lang="EN-US">this</span><span>的值并非函数如何被声明而确定,而是被函数如何被调用而确定,这一点与传统的面向对象语言截然不同,</span><span style="font-size: 10.0pt;" lang="EN-US">call</span><span>是</span><span style="font-size: 10.0pt;" lang="EN-US">Function</span><span>上的一个函数,详细描述在第四章。</span></p>
<h3>
<a name="_Toc252397761"><span lang="EN-US">3.2</span></a><span><span>使用对象</span></span>
</h3>
<p class="MsoNormal"><span>对象是</span><span lang="EN-US">JavaScript</span><span>的基础,我们使用</span><span lang="EN-US">JavaScript</span><span>来完成编程工作就是通过使用对象来体现的,这一小节通过一些例子来学习如何使用</span><span lang="EN-US">JavaScript</span><span>对象:</span></p>
<p class="MsoNormal"><span>对象的声明有三种方式:</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span style="font-family: Wingdings;" lang="EN-US"><span>Ø<span style="font: 7.0pt ;">  </span></span></span><span>通过</span><span lang="EN-US">new</span><span>操作符作用域</span><span lang="EN-US">Object</span><span>对象,构造一个新的对象,然后动态的添加属性,从无到有的构筑一个对象。</span></p>
<p class="MsoNormal"><span style="font-family: Wingdings;" lang="EN-US"><span>Ø<span style="font: 7.0pt ;">  </span></span></span><span>定义对象的“类”</span><span lang="EN-US">:</span><span>原型,然后使用</span><span lang="EN-US">new</span><span>操作符来批量的构筑新的对象。</span></p>
<p class="MsoNormal"><span style="font-family: Wingdings;" lang="EN-US"><span>Ø<span style="font: 7.0pt ;">  </span></span></span><span>使用</span><span lang="EN-US">JSON</span><span>,这个在下一节来进行详细说明</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span>这一节我们详细说明第二种方式,如:</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #808000; font-size: small;"><span style="font-size: 13px;">
</span></span></p>
<pre name="code" class="js">//定义一个"类",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());</pre>
 
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>运行结果如下:</span></p>
<p class="MsoNormal"><span style="" lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; font-size: small;"><span style="font-size: 13px;">
</span></span></p>
<div class="quote_div">jack<br>26<br>street : Qing Hai Road, No : 123<br>abruzzi<br>26<br>street : Huang Quan Road, No : 135</div>
 
<p> </p>
<h3>
<a name="_Toc252397762"><span lang="EN-US">3.3 JSON</span></a><span><span>及其使用</span></span>
</h3>
<p class="MsoNormal"><span lang="EN-US">JSON</span><span>全称为</span><span lang="EN-US">JavaScript</span><span>对象表示法</span><span lang="EN-US">(JavaScript
Object Notation)</span><span>,即通过字面量来表示一个对象,从简单到复杂均可使用此方式。比如:</span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><strong><span style="font-size: 10.0pt;" lang="EN-US"> </span></strong></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">var obj = {
    name : "abruzzi",
    age : 26,
    birthday : new Date(1984, 4, 5),
    addr : {
       street : "Huang Quan Road",
       xno : "135"
    }
}</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>这种方式,显然比上边的例子简洁多了,没有冗余的中间变量,很清晰的表达了</span><span style="color: black;" lang="EN-US">obj</span><span>这样一个对象的结构。事实上,大多数有经验的</span><span style="color: black;" lang="EN-US">JavaScript</span><span>程序员更倾向与使用这种表示法,包括很多</span><span style="color: black;" lang="EN-US">JavaScript</span><span>的工具包如</span><span style="color: black;" lang="EN-US">jQuery</span><span>,</span><span style="color: black;" lang="EN-US">ExtJS</span><span>等都大量的使用了</span><span style="color: black;" lang="EN-US">JSON</span><span>。</span><span style="color: black;" lang="EN-US">JSON</span><span>事实上已经作为一种前端与服务器端的数据交换格式,前端程序通过</span><span style="color: black;" lang="EN-US">Ajax</span><span>发送</span><span style="color: black;" lang="EN-US">JSON</span><span>对象到后端,服务器端脚本对</span><span style="color: black;" lang="EN-US">JSON</span><span>进行解析,还原成服务器端对象,然后做一些处理,反馈给前端的仍然是</span><span style="color: black;" lang="EN-US">JSON</span><span>对象,使用同一的数据格式,可以降低出错的概率。</span></p>
<p class="MsoNormal"><span style="color: black;" lang="EN-US"><span>         </span></span><span>而且,</span><span style="color: black;" lang="EN-US">JSON</span><span>格式的数据本身是可以递归的,也就是说,可以表达任意复杂的数据形式。</span><span style="color: black;" lang="EN-US">JSON</span><span>的写法很简单,即用花括号括起来的键值对,键值对通过冒号隔开,而值可以是任意的</span><span style="color: black;" lang="EN-US">JavaScript</span><span>对象,如简单对象</span><span style="color: black;" lang="EN-US">String</span><span>,</span><span style="color: black;" lang="EN-US">Boolean</span><span>,</span><span style="color: black;" lang="EN-US">Number</span><span>,</span><span style="color: black;" lang="EN-US">Null</span><span>,或者复杂对象如</span><span style="color: black;" lang="EN-US">Date</span><span>,</span><span style="color: black;" lang="EN-US">Object</span><span>,其他自定义的对象等。</span></p>
<p class="MsoNormal"><span style="color: black;" lang="EN-US"><span>         </span>JSON</span><span>的另一个应用场景是:当一个函数拥有多个返回值时,在传统的面向对象语言中,我们需要组织一个对象,然后返回,而</span><span style="color: black;" lang="EN-US">JavaScript</span><span>则完全不需要这么麻烦,比如:</span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><strong><span style="font-size: 10.0pt;" lang="EN-US"> </span></strong></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">function point(left, top){
    this.left = left;
    this.top = top;
    //handle the left and top
    return {x: this.left, y:this.top};
}</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>直接动态的构建一个新的匿名对象返回即可:</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">var pos = point(3, 4);
//pos.x = 3;
//pos.y = 4;</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal"><span style="font-size: 10.0pt;" lang="EN-US"> </span></p>
<p class="MsoNormal"><span>使用</span><span lang="EN-US">JSON</span><span>返回对象,这个对象可以有任意复杂的结构,甚至可以包括函数对象。</span></p>
<p class="MsoNormal"><span>在实际的编程中,我们通常需要遍历一个</span><span lang="EN-US">JavaScript</span><span>对象,事先我们对对象的内容一无所知。怎么做呢?</span><span lang="EN-US">JavaScript</span><span>提供了</span><span lang="EN-US">for..in</span><span>形式的语法糖:</span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><strong><span style="font-size: 10.0pt;" lang="EN-US"> </span></strong></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">for(var item in json){
    //item为键
    //json[item]为值
}</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span>这种模式十分有用,比如,在实际的</span><span lang="EN-US">WEB</span><span>应用中,对一个页面元素需要设置一些属性,这些属性是事先不知道的,比如:</span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><strong><span style="font-size: 10.0pt;" lang="EN-US"> </span></strong></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">var style = {
    border:"1px solid #ccc",
    color:"blue"
};</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span>然后,我们给一个</span><span lang="EN-US">DOM</span><span>元素动态的添加这些属性:</span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><strong><span style="font-size: 10.0pt;" lang="EN-US"> </span></strong></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">for(var item in style){
    //使用jQuery的选择器
    $("div#element").css(item, style[item]);
}</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span>当然,</span><span lang="EN-US">jQuery</span><span>有更好的办法来做这样一件事,这里只是举例子,应该注意的是,我们在给</span><span style="" lang="EN-US">$("div#element")</span><span>添加属性的时候,我们对</span><span lang="EN-US">style</span><span>的结构是不清楚的。</span></p>
<p class="MsoNormal"><span lang="EN-US"> </span></p>
<p class="MsoNormal"><span>另外比如我们需要收集一些用户的自定义设置,也可以通过公开一个</span><span lang="EN-US">JSON</span><span>对象,用户将需要设置的内容填入这个</span><span lang="EN-US">JSON</span><span>,然后我们的程序对其进行处理。</span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><strong><span style="font-size: 10.0pt;" lang="EN-US"> </span></strong></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-family: 'Courier New'; color: #0000c8; font-size: small;"><span style="font-size: 13px;"><strong>
</strong></span></span></p>
<p><strong>
<pre name="code" class="js">function customize(options){
    this.settings = $.extend(default, options);
}</pre>
 </strong></p>
<p> </p>
<p class="MsoNormal"><span lang="EN-US"> <span style="font-family: Arial, sans-serif, Helvetica, Tahoma; line-height: 18px;"><strong style="font-weight: bold;">附:由于作者本身水平有限,文中难免有纰漏错误等,或者语言本身有不妥当之处,欢迎及时指正,提出建议,参与讨论,谢谢大家!</strong></span></span></p>
</div>
<br>
27 楼 lipeng88213 2010-05-07  
<div class="quote_title">abruzzi 写道</div>
<div class="quote_div">
<div class="quote_title">lipeng88213 写道</div>
<div class="quote_div">
<div class="quote_title"><span style="font-weight: normal;"><strong>
<div class="quote_title"> 写道</div>
<div class="quote_div">3.3 JSON及其使用<br><br>JSON全称为JavaScript对象表示法(JavaScript Object Notation),即通过字面量来表示一个对象,从简单到复杂均可使用此方式。比如:<br><br> var obj = {<br>    name : "abruzzi",<br>    age : 26,<br>    birthday : new Date(1984, 4, 5),<br>    addr : {<br>       street : "Huang Quan Road",<br>       xno : "135"<br>    }<br>}<br>
</div>
 这个通过json来创建对象,和前面那个通过new的方式有什么不同吗  如果用json来创建的话 好像name,age等属性的值都固定了吧 这有什么用啊</strong></span></div>
</div>
<p>在JavaScript中,没有什么固定的东西,比如这里定义了obj,同样可以通过:</p>
<p> </p>
<p> </p>
<pre name="code" class="js">obj.getName = function(){};
obj.pid = "parent";
</pre>
<p> </p>
<p>来修改。使用Json的好处事实上显而易见:</p>
<p>1.更加清晰,较</p>
<pre name="code" class="js">function obj(){
var name = "abruzzi";
var age = 26;
//...
}</pre>
<p> 的形式明显简洁</p>
<p> </p>
<p>2.不会从继承连上得到一些不必要的属性或者方法</p>
<p> </p>
<p>JSON一般用于简单的一次型对象,并且作为数据交换的一种格式,较之XML可能更轻量级!</p>
</div>
<p><span style="white-space: pre;"> </span>恩  领教了 谢谢楼主</p>
26 楼 abruzzi 2010-05-07  
<div class="quote_title">lipeng88213 写道</div>
<div class="quote_div">
<div class="quote_title"><span style="font-weight: normal;"><strong>
<div class="quote_title"> 写道</div>
<div class="quote_div">3.3 JSON及其使用<br><br>JSON全称为JavaScript对象表示法(JavaScript Object Notation),即通过字面量来表示一个对象,从简单到复杂均可使用此方式。比如:<br><br> var obj = {<br>    name : "abruzzi",<br>    age : 26,<br>    birthday : new Date(1984, 4, 5),<br>    addr : {<br>       street : "Huang Quan Road",<br>       xno : "135"<br>    }<br>}<br>
</div>
 这个通过json来创建对象,和前面那个通过new的方式有什么不同吗  如果用json来创建的话 好像name,age等属性的值都固定了吧 这有什么用啊</strong></span></div>
</div>
<p>在JavaScript中,没有什么固定的东西,比如这里定义了obj,同样可以通过:</p>
<p> </p>
<p> </p>
<pre name="code" class="js">obj.getName = function(){};
obj.pid = "parent";
</pre>
<p> </p>
<p>来修改。使用Json的好处事实上显而易见:</p>
<p>1.更加清晰,较</p>
<pre name="code" class="js">function obj(){
var name = "abruzzi";
var age = 26;
//...
}</pre>
<p> 的形式明显简洁</p>
<p> </p>
<p>2.不会从继承连上得到一些不必要的属性或者方法</p>
<p> </p>
<p>JSON一般用于简单的一次型对象,并且作为数据交换的一种格式,较之XML可能更轻量级!</p>
25 楼 lipeng88213 2010-05-07  
<div class="quote_title"><span style="font-weight: normal;"><strong>
<div class="quote_title"> 写道</div>
<div class="quote_div">3.3 JSON及其使用<br><br>JSON全称为JavaScript对象表示法(JavaScript Object Notation),即通过字面量来表示一个对象,从简单到复杂均可使用此方式。比如:<br><br> var obj = {<br>    name : "abruzzi",<br>    age : 26,<br>    birthday : new Date(1984, 4, 5),<br>    addr : {<br>       street : "Huang Quan Road",<br>       xno : "135"<br>    }<br>}<br>
</div>
 这个通过json来创建对象,和前面那个通过new的方式有什么不同吗  如果用json来创建的话 好像name,age等属性的值都固定了吧 这有什么用啊</strong></span></div>
24 楼 weiqingfei 2010-04-22  
我上面所说的话,也不是十分严谨。
Object的prototype属性所指向的对象实例,和普通情况下使用new Object所生成的对象实例还是不一样的。

从ECMA Javascript的角度来看,就是Object的prototype属性,默认是没有__proto__属性(严格来讲是__proto__属性为空)的。
23 楼 abruzzi 2010-04-22  
翻译过来应该是这样:
原型链终止与有null原型的对象,Object的构造的默认原型有一个null原型。
意思是说,Object默认构造是“有null原型的对象”,因此链会断开,对吧?

是我的理解有误,谢谢你的指正!
22 楼 weiqingfei 2010-04-22  
abruzzi 写道
weiqingfei 写道
另外,既然看到了,就指出来吧。
这句话,你是怎么得来的?希望你再验证一下,如果是依据于特殊执行环境,请明示一下。
引用

JavaScript的基对象Object的prototype属性即为null


应该是来源于这里:
引用

But all objects may have prototypes, and prototypes are objects so they, in turn, may have prototypes, which may have prototypes, and so on forming what is called the prototype chain. The prototype chain ends when one of the objects in the chain has a null prototype. The default prototype for the Object constructor has a null prototype


文章的链接在此
http://www.jibbering.com/faq/faq_notes/closures.html
此文是John(jQuery之父)推荐的一篇文章,我拿来读了好几遍。个人也很推荐,非常值得一读。


请正确理解mark的这句话,这里是用的是has,不是is。
不是说Object的prototype是空,而是Object的prototype属性是一个空的对象(Object)实例,而这个实例是没有prototype属性的,也就是说prototype链在这儿断开了。

这句话也是你的描述语病?
21 楼 abruzzi 2010-04-22  
weiqingfei 写道
另外,既然看到了,就指出来吧。
这句话,你是怎么得来的?希望你再验证一下,如果是依据于特殊执行环境,请明示一下。
引用

JavaScript的基对象Object的prototype属性即为null


应该是来源于这里:
引用

But all objects may have prototypes, and prototypes are objects so they, in turn, may have prototypes, which may have prototypes, and so on forming what is called the prototype chain. The prototype chain ends when one of the objects in the chain has a null prototype. The default prototype for the Object constructor has a null prototype


文章的链接在此
http://www.jibbering.com/faq/faq_notes/closures.html
此文是John(jQuery之父)推荐的一篇文章,我拿来读了好几遍。个人也很推荐,非常值得一读。
20 楼 weiqingfei 2010-04-22  
另外,既然看到了,就指出来吧。
这句话,你是怎么得来的?希望你再验证一下,如果是依据于特殊执行环境,请明示一下。
引用

JavaScript的基对象Object的prototype属性即为null
19 楼 abruzzi 2010-04-22  
weiqingfei 写道
abruzzi 写道
weiqingfei 写道
abruzzi 写道
weiqingfei 写道
以面向对象的特性来解释javascript特别容易让人困惑。


怎么说呢,JavaScript本身就是面向对象的,一般这个特性叫做基于对象。同时,它又是“可编程”的,而大部分可以见到的代码都或多或少的体现了其函数式思想,所以JavaScript看起来让人觉得很混乱,代码风格千奇百怪,但是却都能工作。所以,我的建议是既不要把它看成OO的,也不要将其看成FP的,而是完全将其当作一门新的语言来学习,避免盲目的类比。


既然这样就不要提继承的概念,基于对象也不是面向对象。就像虽然同样适用new关键字,但是不看function的内容,你完全不知道它要返回的是什么类型的东西。


呵呵,不要偏颇,用继承的概念没有什么不好,帮助理解而已。基于对象就不能提用面向对象的概念吗?那如果我用诸如柯里化,闭包之类的函数式编程的概念来讲JS的函数式特性,也不行吗?


如果你理解里面的内部机制,怎么说都行,怎么说也觉得没什么问题,可是对于初学者,尤其对于接触过oo的初学者来讲,确实容易混淆。
就像这句话一样“每个对象都有一个prototype的属性来,这个prototype本身也是一个对象”,我想其实你自己是明白这句话的意思的,可是对于初学者来讲,这里的两个“对象”是一个意思么,是,指的是什么,不是,又分别指的什么?


哦,也对,文字上有些地方还是要好好琢磨琢磨,谢谢你的建议!

相关推荐

Global site tag (gtag.js) - Google Analytics