一柬祠、了解創(chuàng)建函數(shù)對象時new的過程。 我們先看一段代碼:
<script type="text/javascript">
var Person = function () { };
var p = new Person();
</script>
我們可以把new的過程拆分成以下三步:
<1> var p={}; 初始化一個對象p负芋。
<2> p.__proto__=Person.prototype;
<3> Person.call(p);也就是說構(gòu)造p漫蛔,也可以稱之為初始化p。
二旧蛾、 此三步的關(guān)鍵點時是第二步莽龟,以下為證明材料證明一下:
<script type="text/javascript">
var Person = function() { };
var p = new Person();
alert(p.__proto__ === Person.prototype);
</script>
1、首先锨天,我們先理解下proto是什么毯盈?
每個對象都會在其內(nèi)部初始化一個屬性,就是__proto__病袄,當我們訪問一個對象的屬性時搂赋,如果這個對象內(nèi)部不存在這個屬性,那么他就會去__proto__里找這個屬性益缠,這個__proto__又會有自己的__proto__脑奠,一直找下去,這也就是我們平時所說的原型鏈的概念幅慌。
2宋欺、了解proto屬性特點
按照標準,__proto__是不對外公開的胰伍,也就是說是個私有屬性齿诞,但 是Firefox的引擎將他暴露了出來成為了一個共有的屬性,我們可以對外訪問和設(shè)置骂租。
3祷杈、讓我們看一下下面這些代碼:
<script type="text/javascript">
var Person = function () { };
Person.prototype.Say = function () {
alert("Person say");
}
var p = new Person();
p.Say();
</script>
那就讓我們看下為什么p可以訪問Person的Say?
首先var p=new Person()渗饮;可以得出p.proto=Person.prototype但汞。那么當我們調(diào)用p.Say()時,首先p中沒有Say這個屬性抽米,于是特占,他就需要到他的proto中去找,也就是Person.prototype云茸,而我們在上面定義了 Person.prototype.Say=function(){}; 于是是目,就找到了這個方法。
4标捺、讓我們看個更復(fù)雜的原型鏈例子懊纳。
<script type"text/javascript">
var Person = function () { };
Person.prototype.Say = function () {
alert("Person say");
}
Person.prototype.Salary =20000;
var Programmer = function () { };
Programmer.prototype = new Person();
Programmer.prototype.WriteCode = function() {
alert("programmer writes code");
};
Programmer.prototype.Salary = 10000揉抵;
var p = new Programmer();
p.Say();
p.WriteCode();
alert(p.Salary)嗤疯;
</script>
我們來做這樣的推導(dǎo):
var p=new Programmer()可以得出p.proto=Programmer.prototype;
而在上面我們指定了Programmer.prototype=new Person();
我們來這樣拆分冤今,var p1=new Person();Programmer.prototype=p1;
那么:
p1.proto=Person.prototype;
Programmer.prototype.proto=Person.prototype;
根據(jù)上面得到p.proto=Programmer.prototype。
可以得到p.proto.proto=Person.prototype茂缚。
輸出結(jié)果分析:
p.Say()戏罢。由于p沒有Say這個屬性,于是去p.proto也就是Programmer.prototype脚囊,也就是p1中去找由于p1中也沒有Say龟糕,那就去p.proto.proto,也就是
Person.prototype中去找悔耘,于是就找到了alert(“Person say”)的方法讲岁。
其它同理。
三衬以、一幅圖說明它們之間的關(guān)系
Javascript中12個內(nèi)置對象缓艳,其中10個函數(shù)類型,2個對象類型看峻。
上圖有十種構(gòu)造器函數(shù)阶淘,分別為:date Array Number Object Bloolean String Event Error RegExp Function,這些構(gòu)造器函數(shù)都可以通過new來實例化一個對象
注意:
1备籽、所有構(gòu)造器的prototype都是對象(object)類型舶治,只有Function.prototype是函數(shù)(function)類型分井,這是為了保證函數(shù)構(gòu)造器們的__proto__指向的都是函數(shù)车猬。
2、JSON和Math不是構(gòu)造器函數(shù)尺锚,他們是普通的對象珠闰。只有構(gòu)造器函數(shù)才能使用new 關(guān)鍵字實例化一個對象,而JSON和Math已經(jīng)是對象了瘫辩,所以我們可以不用實例化直接使用JSON和Math中的屬性和方法伏嗜。