理解JS建構函式,其原型物件和其實例物件的關係

2021-08-18 07:02:21 字數 3067 閱讀 5491

at first ,please look at this demo:

function fn(),而空{}的constructor就是object原生物件。

//造成fn.prototype.constructor不再指向 fn,而是指向萬物之主object,但是fn1 instanceof fn == true

處理方法:如果constructor 很重要,則

fn.prototype =

var fn1 = new fn();//例項物件

fn.prototype.age = 18;//在instance 之後定義 

console.log(fn1.age);//還是=18

因為找值的時候先找例項本身,再去找原型。而例項與原型的連線只是指標關係,而非副本,所以能及時反應。

但是,如果在例項化後重寫了prototype 那就切斷了例項與新prototype的聯絡,例項中的原型__proto__僅指向fn建構函式的prototype,而不是 直接指向建構函式fn。所以例項還是指向原來的fn.prototype.

解決辦法:在所有例項化前進行fn.prototype = {} 重寫。

section 7 原生物件(原生引用型別)的原型:

array\string\object等

e.g.:  array.prototype.sort

section 8 原型物件的缺點(當在prototype中定義的屬性是引用型別時,如,只要有乙個例項改變了這個屬性,那麼全部例項這的這個屬性都改變了,這不是我們想要的)

因為原型是被多個例項共享的,所以我們不要把例項各自的屬性定義在原型中,而是定義在原建構函式中。

section 9 組合使用建構函式模式和原型模式

function money(value)

var m1 = new money(10);

var m2 = new money(99);

m1.count.push(3);

= [1,2,3]

///最後來看看完美的繼承模式吧:

object-oriented語言都支援兩種繼承方式:1:介面繼承;2:實現繼承。介面繼承只繼承方法簽名,而實現繼承則繼承實際的方法。but js沒有函式簽名,so ecmascript 中無法實現介面繼承。只好乖乖的做實現繼承(繼承實際的方法),主要通原型鏈來實現。

基本思路是利用原型讓乙個引用型別繼承另乙個引用型別的屬性和方法。簡單回顧一下構造了函式、原型和例項的關係:每個建構函式都有會預設有乙個prototype物件,prototype包含乙個指向建構函式的指標,而例項都包含乙個指向原型物件的內部指標[[prototype]]==__proto__,如:

function a(){}

function b(){}

如果 b.prototype = new a();   //這裡b.prototype.constructor = a (在這裡我還是覺得有必要解釋一下,為什麼b.prototype.constructor == a,我們拆開來,new a()是a的例項,a的例項的constructor == a,而b.prototype == a的例項,這樣說應該夠明白了吧^_^ )

var b1= new b();   //這裡b1.__proto__.constructor = a ;b1.__proto__ = a建構函式裡的內容,應該是以物件的形式展示

則b1繼承a\b\object的所有屬性方法,b則繼承了a\object的所有屬性方法,所有a的例項都會繼承了a\object的屬性和方法;

再定義乙個function c(); c.prototype = new b();

則此時c.__proto__(c建構函式的例項) =c+ b + a+ object; 

以上就是原型鏈了。

下面來一條比較perfect inherit method:

組合繼承:

function a(age);

// 以下是原型繼承的優化方法

function inheritprototype(subtype,supertype)

第二種改善後的繼承原型的方法:(不會改變a的原型)

在其它操作之前一定要object.freeze(a.prototype),這樣a物件的原型就不會改變了

var b = new b("bname"); //上面方法繼承了,這裡就是只間接的呼叫a()

brief summary:

prototype只有在new例項的時候才有用。

log = console.log

;functiona(name,age)

a.prototype.asayname =function()

functionb(name,age,car)

functioninheritprototype(subtype,supertype)

}inheritprototype(b.prototype

,a.prototype);

b.prototype.bsaycar =function()

varb =newb("tangcc",18

,"fute");

//new之後,b例項自動產生乙個__proto__繼承了 b.prototype

//brief summary

//構造器只要被例項化後,其實例直接就可以用構造器原型上定義的方法e.g.:b.bsaycar()。最重要就是我們理解的時候,凡用new操作的函式,則這個函式原型上的方法直接就賦給了其實例。

//我猜想其內部實現是這樣的,只要是用new操作過的函式,則這個函式的prototype 會自動的將其內部所有的屬性轉化成json物件

//拿b舉例,new b()後,有一套規則直接把b.prototype裡的屬性轉為json賦給b, 如:b = ,然後就可以順理成章的b.bsaycar() 。是不是很形象呢?我猜想是這樣的。

//否則總是有同學理解不了,為什麼定義時是b.prototype.basaycar ,但呼叫時卻是b.basaycar了。

js關於原型建構函式和原型鏈的理解

js的物件導向方式的函式有很多種方式,其中有兩個比較重要的是兩種方式一是建構函式模式,一是原型模式。1 建構函式模式如 function persion name,age var person1 new person alex 29 person1.sayname alex var person2 ...

js建構函式和原型

建立物件的方式 1,物件字面量 var obj1 2,new object var obj2 new object 3,利用建構函式建立物件 建構函式 利用建構函式 可以建立很多個物件 建構函式,把物件中公共屬性和方法抽出來,放在建構函式裡,通過new建立不同的物件 function star na...

js 建構函式和原型鏈

比較new和object.create 建構函式 new 保留原建構函式屬性 object.create 丟失原建構函式屬性 原型鏈new 原建構函式prototype屬性 object.create 原建構函式 物件 本身 作用物件 new function object.create funct...