js继承

191 阅读2分钟

原型继承

事实上js继承很特殊,没有子类父类的继承模式,而是js独有的原型链来继承,

比如我们创建一个一个数组

arr = [1,2,3,4,5]
console.log(arr)  // [1,2,3,4]
arr1 = arr.toString()
console.log(arr1) // "1,2,3,4"

arr的属性只有.lenght。却可以用.toString(),

因为arr是通过Array函数创建的一个对象,Array有toString的属性,通过原型链的继承,当你使用toString的命令时,它发现自己身上没有这功能,怎么办?通过_ptoto——去构造它的函数身上找,如果找不到,就去Array构造函数的_ptoto_身上找,直到一个的原型为null停止。

也可以通过下面例子来了解:

//构建一个未知名的函数,拥有两个属性name和age

function People(name,age){
    this.name = name
    this.age = age
}

//构建一个实例

let people1 = new People('wang',18)
console.log(people1)  // 打印出{age: 18,name: "wang"}

使用new操作符可以构建一个对象实例 可以看到name,age是自身属性

//在People的原型上添加属性

People.prototype.language = 'chinses'
People.prototype.speak = 'English'

//打印出language

console.log(people.language) //打印出了chinse

language和speak是自身属性吗?不是,是他原型上的属性,只是我们要打印出language和speak的时候,他在自身没有找到,去原型找这个属性,直到找到根目录,根目录的原型是null,停止搜索,返回一个undefined.

//这个原型链就是 {name:wang,age:18} --->{language:chinse,speak:English}--->Object.prototype--->null

class继承

class继承是ES6加入的一个新的继承方式,可以说是语法糖。 语法:

class People{   // 这里还是用people举例
   constructor(){
   }
}

// 看起来和我们构架匿名函数没用new操作符创建一个实例对象类似,但是写法更加的简洁, //值得注意的是,函数申明自动提升,而class却不可以,所以是用的时候,必须先声明再使用

let peopel1 = new Peopel()

class People{}

// 报错,返回一个ReferenceError

写在原型上

还是用原型继承的例子,方便对比

class People {
    constructor(name,age){
        this.name = name
        this.age = age
    }
}

//构架一个实例

let people1 = new People('wang',18)
console.log(people1)  // 打印出了{age: 18,name: "wang"}

//基本相同,在原型上写属性就显得简单许多了

class People{
constructor(name,age){
        this.name = name
        this.age = age
    }
    get language(){
        return this.name + " speak Chinses" }
    get speak(){
        return this.name + " English"}
}

// 打印出language

let people2 = new People('wang',18)
console.log(people2.langeuage)  // 打印出了wang speak Chinses

// 在一个block里就可完成写在自身属性和原型上的属性,简单便捷。

//自身属性用constructor,原型上就用get。

class Parent{
    constructor(name1){
        this.name1 = name1
    }
    pMethod(){
        console.log(this.name1)
    }
}
class Child extends Parent{
    constructor(name2, name1){
        super(name1) //
        this.name2 = name2
    }
    cMethod(){
        console.log(this.name2)
    }
}

super用法

关键字用于访问和调用一个对象的父对象上的函数。

// 原型链也是 // {name:wang,age:18} --->{language:chinse,speak:English}--->Object.prototype--->null