js基础——js原型、原型对象、原型链、继承

276 阅读2分钟

一、js原型链

1.继承的实现并不是靠prototype,而是靠__proto__
2.原型链的作用,在于读取对象的某个属性时,js引擎会优先查找对象本身的属性,如果没有,会去该对象的构造函数的原型对象(prototype)上面找,一直找到最顶层的原型对象,Object.prototype , 如果还没有则返回undefine
3.这个过程中,维持上下层关系靠的是__proto__

(1) __ proto__ (原型属性)

任何对象都有__proto__ 属性,__proto__指向创建他的构造函数的原型对象(实例指向原型对象的指针).

function Student () {
  this.role = '学生'
}
var stu1 = new Student()
console.log(stu1.__proto__ === Student.prototype) // true

var a = {
  a:1,
  b:2
}
console.log(a.__proto__ === Object.prototype) // true

(2)prototype (原型对象)

它是函数所独有的,它是从一个函数指向一个对象。它的含义是函数的原型对象,也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象。

function Student () {
  this.role = '学生'
}
var stu1 = new Student()
console.log(stu1.__proto__ === Student.prototype) // true

constructor

constructor属性也是对象才拥有的,它是指向该对象的构造函数

console.log(stu1.constructor === Student) //true
console.log(Student.constructor === Function) // true

instanceof

通常来讲,使用 instanceof 就是判断一个实例是否属于某种类型。 另外,更重的一点是 instanceof 可以在继承关系中用来判断一个实例是否属于它的父类型。

 
// 判断 foo 是否是 Foo 类的实例 , 并且是否是其父类型的实例function Aoo(){} 
function Foo(){} 
Foo.prototype = new Aoo();//JavaScript 原型继承 
var foo = new Foo(); 
console.log(foo instanceof Foo)//true 
console.log(foo instanceof Aoo)//true 

二、js继承

(1)es6 class 继承

class A {
    constructor (name) {
        this.name = name
        console.log(')))))))))))')
    }
    // 静态方法
    static a () {
        return this.name
    }
    b () {
        return this.name
    }

}

// 使用extends 关键字进行继承
class B extends A{
    constructor(name){
        super(name)
        // console.log(this)
    }
}

(2)es5继承

原型链继承

缺点: 1、所有实例共享父类方法和属性2、不能向父类传值

function Parent (name) {
    this.name = name
}

function Child () {
    
}
Child.prototype = new Parent()

var child_1 = new Child()
构造函数继承

缺点:不能继承父类原型链上的属性和方法

function Parent (name) {
    this.name = name
}

function Child (name) {
    Parent.call(this, name)
}

var child_1 = new Child()
组合继承

缺点: 父类被执行两次

function Parent (name) {
    this.name = name
}

function Child (name) {
    Parent.call(this, name)
}

Child.prototype = new Parent()
var child_1 = new Child()
寄生组合继承
function Parent (name) {
    this.name = name
}

function Child (name) {
    Parent.call(this, name)
}
// 最初写法
Child.prototype = new Parent()

// 进阶写法 防止执行两次,带来新的问题,父类、子类共享原型对象
Child.prototype = Parent.prototype

// 解决办法,做一次copy
Child.prototype = Object.create(Parent.prototype)