什么是構造函數(shù)
構造函數(shù)在外型上與普通的function并無差別观游,人們?yōu)榱藚^(qū)分函數(shù)和構造函數(shù)規(guī)定構造函數(shù)的首字母大寫。
function Foo (name) {
this.name = name
}
function foo (name) {
this.name = name
}
我們新建兩個函數(shù)為了以示區(qū)別Foo為構造函數(shù)鹃共,foo為普通函數(shù)
我可以看見兩者并沒有差別關鍵是使用了
new
操作符怖糊,new
操作符到底干了些什么呢?
- 創(chuàng)建一個類的實例:創(chuàng)建一個空對象
obj
纱扭,然后把這個空對象的__proto__
設置為Foo.prototype
(即構造函數(shù)的prototype
); - 初始化實例:構造函數(shù)
Foo
被傳入?yún)?shù)并調用棍矛,關鍵字this被設定指向該實例obj漠魏; - 返回實例obj舔株。
什么是proto和prototype
我們打印一下__proto
和prototype
我們發(fā)現(xiàn)
__proto
和prototype
中都有一個constructor
屬性并且都指向構造函數(shù)Foo
枣申,實例的__proto__
會指向自己的構造函數(shù)屡久,構造函數(shù)的prototype
指向構造函數(shù)自己
構造函數(shù)中的this指向
- 不使用
new
操作符this
指向
如果不使用new操作符的話this
是指向window
的 - 使用
new
操作符
this
是指向實例本身的
構造函數(shù)的應用
function f (name, age) {
console.log(name, age)
}
如果我們需要許多類似這樣的函數(shù)我們需要一個一個去創(chuàng)建,但是如果使用構造函數(shù)的話, 使用new
操作符就可以搞定慨绳,而不需要一個一個去創(chuàng)建
function F (name, age) {
this.name = name
this.age = age
this.speak = function () {
console.log(`我叫${this.name},今年${this.age}歲了掉冶,很高興認識大家`)
}
}
var f1 = new F('張三', '18')
var f2 = new F('李四', '20')
上面我們new兩個實例f1,f2他們都有一個方法speak
,這個方法是一樣的但是我new
一次就會新建一個同樣的方法脐雪,有沒有什么方法把這個相同的函數(shù)提取出來
function F (name, age) {
this.name = name
this.age = age
}
F.prototype.speak = function () {
console.log(`我叫${this.name},今年${this.age}歲了厌小,很高興認識大家`)
}
var f1 = new F('張三', '18')
var f2 = new F('李四', '20')
我們可以把共有的方法放到構造函數(shù)的prototype
上這樣無論有多少個實例都只會有一個speak
方法,但并不是什么東西的都可以提取到prototype
上战秋,比如一些引用值璧亚,如果其中一個實例改變了prototype
上的這個值會導致其他實例訪問到的值都改變,這個情況我們還是需要把他放到構造函數(shù)里面去脂信,但有些時候一些是需要共享的癣蟋,比如訂閱發(fā)布模式中儲存方法的數(shù)組就需要全局共享透硝,這個時候就需要提取到prototype
上。
構造函數(shù)結合原型鏈非常靈活疯搅,可以解決很多問題濒生。