Skip to content

简要分析ES5/6原型链继承 #73

Open
@onvno

Description

@onvno

Javascript 原型链继承

图片无法在issue中提交,原文在这里:onvno博客

简单实现继承

var a = {
      x: 10,
    calculate: function (z) {
        return this.x + this.y + z
      }
};

var b = {
  y: 20,
  __proto__: a
};

var c = {
  y: 30,
  __proto__: a
};

// call the inherited method
b.calculate(30); // 60
c.calculate(40); // 80

他们之间的继承关系:

1430231-2383de904a0ef8df

以上图,观察a可得到:

如果没有明确为一个对象指定原型,那么它将会使用proto的默认值-Object.prototype。Object.prototype对象自身也有一个proto属性,这是原型链的终点并且值为null。

以上代码,ES5实现方法:

var b = Object.create(a, {y: {value: 20}});
var c = Object.create(a, {y: {value: 30}});

如浏览器不支持,可用以下Polyfill

if(!Object.create){
    Object.create = function(obj){
        function F(){};
        F.prototype = obj;
        return new F();
    }
}

构造函数继承

// a constructor function
function Foo(y) {
  // which may create objects
  // by specified pattern: they have after
  // creation own "y" property
  this.y = y;
}

// also "Foo.prototype" stores reference
// to the prototype of newly created objects,
// so we may use it to define shared/inherited
// properties or methods, so the same as in
// previous example we have:

// inherited property "x"
Foo.prototype.x = 10;

// and inherited method "calculate"
Foo.prototype.calculate = function (z) {
  return this.x + this.y + z;
};

// now create our "b" and "c"
// objects using "pattern" Foo
var b = new Foo(20);
var c = new Foo(30);

// call the inherited method
b.calculate(30); // 60
c.calculate(40); // 80

// let's show that we reference
// properties we expect

console.log(

  b.__proto__ === Foo.prototype, // true
  c.__proto__ === Foo.prototype, // true

  // also "Foo.prototype" automatically creates
  // a special property "constructor", which is a
  // reference to the constructor function itself;
  // instances "b" and "c" may found it via
  // delegation and use to check their constructor

  b.constructor === Foo, // true
  c.constructor === Foo, // true
  Foo.prototype.constructor === Foo // true

  b.calculate === b.__proto__.calculate, // true
  b.__proto__.calculate === Foo.prototype.calculate // true

);

1430231-f99c16e43ea4bff1

注意:可得出constructor都指向构造函数本身,创建的实例b,c都指向构造函数的'prototype对象'

ES6的继承-类-extends

class Person {
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    sayHello(){
        console.log(`My name is ${this.name},i'm ${this.age} years old`)
    }
    toString(){
        ...
    }
}

class Student extends Person{
    constructor(name,age,cla){
        super(name,age); // 调用父类的constructor(name, age)
        this.class = cla;
    }
    study(){
        console.log(`I'm study in class ${this.class}`)
    }
    toString() {
        return this.class + ' ' + super.toString(); // 调用父类的toString()
    }
}

constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。

ES6入门

注意,子类中必须在constructor先使用super()来调用父类。

原因是子类通过super获取父类this实现继承,否则后边的this.class因获取不到this会报错。

super这个关键字,有两种用法,含义不同。

(1)作为函数调用时(即super(...args)),super代表父类的构造函数。

(2)作为对象调用时(即super.propsuper.method()),super代表父类。注意,此时super即可以引用父类实例的属性和方法,也可以引用父类的静态方法。

ES6可实现原生构造函数的继承。

参考链接

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions