概述
本篇主要講述構(gòu)造函數(shù)和繼承
構(gòu)造函數(shù)
編程
編程主要分為函數(shù)式編程和面向?qū)ο缶幊?/strong>
函數(shù)式編程 ==> 推崇函數(shù)
面向?qū)ο缶幊?==> 推崇類,沒(méi)有函數(shù)概念
JavaScript
JavaScript 中的類可以理解為構(gòu)造函數(shù)
類 ==> 如果一個(gè)東西返回一個(gè)
Object就叫做類構(gòu)造函數(shù) ==> 如果一個(gè)函數(shù)返回一個(gè)
Object就叫做構(gòu)造函數(shù)
因?yàn)?JavaScript 中沒(méi)有類的概念,所以 JavaScript 中的構(gòu)造函數(shù)即可以看做是類,JavaScript 中 new 是構(gòu)造函數(shù)的典范
繼承
繼承可以實(shí)現(xiàn)代碼復(fù)用,JavaScript 中使用原型(__proto__,原型鏈)實(shí)現(xiàn)繼承,實(shí)例化對(duì)象的 __proto__ 指向構(gòu)造函數(shù)的 prototype
對(duì)象.__proto__ === 函數(shù).prototype
分類
對(duì)象之間的繼承 ==>
__proto__函數(shù)與對(duì)象之間的繼承通過(guò)
this參數(shù)(關(guān)鍵字)傳導(dǎo)關(guān)鍵字
new形成構(gòu)造函數(shù),從而使用函數(shù)創(chuàng)建對(duì)象,使得新創(chuàng)建的對(duì)象可以繼承構(gòu)造函數(shù)上的屬性
模擬繼承的具體方式
- 共有屬性 ==>
prototype屬性 - 私有屬性 ==> 構(gòu)造函數(shù)上的屬性
==> 繼承 === 共有屬性 + 私有屬性 === prototype 屬性 + 構(gòu)造函數(shù)上的屬性
function Person( name ){
this.name = name
}
Person.prototype.think = true
Person.prototype.foot = 'two'
Person.prototype.say = function(){
console.log( 'I can say' )
}
Person.prototype.walk = function(){
console.log( 'I can walk' )
}
new 模擬繼承
let xiaoming = new Person( 'xiaoming' )
xiaoming.a = 1
xiaoming.xxx = function(){
console.log( 'xxx' )
}
對(duì)象 xiaoming 具有 Person 的私有屬性 + 共有屬性,還有自身的屬性

call + Object.create() + new 模擬繼承
new 模擬的繼承僅僅有一層,如果我們要模擬多層,即 xiaoming 繼承 Student,Student 繼承 Person

其中
Student 繼承 Person 是構(gòu)造函數(shù)與構(gòu)造函數(shù)的繼承(類與類的繼承)
function Student( name, school ){
Person.call( this, name ) // 繼承 Person 屬性 === Person.bind( this ).( name )
this.school = school
}
Student.prototype = Object.create( Person.prototype ) // 繼承 Person 方法
Student.prototype.learn = function(){
console.log( `${ this.name } learn in ${ this.school }` )
}
let xiaoming = new Student( 'xiaoming', 'qinghua' )
xiaoming.a = 1
xiaoming.xxx = function(){
console.log( 'xxx' )
}
對(duì)象 xiaoming 既繼承了 Student 的共有屬性 + 私有屬性,又繼承了 Person 的共有屬性 + 私有屬性,還有自己的屬性

模擬構(gòu)造函數(shù)與構(gòu)造函數(shù)的繼承(類與類的繼承)
上面中模擬構(gòu)造函數(shù)與構(gòu)造函數(shù)的繼承(類與類的繼承)使用了 Object.create()。模擬構(gòu)造函數(shù)與構(gòu)造函數(shù)的繼承(類與類的繼承)即是實(shí)現(xiàn)
Student.prototype.__proto__ = Person.prototype
-
方案1:前提 ==>
Person為空(沒(méi)有私有屬性),若Person不為空,則Student上會(huì)多出Person上的私有屬性Student.prototype = new Person() ==> Student.prototype === this ==> Student.prototype.__proto__ === Person.prototype -
方案2:ES3 ==> not care Person 上的私有屬性
function emptyPerson() {} emptyPerson.prototype = Person.prototype Student.prototype = new emptyPerson() -
方案3:ES5 API
Student.prototype = Object.create( Proson.prototype ) -
方案4:ES6 ==> class + extends ==> prototype(共有屬性)必須是函數(shù)
-
class用法:class Example{ constructor(options){ this.name = options.name } say() { } walk() { } } == 等價(jià)于 == function Example(options) { this.name = options.name } Example.prototype.say = function() { } Example.prototype.walk = function() { } -
extends 用法:
class Student extends Person === Student.prototype = Object.create(Person.prototype) super(options) === Example.call(this,options) -
具體實(shí)現(xiàn)
class Student extends Person{ constructor(options){ super(options) // 繼承私有屬性 } } class + extends不倫不類
Student是class(類) ==> JavaScript 中沒(méi)有類這個(gè)數(shù)據(jù)類型
Student是函數(shù) ==> Student 并不能call
-
相關(guān)知識(shí)點(diǎn)
Object.create() 的實(shí)現(xiàn)
function inherit( base ){
function fn(){}
fn.prototype = base
return new fn()
}