1.4. js原型链

233 阅读2分钟

1. js继承 vs java继承

js 继承

  • 在构造函数里面的属性和方法是不通过实例共享的;
  • 在构造函数的原型对象(prototype)里面的属性和方法,是所有的实例所共享的
    java 继承
  • 通过 extends 关键字可以申明一个类是从另外一个类继承而来
  • 使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口

JVM是采用了一种叫做“内存叠加”的方式,来实现继承关系的。 当我们产生一个子类对象的时候,JVM是分两步走: 1、首先调用父类的构造方法,产生一个父类对象部分; 2、然后再调用子类构造,在上一步的父类对象部分之下叠加上子类特有部分的内容,从而形成一个完整的子类对象。

2. js原型链

在JavaScript中,每个函数 都有一个prototype属性,当一个函数被用作构造函数来创建实例时,这个函数的prototype属性值会被作为原型赋值给所有对象实例(也就是设置 实例的__proto__属性

function Person() {
  this.name = '';
}

Person.prototype = {
  setName: function(v){
    this.name = v;
  }
};

var person = new Person();

image.png

3.new 干了什么

 var p =  new Person('张三',20);
    1. var p={}; 初始化一个对象p。
    1. p.proto=Person.prototype,将对象p的 __proto__ 属性设置为 Person.prototype;
    1. Person.call(p,”张三”,20); Person函数对象的this指针替换成p,然后再调 Person构造函数来初始化p。
    1. 返回p

4. 手写instanceof

function new_instance_of(leftVaule, rightVaule) { 
    let rightProto = rightVaule.prototype; // 取右表达式的 prototype 值
    leftVaule = leftVaule.__proto__; // 取左表达式的__proto__值
    while (true) {
    	if (leftVaule === null) {
            return false;	
        }
        if (leftVaule === rightProto) {
            return true;	
        } 
        leftVaule = leftVaule.__proto__ 
    }
}

5.js 6种继承