JavaScript面向对象之原型链和继承原理

HTML/CSS/JS 阅读: 193

刚接触JavaScript面向对象的同学,对于原型链和继承一定一头雾水。我接触js也有不少时间了,但这些问题到今天才弄清楚,不会的同学随我一起来学习吧。

实例化对象

我们知道js中没有“类”,只有对象。没有类那么怎样创建一个对象呢?有两种方法,一种直接通过{}创建,一种是通过构造函数创建。

通过{}创建对象

使用{}创建一个对象十分直观,就像这样:

var zhangsan = {
    name: 'zhangsan',
    hello: function() {
        console.log(`hi!I am ${this.name}`);
    },
};
zhangsan.age = 20;
zhangsan.hello();

{}中使用键值对方式直接书写属性和方法,也可以创建后再动态添加属性和方法。

通过构造函数创建对象

先写一个构造函数:

function Person(name, age)
{
    this.name = name;
    this.age = age;
    this.hello = function() {
        console.log(`hi!I am ${this.name}`);
    };
}

this上添加属性即为新对象的属性,然后我们再通过new构造函数来创建对象:

var zhangsan = new Person('zhangsan', 20);
zhangsan.hello();

其中还有第三种创建对象的方法,就是使用Object.create(),用的不多,大家自己去了解一下。

原型链

对于原型链我们需要需要知道以下三点:

  1. __proto__ 是指该对象的原型对象(父对象),沿着某对象的 __proto__ 可以自下而上直到null组成一条对象链,这个就叫原型链。访问对象的属性或方法会沿着原型链自下而上查找。
  2. prototype 是函数(如Array)的独有属性,指向该函数所有实例对象的原型对象。
    由1,2两点可知:
    (new Array()).__proto__ === Array.prototype;  //(1)
  3. constructor 为对象的属性, 指向new出该对象的构造函数。
    由2,3两点可知:
    (new Array()).constructor === Array;  //(2)

    由(1)(2)式可推出:

    (new Array()).constructor.prototype === (new Array()).__proto__;  //(3)

可以结合下面这张图来理解:

Javascript原型链

只要我们理解上面的三点,即__proto__prototypeconstructor的作用和三个式子,对于很多js面向对象的问题我们也都能弄懂了。

对象继承原理

不多说,直接上代码:

function Father() {}
Father.prototype.say = function() {
    console.log('I am Father');
};

function Son() {}
Son.prototype.__proto__ = Father.prototype; // 修改原型指向

var son = new Son();
son.say();

结合这张图看代码:

Javascript继承

ES6对象继承

ES6提供了class和extends关键字实现对象继承,但其实原理仍然是上面的原型链机制。

class Father
{
    say() {
        console.log('I am Father');
    }
}

class Son extends Father {}

var son = new Son();
son.say();

参考文章

  1. 帮你彻底搞懂JS中的prototype、proto与constructor(图解)
  2. 原型继承 - 廖雪峰的官方网站
  3. js创建对象的三种方式 - 改天打老虎 - 博客园

版权声明:本文为博主原创文章,转载需注明来自: 洛洛の空间