链上的 Foo.prototype 。 但是这个对象也没有 constructor 属性(不过默认的 Foo.prototype 对象有这个属性 , 默认的已经被修改为空对象) 。 所以它会继续委托 , 这次会委托给委托链顶端的 Object.prototype 。 这个对象有 constructor 属性 , 指向内置的 Object 函数 。
错误观点已经被摧毁 。
Foo.prototype 被人为修改成空对象 。 所以指向 Object.prototype , Object.prototype.constructor 指向 Obeject
当然 , 你可以给 Foo.prototype 添加一个 consructor 属性 , 不过这需要手动添加一个符合正常行为的不可枚举属性 。
这里的错误观点指的是 a.constructor === Foo 理解为由 Foo 构造 , 然而并不是 。
a 的原型就是 Foo 的原型 。 a.constructor 即 Foo.prototype.constructor
举例来说:
function Foo() {Foo.prototype = { // 创建一个新原型对象// 需要在 Foo.prototype 上修复丢失的 constructor 属性// 新对象属性起到 Foo.prototype 的作用Object.defineProperty(Foo.prototype 'constructor' { enumerable: false writable: true configurable: true value: Foo // 让 constructor 指向 Foo)var a = new Foo()a // Foo { ___proto___: { constructor: ? Foo() 修复 constructor 需要很多手动操作 。 所有这些工作都是源于把「constructor」错误地理解为「由……构造」 , 这个误解的代价实在太高了 。
实际上 , 对象的 constructor 会默认指向一个函数 , 这个函数可以通过对象的 prototype 引用 。 「constructor」和「prototype」这两个词的含义可能适用也可能不适用 。 最好的办法是记住这一点:「constructor」并不表示被构造 。
constructor 并不是一个不可变属性 。 它是不可枚举的 , 但是它的值是可写的 。 此外 , 你可以给任意 [[Prototype
a.constructor 并不表示由 Foo 构造 , 而是委托给 Foo
链中的任意对象添加一个名为 constructor 的属性对其进行修改 , 你可以任意对其赋值 。
和 [[Get
算法查找 [[Prototype
链的机制一样 , constructor 属性引用的目标可能和你想的完全不同 。
现在你应该明白这个属性多么随意了吧 。
结论:一些随意的对象属性引用 , 比如 a.constructor 实际上是不被信任的 , 它们不一定会指向默认的函数引用 。 此外 , 很快我们就会看到 , 稍不留神 a.constructor 就可能会指向你意想不到的地方 。
似乎这个属性被修改了 , 对于使用 new 实例新对象也不影响 。
a.constructor 是一个非常不可靠并且不安全的引用 。 通常来说要尽量避免使用这些引用 。
原型继承我们已经看到过了许多 JavaScript 程序中常用的模拟类行为的方法 , 但是如果没有「继承」机制的话 , JavaScript 中的类就只是一个空架子 。
实际上 , 我们已经了解了被称作是原型继承的机制 , a 可以「继承」 Foo.prototype 并访问 Foo.prototype 的 myName 函数 。 但是我们之前只把继承看作是类是类之间的关系 , 并没有把它看作是类和实例之间的关系:
- javascript|穿戴设备将迎变革,OPPO又增新专利,能提升模式切换效率!
- |强劲送风,满足你对美感的挑剔—洛斐有范S桌面风扇
- 你甩不掉的伴侣——AEROPEXAS800初体验
- 趋势雷达|行业流行力——《新锐美妆种草看点》
- 社交平台cookie出卖了你——木马FFdroider欲窃取你的账户信息丨大东话安全
- 电子商务|广州蓝景分享 — 给刚入职前端\大佬\们的一些建议
- 开源软件|嵌入式开发:技巧和窍门——引导加载程序跳转到应用程序代码
- 三星|三星 S22 Ultra——硬件上的机皇,系统体验两极分化
- 天津航空——打造主题飞机 为智能大会插上“双翼”
- 支付宝|嵌入式开发:嵌入式基础——重启和重置的区别
