原型与原型链的纠葛

96 阅读2分钟

“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

理解原型与原型链首先要搞清楚几个概念,prototype、proto、constructor

  • prototype 每个构造函数都有一个prototype属性,它指向一个对象(对象为调用该构造函数而创建的实例的原型)
  • proto 每一个JavaScript对象(除了 null )都具有的一个属性,叫_proto_,这个属性会指向该对象的原型。
Function._proto_ === Function.prototype
  • constructor 每个原型都有一个constructor属性,指向关联的构造函数
function Person() {

}
console.log(Person === Person.prototype.constructor); // true
  • 原型链:每个对象都有_proto_属性,它指向原型对象,而原型对象也有自己的原型对象,当你访问一个属性时,如果对象内部不存在这个属性就会从原型对象上找,如果找不到就沿着原型对象上的原型对象上找,直到找到null为止。
function Person(name) {
  this.name = name;
}
Person.prototype.sayName = function () {
  return this.name;
};
var person = new Person('Lily');
console.log(person.sayName()); // 'Lily'在内部对象Person上找到
console.log(person.sayName()); // 'Lily'在person的原型对象Person.prototype上找到
console.log(person.toString()); // '[object Object]'在Person.prototype._proto_上找到

手写instanceof从而理解原型链

instanceof:用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上。由此可知,instanceof左边是实例对象,右边是构造函数。

function Person(name){
    this.name = name
}
const person = new Person()
console.log(person instanceof Person) //true
console.log(person instanceof Object) //true

JavaScript对象中有内置对象,这些内置对象都是构造函数,包括Object、Array、String、Number、RegExp。因为它们都是函数所以都是Function创建的,即都是Function的实例。

Object instanceof Object //true
// 可以理解为Object原型链上有一值和Object.prototype相等
Object._proto_ === Function.prototype
Function.prototype._proto_ === Object.prototype
Object._proto_._proto_ === Object.prototype

手写instanceof

function myInstanceof(left, right) {
    // 基本数据类型直接返回 false
    if (typeof left !== 'object' || left === null) return false;
    // getPrototype是Object对象自带的一个方法,等效于__proto__
    let proto = Object.getPrototypeOf(left);
    while (true) {
        // 循环往下寻找,直到找到相同的对象
        if (proto == null) return false;
        // 找到相同的原型对象
        if (proto == right.prototype) return true;
        proto = Object.getPrototypeOf(proto);
    }
}

最后来回答下原型与原型链的一些相关问题。

  1. 原型是什么?

给其他对象提供共享属性的对象

  1. prototype和_proto_的区别?

prototype是函数特有的属性,它指向一个原型对象。 每个对象都有一个_proto_属性,它也指向原型对象。 Function.proto` === Function.prototype

  1. 原型链是什么?

每个对象都有 __proto__ 属性,它指向原型对象,原型对象也是对象,也有 __proto__ 属性,并指向它的原型对象,这样一层一层,最终指向 null,这种关系被称为原型链

  1. 原型和原型链的关系如何?

原型是用来实现继承的方法,原型链是在继承过程中寻找对象中属性及方法的产物。