js的原型跟原型链

113 阅读1分钟

原型

  • js上所有的对象都是通过new函数创建的,包括字面量定义的对象也是new的语法糖
  • 所有的函数都是通过new Function创建的,包括Array object等
  • 所有的函数都是对象

prototype

每个函数都存在的属性,指向它的原型

constructor

原型对象上存在一个指针constructor指向构造函数

proto

实例上存在的属性,指向其构造函数的原型

一图说明关系

image.png

举个例子

    function Person() {}

    function Animal() {}

    Person.prototype = new Animal();

    Person.prototype.name = "alan";

    var person = new Person();
    person.name = "tom";

    console.log(person.name); // tom
    delete person.name;
    console.log(person.name); // alan

    console.log(person.__proto__); // Animal
    console.log(Person.prototype.__proto__ === Object.prototype); // true
    console.log(Object.prototype.__proto__ === null); // true
    console.log(Person.prototype);

原型链

当访问一个对象的属性或方法时,如果找不到,就会查找与这个对象关联的原型中的属性,如果还找不到,就再去找原型的原型,一直找到最顶层(Object)为止,而由原型组成的这个链条就叫做原型链。

继承

原型继承

   function father() {
      this.a = 1;
    }
    father.prototype.say = () => {
      console.log("hhh");
    };
    function child() {}
    child.super = new father();
    console.log(child.say);
    

缺点:

如果父方法里的某个属性是引用值,则会造成污染。

构造继承

    function father() {
      this.a = 1;
    }
    father.prototype.say = () => {
      console.log("hhh");
    };
    function child() {
      father.call(this);
      this.b = 2;
    }
    const test = new child();
    console.log(test.say); //undefined

缺点:

子函数无法使用父函数原型上的方法属性 父构造函数中方法需要在每个实例上创建一遍

组合继承

    function father() {
      this.a = 1;
    }
    father.prototype.say = () => {
      console.log("hhh");
    };
    function child() {
      father.call(this);
      this.b = 2;
    }
    child.prototype = new father();
    const test = new child();
    test.say(); //hhh
    

缺点: father函数始终会被调用两次

组合寄生继承


     function father() {
      this.a = 1;
    }
    father.prototype.say = () => {
      console.log("hhh");
    };
    function child() {
      father.call(this);
      this.b = 2;
    }
    child.prototype = Object.create(father.prototype);
    child.prototype.constructor = child;
    const test = new child();
    test.say(); //hhh