关于javaScript中的__proto__和prototype、认识原型链

区别:

__proto__是浏览器对实例化对象中[[prototype]]属性的命名方式,__proto__是属于对象的属性,prototype是属于函数对象的属性。

__proto__指向[函数名].prototype,[函数名].prototype是函数的原型对象

示例:
function Fn1(...){...}; // 函数Fn1
let obj1 = new Fn1(...); // new关键字,会将Fn1以构造函数的形式调用,构造一个对象
obj1.__proto__ === Fn1.prototype; // true

obj1.__proto__指向Fn1.prototype(Fn1的原型对象)。

个人解读:

区别:

prototype可以理解为在函数(函数对象)上的一个名为原型对象的属性,这里的原型对象是命名和功能意义双重含义的,所以prototype是函数(函数对象)上的一个属性,保存原型对象,意义上也可以叫做原型对象。那么这个原型对象的内容是一些可以继承的属性和方法。而__proto__是对象上的一个属性,通过这个属性可以访问prototype这个函数对象上的属性里的内容,也就是说对象.__proto__指向构造该对象的函数.prototype

当然,由于函数在js语言中也是对象,所以也有__proto__属性,指向构造该函数的Function.prototype,而Function.prototype这个原型也是对象,所有也有它的__proto__属性,以此类推,这就形成了一条原型链,链子的尽头是Object.prototype的__proto__,为null,这个Object非特指某一个对象,而是实际的构造所有对象的函数。

补充:
  1. 有一种比较迷惑的特殊情况,也就是Function.__proto__,它在浏览器中显示的是一个ƒ () { [native code] },但其实这个就是Function.prototype,因为所有的构造函数的的原型都是Function.prototype,Function这个函数的构造函数也不例外,而这个Function.prototype比较特殊是一段native code实现。可能的情况是,js原生代码c/c++实现了一个Object.prototype还有一个Function.prototype,并将Function.prototype指向了Object.prototype,除此之外,其它的对象、函数皆衍生自这两个原型。

  2. 这里还要提一下constructor这个属性,理解为构造器,该属性是函数,并挂载在函数的prototype属性上。每一个由函数构造而来的对象都有一个constructor属性(继承于构造该对象的函数),该属性功能为访问(获取)构造该对象的构造函数,按以下示例理解

还是这个示例:

function Fn1(...){...}; // 函数Fn1
let obj1 = new Fn1(...); // new关键字,会将Fn1以构造函数的形式调用,构造一个对象

该函数.prototype.constructor === 该函数。该函数构造的对象.constructor继承自该函数.prototype.constructor === 该函数

Fn1.prototype.constructor === Fn1。obj1.constructor === Fn1.prototype.constructor === Fn1

注意:constructor这个属性只是具有不可枚举属性,而依旧是可写、可配置的,比较随意,所以对该属性的引用结果没办法保证足够的信任,尽量少用。

posted @ 2023-01-17 15:44  szq233  阅读(63)  评论(0编辑  收藏  举报