原型 原型鏈 new做了什麼 繼承

2021-10-09 13:25:48 字數 3191 閱讀 8117

比我們通過乙個建構函式new了乙個新物件,建構函式的原型prototype指向乙個物件,所有通過該建構函式new的新物件可以共享它所包含的屬性和方法。

建構函式的原型prototype是乙個物件,那麼它也可以有自己的建構函式原型prototype,通過這樣,形成乙個原型鏈。原型鏈最終都可以上溯到object.prototype。object.prototype的__proto__是null。null沒有任何屬性和方法,也沒有自己的原型。因此,原型鏈的盡頭就是null。

來看乙個例子:

function test() {}

var test = new test();

test.__proto__===test.prototype

test.prototype.__proto__===object.protype

object.protype.__proto__===null

test.__proto__.__proto__.__proto__ === null

test.__proto__===function.prototype

獲取物件原型api: object.getprototypeof(a) 即a.proto(tip: 方法在object上而不是object.prototype上)

為了更清晰地理解,看以下練習:

var obj= {}

obj.__proto__ === object.prototype // 為 true

var fn = function(){}

fn.__proto__ === function.prototype // 為 true

fn.__proto__.__proto__ === object.prototype // 為 true

var array =

array.__proto__ === array.prototype // 為 true

array.__proto__.__proto__ === object.prototype // 為 true

array.__proto__ === function.prototype // 為 true, array的本質為乙個建構函式

實際上,看a.__proto__是什麼,就看a的本質是什麼:

1.new出來的物件,則指向其建構函式的prototype;

2.建構函式,則function.prototype

new的過程:

初始化乙個新物件

該物件的__proto__屬性指向建構函式的原型prototype

將建構函式的this指向新物件,並執行函式

將新物件返回

[如果建構函式有返回乙個物件(null除外),則將建構函式內的物件返回]

手寫new:

function mynew(func, ...params) ;

obj.__proto__ = func.prototype

if(temp && typeof temp === 'object') else

}

在這裡插播乙個經常面試的知識點:

既然知道這三個方法是用來改變this指向,那麼可以利用this在方法中誰呼叫指向誰的特性,將函式繫結到物件上,執行後再刪除

context.fn = this;

context.fn(...params)

delete context.fn

}function.prototype.mycall = function (context, ...params)

function.prototype.mybind = function (context, params)

}function person(name, age)

let obj = {}

let obj1 = {}

let obj2 = {}

person.mycall(obj1, 'lf', 18)

person.mybind(obj2, ['lf', 18])()

既然通過原型鏈例項能訪問到上層的一些方法和屬性,那麼,自然而然繼承可以由他來實現。

最容易想到的是,讓建構函式的原型指向另乙個你想要繼承的建構函式的例項,如下:

// 原型鏈繼承

// 缺點1:任何乙個例項改變原型的屬性,所有例項的原型屬性都會變,因為指向的是同乙個

// 缺點2:沒有辦法在不影響所有物件例項的情況下,給超型別的建構函式傳遞引數

function father(firstname)

function son(lastname)

son.prototype = new father('lee')

const a = new son('mei')

const b = new son('lei')

a.ver[0] = '3.0'

console.log(a)

console.log(b)

通過上面的流程也可以很好地去理解es6中的extends。

class father 

update(firstname)

}class son extends father

update(firstname, lastname)

}// 通過觀察xiao的結構可以看出,原理大概是終極版

let xiao = new son('lee', 'mei')

看看下面的兩個例子:

function f1()

}f1.prototype.f2=function()

class s1 extends f1

k2()

}new s1().f1();

new s1().k1();

new s1().k2() ;

function f1()

}class s1 extends f1

}new s1().f1();

new s1().k1();

這些輸出你做對了嗎?

tips:當你呼叫super()時,解析為呼叫父類的constructor。當你呼叫super. ***(),解析為呼叫父類的原型物件上的方法。

原型 原型鏈 繼承

原型 是function物件的乙個屬性,它定義了建構函式 製造出的物件 的公共祖先。通過該建構函式產生的物件,可以繼承該原型的屬性和方法。原型也是物件 這定義有點模糊,用 解釋一下 我們在控制台中列印出了這個,首先son物件的建構函式是foo,但是我們的foo中什麼屬性都沒有,怎麼會出現乙個 pro...

原型 原型鏈 繼承

在 js 中,一切皆物件!下面就讓我們從建立物件開始,逐步學習js中的核心知識 原型,原型鏈,繼承等 1.字面量方式建立物件 var obj var obj1 2.使用 new object 的方式建立物件 var obj2 new object obj2.name 張三 obj2.age 13 o...

原型 原型鏈和繼承

看一段 就明白了function person nick,age person.prototype.sayname function var p1 newperson byron 20 var p2 newperson casper 25 p1.sayname byron p2.sayname ca...