JavaScript 原型浅析

发布于 2022-07-29 00:57:27 字数 2451 浏览 243 评论 0

JavaScript 中所有的函数默认都有一个名为 prototype(原型)的公有并且不可枚举的属性,这个属性是一个指针,它会指向一个对象。

function Foo () {
}
Foo.prototype; //{ }

而这个对象通常被称为 Foo 的原型对象,用 FooPrototype(自己假想的)表示。 Foo.prototype = FooPrototype; 在默认情况下,所有原型对象都会获得一个 constructor 属性,这个属性包含一个指向prototype属性所在函数的指针。当我们使用 new 来调用这个函数Foo创建一个实例时,该实例的内部会包含一个指针(内部属性),指向这个构造函数的原型对象,这个指针叫 [[prototype]] ,可以使用 proto 来访问这个原型对象。

function Foo () {
}
Foo.__proto__ === Function.prototype // true
var a = new Foo();
a.__proto__ === Foo.prototype; // true
Object.getPrototypeOf(a) === Foo.prototype; // true
Foo.prototype.__proto__ === Object.prototype; // true
Object.prototype.__proto__ === null;// true

Foo.prototype.constructor === Foo; // true
a.constructor === Foo; // true
a.constructor === Foo.prototype.constructor; // true

这里有个比较疑惑的点在于 a.constructor ,难道 a 也有 .constructor 属性?实际上a本身并没有 .constructor 属性,而且,虽然 a.constructor 确实指向 Foo 函数,但是这个属性并不是表示 a 有 Foo 构造 的。

实际上,.constructor 引用同样被委托给了 Foo.prototype ,而 Foo.prototype.constructor 默认指向 Foo 。举个例子:

function Foo () {
}
Foo.prototype = { /**/ };//创建一个新原型对象,相当于 new Object()。
var a1 = new Foo();
a1.constructor === Foo;//false
a1.constructor === Object.prototype.constructor;//true
a1.constructor === Object;//true

a1 并没有 .constructor 属性,所以它会委托 [[prototype]] 链上的 Foo.prototype 。但是这个对象也没有 .constructor 属性(不过默认的 Foo.prototype 对象有这个属性!),所以它会继续委托,这次它会委托给委托链顶端的 Object.prototype 。这个对象有 .constructor 属性,指向内置的 Object(...) 函数。

当然,我们可以给 Foo.prototype 添加一个 .constructor 属性,这需要手动添加一个符合正常行为的不可枚举属性。

function Foo () {
}
Foo.prototype = { /**/ };
Object.defineProperty({
  enumerable: false,
  writable: true,
  configurable: true,
  value: Foo // 让 .constructor 指向 Foo
})

JavaScript 里其他的引用类型,如 Array ,Date ,RegExp ,Function ,String ,Number ,Boolean 等。举例如下:

var a = new Array();
a.__proto__ === Array.prototype; // true
a.__proto__.__proto__ === Object.prototype; // true
a.__proto__.__proto__.__proto__ === null; // true
Array.prototype.constructor === Array;//true
a.constructor === Array;//true
a.constructor === Array.prototype.constructor;//true
Array.constructor === Function;// true

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

尴尬癌患者

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文