js这麻烦的原型

77 阅读2分钟

proto

⚠️ __proto__不是标准用法, 可以使用Reflect.getPrototypeOf 或者 Object.getPrototypeOf, _proto__指向的是负责创建它的对象,即调用了__proto__的对象是由谁负责创建出来的

如下

const stringA = new String("stringA")
// true,即stringA是由String.prototype创建出来的
console.log(Reflect.getPrototypeOf(stringA) === String.prototype)
// true,即String.prototype是由Object.prototype创建出来的
console.log(Reflect.getPrototypeOf(String.prototype) === Object.prototype)

const objectA = {}
// true,即objectA是由Object.prototype创建出来的
// Object.prototype是一个创建了objectA的对象
console.log(Reflect.getPrototypeOf(objectA) === Object.prototype)

// true,说明Object.prototype已经是最顶层的对象了
console.log(Reflect.getPrototypeOf(Object.prototype) === null)

prototype

可能这时候大家有疑问, Man的prototype是怎么来的,其实对于JS来说,class 只是语法糖,所以我用了babel进行了还原, 当发生继承行为的时候,subClass会基于superClass.prototype创建一个prototype对象


function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
   // 输出false
  console.log(subClass.prototype.__proto__ == superClass.prototype)
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: { value: subClass, writable: true, configurable: true },
  });
   // 输出true 调用Object.create之后 派生类指向了父类
  console.log(subClass.prototype.__proto__ == superClass.prototype)
  if (superClass) _setPrototypeOf(subClass, superClass);
}

当执行完上述操作,可以得到如下结果,配合例子解释

class Person {

}

class Man extends Person {

}

const man = new Man()
// 输出true,说明man 是被 Man.prototype创建出来
console.log(Reflect.getPrototypeOf(man) === Man.prototype)
// 输出true,说明Man.prototype是被Person.prototype创建出来
console.log(Reflect.getPrototypeOf(Man.prototype) === Person.prototype)

如果仔细留意,会发现Reflect.getPrototypeOf的调用方是对象实例,而prototype的调用方是构造函数,即语法糖包装过的类对象。同理,Man.prototype也是一个对象实例, 而由于继承关系,我们可知Man.prototype是Person.prototype由创建出来的。

我们平常使用的instanceof操作符,object instanceof constructor 本质上是判断constructor.prototype 是否存在于参数 object 的原型链上。

总结

我们可以得出下面的结论

  • __proto__是个指针,指向负责创建它的对象
  • prototype是个对象,负责创建对应类型的对象实例
	// 这就是原型链 通过__proto__串联起来
console.log(Reflect.getPrototypeOf(new String("")) === String.prototype)
console.log(Reflect.getPrototypeOf(String) === Function.prototype)
//console.log(Reflect.getPrototypeOf(Function) === Function.prototype)
//console.log(Reflect.getPrototypeOf(Object) === Function.prototype)
console.log(Reflect.getPrototypeOf(Function.prototype) === Object.prototype)
console.log(Reflect.getPrototypeOf(Object.prototype) == null)

所有基本对象的prototype都来源Object.prototype,万物都继承自对象Object

所有基本对象的构造函数都来源Function.prototype,对象本身都由Function创建而来,所以Function是一等公民😼。

对象的属性来源是prototype,对象本身由Function创建,prototype赋予了对象能力,Function创建了对象

参考