Javascript中一切都是對象
在javascript中诈悍,一切都是對象,函數(shù)也是兽埃。除了null和undefined侥钳。
1
對象的構(gòu)建方法有兩種
var o = {name:'jalon'};
var o = new Object(); o.name = 'jalon';
推薦使用第一種。
而有的時候柄错,我們?nèi)绻枰芏囝愃频膶ο笙隙幔覀円惨?一樣一一創(chuàng)建嗎?
2
當(dāng)然不是鄙陡,我們可以使用構(gòu)造函數(shù)冕房,通過new的方法,生成多個對象趁矾。也就是在模擬其他語言的類與實例耙册。
簡單這樣理解:構(gòu)造函數(shù)=類,對象=實例毫捣。
其實在js中详拙,每一個對象(即使是第一種方法創(chuàng)建的)都有一個隱藏的屬性,他的值是構(gòu)造他的那個構(gòu)造函數(shù)蔓同。如果是第一種方式創(chuàng)建的對象饶辙,那么他的構(gòu)造函數(shù)就是Object()這個內(nèi)建函數(shù)對象。這個屬性就是constructor斑粱。它對應(yīng)的值就是那個都早該對象的構(gòu)造函數(shù)弃揽。
那么問題來了?(藍翔,愛過)前面說函數(shù)也是對象矿微,那么構(gòu)造函數(shù)也是對象痕慢,他是不是也有他的構(gòu)造函數(shù)呢,答對了涌矢,他也有掖举,他的構(gòu)造函數(shù)就是Function()這個對象(也是函數(shù)),也可以說這個構(gòu)造函數(shù)娜庇。
那...Function這個對象有沒有構(gòu)造函數(shù)呢...對塔次,有,不過就是他自身,也就是他的constructor就是Function他本身名秀。
Object對象的構(gòu)造函數(shù)也是Function()励负。
3
每一個構(gòu)造函數(shù)都有一個屬性叫做prototype,這個屬性的值是一個對象泰偿,這個對象是所有基于此構(gòu)造函數(shù)創(chuàng)建的對象的基引用(base refrence)熄守。所有的實例都會去找這個對象(模子)制作自己。
每一個對象都有對應(yīng)的基引用耗跛。(也會有對應(yīng)的構(gòu)造函數(shù))
因為基引用也是對象裕照,所以他一定也有基引用。他的基引用肯定也有基引用调塌。對晋南,
這就是原型鏈。
4#
那么羔砾,當(dāng)我們new出2個實例來的時候负间,
new的過程其實就是將構(gòu)造函數(shù)的作用域賦給新對象的過程,即將this指代綁定到新對象身上姜凄,即新對象有了構(gòu)造函數(shù)的屬性政溃,但是基引用還是空的 { }。
不過當(dāng)我們:
o.constructor.prototype.age = 23;或O.prototype.age = 23
輸出的o新增了age屬性态秧。這是因為改變了基引用 {age : 23}董虱。
這個過程是這樣的,當(dāng)訪問一個對象的時候申鱼,會先查找他的自身的屬性愤诱,如果找到,則立刻返回捐友,如果找不到淫半,就去他的基引用找(再找不到,就找基引用的基引用...)匣砖。也就是之前構(gòu)造函數(shù)的屬性已經(jīng)在實例上了科吭,可以找到昏滴,接下來找基引用,就新增age屬性了对人。并且新增到了實例本身上影涉,不是還掛在基引用上。
所以你會看到规伐,如果o.constructor.prototype = { } 一個新的空對象(被清空了)的時候。之前構(gòu)建的實例是不變的(因為本身已經(jīng)富有所有屬性了)匣缘,之后再構(gòu)建的實例是只有構(gòu)造函數(shù)的屬性了猖闪,因為基引用是空的,沒什么可添加的肌厨。如果o.constructor.prototype = { 非空對象}培慌,那么就會是構(gòu)造函數(shù)屬性+基引用屬性了。
使用給基引用添加屬性達到同步所有實例的屬性的目的柑爸。
使用原型繼承吵护,是為了節(jié)約空間,沒有必要在實例化的時候(會把構(gòu)造函數(shù)的屬性添加過來)把所有東西都加過來表鳍,只有在用的時候馅而,再去原型鏈上找到添加過來。
貼一個參考鏈接 http://www.cnblogs.com/FlyingCat/archive/2009/09/21/1570656.html