一直没搞懂的原型,真的懂了吗?

195 阅读3分钟

讲实在的,原型这里我是真的没弄懂,我这脑子一扯到这些一层一层的就乱的跟个xxx一样。我一直在想显式原型和隐式原型这两者的区别是什么,太乱了,我这里就先捋一下,可能有些错误,大家不要喷哈。主要就是借助通义千问以及掘金里大佬写的文章进行总结。

救命啊!隐式原型和显式原型到底是啥

首先这是通义千问给我的答案:

image.png

所以我就问了一个这样的问题

image.png

我这里稀里糊涂的,怎么越搞越不明白了,[[Prototype]]这个东西好像一直没有用过,而且我听见的好像都是把__proto__这个作为隐式原型的。

后来就再看掘友写的文章中,说通常了解JavaScript 中的原型时,会将其分为两种类型:函数原型prototype(显示原型)和对象原型__proto__(隐式原型)。

另外在翻阅资料的时候了解了一下引用类型的四个规则。

1、引用类型,都具有对象特性,即可自由扩展属性。

2、引用类型,都有一个隐式原型 __proto__ 属性,属性值是一个普通的对象。

3、引用类型,隐式原型 __proto__ 的属性值指向它的构造函数的显式原型 prototype 属性值。

4、当你试图得到一个对象的某个属性时,如果这个对象本身没有这个属性,那么它会去它的隐式原型 __proto__(也就是它的构造函数的显式原型 prototype)中寻找。

第一点还是很好理解的,就是可以给引用类型添加属性,例如给数组添加个a属性:

image.png

第二点的话也去看一下下:

image.png

arr.__proto__的值指向的是Array.prototype,而Array.prototype[[Prototype]] 属性指向 Object.prototype

第四点的话其实就是原型链的描述。

其实到这里我的理解是,原型其实就是构造函数常说的,而隐式原型就是对象常说的,所以就经常听到一句话,实例对象的隐式原型就是构造函数的显式原型。

看个例子:

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.greet = function() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const person1 = new Person('Alice', 30);

此时打印person1的话,它的值是{ name: 'Alice', age: 30 }

但是此时我们仍然可以用实例对象调用greet方法,因为此时greet是Person原型上的方法,根据第四点,如果在实例对象上找不到的话就需要去它的隐式原型上找,一层层往上找,直到找不到。

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Object.prototype.greet = function() {
    console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};

const person1 = new Person('Alice', 30);
person1.greet();

此时我们把greet方法放到了object的原型上,实例依然可以访问到此方法。

了解了一点之后,找找应用场景。

1.instanceof的实现

我们都知道instanceof是用来判断引用数据类型的,它的实现原理其实就是根据原型链来查找。

function myInstanceof(L,R){
  while(L!==null){
    if(L.__proto__==R.prototype)
      return true
  }
  L = L.__proto__
}

2. new的实现

new的实现存在原型的身影。我们要创建个对象可以用new来实现,它通过创建一个新的对象,然后让这个对象的隐式原型等于构造函数的原型,然后改变this的指向,就基本实现了一个new

function myNew(construct,...args){
  const obj = []
  obj.__proto__==construct.prototype
  const result = construct.apply(obj,args)
  return result instanceof Object ? result : obj
}

最后

这只是我一介野修的理解,如果有不到位的地方,欢迎大家指导,感激不尽!