7、JS如何實(shí)現(xiàn)類?
兩種方法:
ES6之前沒(méi)有class.
那為什么要有類?
第一批前端好多都是java轉(zhuǎn)的,他們按照java的寫法寫JS。
java程序員不允許沒(méi)有類。
方法一:使用原型
對(duì)象本身的屬性寫在構(gòu)造函數(shù)里面,把共有屬性寫在原型上面。
function Dog(name){
this.name = name
this.legsNumber = 4
}
Dog.prototype.kind = '狗'
Dog.prototype.say = function(){
console.log(`汪汪汪~(yú) 我是${this.name},我有${this.legsNumber}條腿。`)
}
Dog.prototype.run = function(){
console.log(`${this.legsNumber}條腿跑起來(lái)。`)
}
const d1 = new Dog('嘯天') // Dog 函數(shù)就是一個(gè)類
d1.say()
原型的錯(cuò)誤寫法
Dog.prototype = {
say:...
kind:....
}
不對(duì) 因?yàn)镴S本身內(nèi)置一個(gè) Dog.prototype.constructor = Dog,在某些時(shí)候會(huì)影響代碼邏輯。
任何一個(gè)函數(shù)的prototype.constructor,都等于這個(gè)函數(shù)本身,除了箭頭函數(shù)。
這樣你聲明d1 你就不知道它是誰(shuí)構(gòu)造出來(lái)的。
方法二:使用class
class Dog {
kind = '狗' // 等價(jià)于在 constructor 里寫 this.kind = '狗' 也是自身屬性
constructor(name) {
this.name = name
this.legsNumber = 4
// 思考:kind 放在哪,放在哪都無(wú)法實(shí)現(xiàn)原型上面的一樣的效果(寫在原型上)
}
say(){
console.log(`汪汪汪~(yú) 我是${this.name},我有${this.legsNumber}條腿。`)
}
run(){
console.log(`${this.legsNumber}條腿跑起來(lái)。`)
}
}
const d1 = new Dog('嘯天')
d1.say()
constructor里面放自身屬性,外面放共有屬性。TS中使用class.
7、JS如何實(shí)現(xiàn)繼承?
繼承就是類和類之間的關(guān)系一個(gè)類繼承了另一個(gè)類
方法一:使用原型鏈
兩個(gè)關(guān)鍵點(diǎn),
自身屬性要繼承
Animal.call,并傳this和參數(shù)
共有屬性要繼承。
Dog.prototype.proto = Animal.prototype /
如果被禁用就使用下面三行代替
function Animal(legsNumber){
this.legsNumber = legsNumber
}
Animal.prototype.kind = '動(dòng)物'
function Dog(name){
this.name = name
Animal.call(this, 4) // 關(guān)鍵代碼1,繼承構(gòu)造屬性,調(diào)用構(gòu)造函數(shù)。相當(dāng)于 this.lengsNumber = 4
}
Dog.prototype.__proto__ = Animal.prototype // 關(guān)鍵代碼2,就是組建一個(gè)原型鏈但這句代碼被禁用了,怎么辦
Dog.prototype.kind = '狗'
Dog.prototype.say = function(){
console.log(`汪汪汪~(yú) 我是${this.name},我有${this.legsNumber}條腿。`)
}
const d1 = new Dog('嘯天') // Dog 函數(shù)就是一個(gè)類
console.dir(d1)
關(guān)鍵點(diǎn)二被禁用解決方法:
Dog.prototype = new Animal()
new做了五件事
1、創(chuàng)建臨時(shí)對(duì)象
2、this = 臨時(shí)對(duì)象
3、this.proto = 構(gòu)造函數(shù)的prototype //我么主要用這一步去改造他的原型
4、執(zhí)行構(gòu)造函數(shù) //由于空了所以第四步不生效 就不會(huì)給他加腿
5、return this
由于Animal構(gòu)造函數(shù) 構(gòu)造出來(lái)的實(shí)例擁有Animal的所有屬性和方法。
但是,我上面的legsNumber已經(jīng)實(shí)現(xiàn)繼承 了 我不需要
所以新建一個(gè)空的函數(shù),讓這個(gè)函數(shù)的prototype = Animal.prptotype
然后使用f來(lái)new
如果面試官問(wèn)被 ban 的代碼如何替換,就說(shuō)下面三句:
var f = function(){ }
f.prototype = Animal.prototype
Dog.prototype = new f()
方法二 class
兩部
1、extends 共有屬性會(huì)自動(dòng)上去
2、super (構(gòu)造函數(shù)中使用super,會(huì)自動(dòng)執(zhí)行Animal constructor中的代碼)
super放在第一行
class Animal{
constructor(legsNumber){
this.legsNumber = legsNumber
}
run(){}
}
class Dog extends Animal{
constructor(name) {
super(4)
this.name = name
}
say(){
console.log(`汪汪汪~(yú) 我是${this.name},我有${this.legsNumber}條腿。`)
}
}