1.如何構造?
先復習一下es5常用的構建類的方法:
-
首先es5的寫法使用原型進行物件的方法的,為什么不在建構式里添加方法呢?
因為實體化物件的時候,會重復的建立好多相同的方法,浪費資源,所以需要把物件的方法掛載到prtotype里,
-
關于new和this的系結問題,可以大概簡化為:
- 首先通過new生成一個新的物件
- 然后讓這個物件系結到建構式的this中去
- 然后系結這個構造物件的原型物件上
- 最后把這個物件回傳給前面定義的物件
那么接下來看例子吧:
fuction Animal(name,age){
this.name = name
this.age = age
// 這樣是浪費資源的
// this.eat = function(){
// console.log("今天我吃飯了")
// }
}
// 正確做法
Animal.prototype.eat=function(){
console.log("今天我吃飯了")
}
然后上ES6的class,class很明顯就簡化了這個操作
cosnt dog = new Animal("wangcai",2) // 會報錯,ES6為了修改陋習,和let和const一樣,class不會提升.
class Animal{
constroctor(name,age){
this.name = name
this.age = age
}
eat(){
console.log("今天我吃飯了")
}
}
cosnt dog = new Animal("wangcai",2) //正確位置
另外class還添加了靜態方法,set,get等操作,
class Animal{
constroctor(name,age){
this.name = name
this.age = age
}
eat(){
console.log("今天我吃飯了")
}
set name(value){
this.tempname ="老鐵"+value
}
get name(){
return this.tempname
}
static introuduce(){
console.log("我現在是一個動物類")
}
}
//set() get()
const dog = new Animal("giao",2)
dog.name="agiao"
console.log(dog.name) // 老鐵agiao
// 靜態方法
Animal.introuduce() // 我現在是一個動物類
再說繼承之前補充個小知識點,class的方法名可以通過計算屬性的操作來命名
let tempname = "giao"
class Animal{
constroctor(name,age){
this.name = name
this.age = age
}
[tempname](){
console.log("一給我咧giao")
}
}
const xiaoagiao = new Animal("giaoge",30)
xiaoagiao.giao() // 一給我咧giao
2.繼承
回到繼承這個問題,es5是怎么繼承的呢?
function Animal( name ){
this.name = name
}
Animal.prototype.break(){
console.log("叫!")
}
function Dog( name, age ){
Animal.call(this,name)
this.age = age
}
Dog.prototype = new Animal()
Dog.prototype.constructor = Dog
那么這個叫組合繼承,怎么個組合法呢?
-
屬性方面的繼承是借用繼承,可以看到
Animal.call(this,name)就是相當于把Animal這個函式在Dog的建構式里呼叫了一遍而已,雖然屬性他們沒有原型鏈的鏈式聯通,但是代碼拿過來給Dog都跑了一遍,所以自然就繼承了Animal的name屬性,Animal.call(this,name) -
方法的繼承是原型式繼承,眾所周知,一個函式會在創建的時候生成一個原型物件,這個函式的的一個
protoype屬性指向他的原型物件,原型物件的constructor屬性指向這個函式,如果用new來新建這個函式的實體,這個實體會有一個__proto__的屬性指向函式的原型物件,所以借用函式實體會指向函式原型物件這個特性,我們將被繼承的函式實體化,然后將這個實體化的物件賦給繼承的建構式的prototype屬性,這樣就構成了一種鏈式結構,但同被繼承的函式實體化是不具備constructor這個屬性的,我們需要將他的constructor指向繼承的建構式,Dog.prototype = new Animal() Dog.prototype.constructor = Dog
所以按照這個套路,我們用es5的語法,將dog函式繼承了Animal函式的name和break方法.
那么ES6是怎么做的呢?
class Animal{
constructor( name ){
this.name = name
}
break(){
console.log("叫!")
}
}
class Dog extends Animal {
constructor( name, age ){
super(name)
this.age=age
}
}
現在只需要在宣告Dog類的時候加一個extends Animal,然后再在constructor建構式里加一個super就好了,
這個super(name)就相當于Animal.call(this,name)了,然后關于方法的問題,自然就不用擔心了,extends自動就處理好了,就不用再去用prototype亂指了.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/144624.html
標籤:JavaScript
上一篇:JS復雜資料拆分重組
