javascript原理--> 原型与原型链

211 阅读2分钟

javascript 构造函数

javascript 通过构造函数来实现面向对象编程,因为JS中没有类(Class)这个概念,所以JS的设计者使用了构造函数来实现继承机制。

// 构造函数
function Dog() {
}

// 生成实例
const p = new Dog();

在es2016后增加了 class 的语法糖,但最终通过babel,或typescript等转义之后,还是会创建function 构造函数。

class Dog{
	bark() {
    	console.log('dog bark');
    }
}

var d = new Dog();

// babel 转译后

function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } }

function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }

var Dog = /*#__PURE__*/function () {
  function Dog() {
    _classCallCheck(this, Dog);
  }

  _createClass(Dog, [{
    key: "bark",
    value: function bark() {
      console.log('dog bark');
    }
  }]);

  return Dog;
}();

var d = new Dog();

原型

  • 每一个js 对象的(null除外),其构造函数都有一个 prototype 属性指向它的原型对象,这个对象就是原型。
   Object.getPrototypeOf(p)
   
   1.  {constructor: ƒ}
1.  1.  constructor: ƒ Dog()
    1.  1.  argumentsnull
        1.  callernull
        1.  length0
        1.  name"Dog"
        1.  prototype: {constructor: ƒ}
        1.  [[FunctionLocation]]: VM569:1
        1.  [[Prototype]]: ƒ ()
        1.  [[Scopes]]: Scopes[1]
    1.  [[Prototype]]: Object
    
  • 每一个js对象(null除外),都有一个 proto 引用或者叫 [[Prototype]] 属性,指向其构造函数的原型对象。
  • 每个原型都有一个 constructor 属性指向关联的构造函数。
function Person() {

}
var person = new Person();
console.log(person.__proto__ === Person.prototype); // true

于是我们能构造出一个这样的图

image.png

原型链

当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

由于每一个对象都有一个 指针, 也就是 proto 指向其构造函数的原型对象, 我们把这条有一指针组成的链式结构叫做 原型链

image.png

总结

原型链可以理解为,查找对象根源的链条,在读取属性值时,寻根问祖的规则。