轻松理解JS原型原型链

464 阅读2分钟

导读

js原型原型链是基础,是对js继承,new的原理,封装组件等等的前提条件。

原型英文是prototype,构造器的英文是constructor

通俗理解

  1. 每个js对象创建的时候,都会与之关联另一个对象。这个另一个对象就是原型对象。
  2. 比如现在创建一个空数组arr,arr能调用数组的方法,arr本身是没有数组方法的,js会通过__proto__(非标准属性)一层层往上找,直到从Array原型上找到对应的方法,这一层层关联起来的关系就是原型链。

概念

  1. js对象可分为函数对象和普通对象,每个对象都有__proto__属性,但只有函数对象才有prototype属性。
var a = {};
console.log(a.prototype); //undefined
console.log(a.__proto__);  //Object {}

var b = function(){}
console.log(b.prototype); //b {}
console.log(b.__proto__);  //function() {}
  1. Object、Function都是js内置的函数对象,类似我们常用的Array、Date、Number、String。
  2. 对象的__proto__指向一个对象,这个对象有两个属性,constructor和__proto__,constructor指向对应的构造函数。
// 以下构造函数Person,他的原型上有所属国属性motherland='China'
function Person(name, age){ 
    this.name = name;
    this.age = age;
 }
 Person.prototype.motherland = 'China'
// 通过new Person()创建的person1实例
let person1 = new Person('kevin', 30);
Person.prototype.constructor == Person // 原型对象(即Person.prototype)的constructor指向构造函数本身
person1.__proto__ == Person.prototype // 实例(即person01)的__proto__和原型对象指向同一个地方

prototype.png

原型原型链的作用

原型对象存放实例中共有的属性与方法,可以大大减少内存的消耗。

扩展知识

proto

__proto__ 是非标准属性,如果要访问一个对象的原型,建议使用 ES6 新增的 Reflect.getPrototypeOf 或者 Object.getPrototypeOf() 方法。

console.log({}.__proto__ === Object.getPrototypeOf({})); // => true

ES6 class

ES6 class 其实就是构造器的语法糖

class Rectangle {
    constructor(x, y) {
      this.x = x;
      this.y = y;
    }
    draw() {
      console.log('draw');
    }
}

babel + babel-preset-es2015-loose 编译出的结果

'use strict';
// Rectangle class 可以理解为就是一个构造器函数
var Rectangle = (function () {
  function Circle(x) {
    this.x = x;
  }
  var _proto = Circle.prototype;
  // class 方法定义在 prototype 上
  _proto.draw = function draw() {
    console.log('draw');
  };
  return Circle;
})();

extends 继承

class Shape {
    constructor(y) {
      this.y = y;
    }
}
class Rectangle extends Shape {
    constructor(y, x) {
        super(y);
        this.x = x;
    }
    draw() {
        console.log('draw');
    }
}

babel + babel-preset-es2015-loose 编译出的结果


var Shape = function Shape(y) {
    this.y = y;
};
var Circle = (function (_Shape) {
    _inheritsLoose(Circle, _Shape);
    function Circle(y, x) {
        var _this;
        // 组合继承
        _this = _Shape.call(this, y) || this;
        _this.x = x;
        return _this;
    }
    var _proto = Circle.prototype;
    _proto.draw = function draw() {
        console.log('draw');
    };
    return Circle;
})(Shape);

小结

希望看完本篇文章能对你有如下帮助:

  • 理解JS 原型原型链
  • ES6 Class

文中如有错误,欢迎在评论区指正,如果这篇文章帮助到了你,欢迎点赞和关注。

往期内容推荐

  1. 深拷贝