为何constructor与instance中this和prototype表现存在差异?
关于JavaScript中构造函数、实例、this与prototype的属性差异问题
我来帮你把这个逻辑掰明白——核心就一句话:构造函数本身和它用new创建出来的实例对象是完全独立的两个东西,属性的归属完全不一样!
一、先看构造函数内用this定义属性的场景
先把你的代码贴出来:
function Aircraft() { this.range = '2,000 Km'; } let mustang = new Aircraft(); console.log('Aircraft.range ', Aircraft.range); // 输出 undefined console.log('mustang.range ', mustang.range); // 输出 '2,000 Km'
当你用new调用Aircraft的时候,JavaScript在背后做了这几件事:
- 悄悄创建一个空的新对象
- 把这个新对象绑定给构造函数里的
this - 执行构造函数里的代码(也就是给这个新对象加
range属性) - 默认返回这个新对象给
mustang
所以你写的this.range,是把属性挂在了刚创建的实例对象上,而不是挂在Aircraft这个构造函数本身。Aircraft作为一个函数对象,它自己的属性得直接写Aircraft.xxx = yyy才会有,和实例的属性完全不搭边,所以直接访问Aircraft.range当然是undefined。
二、再看用prototype定义属性的场景
你的第二部分代码是这样的:
function Aircraft() {} Aircraft.prototype.range = '2,000 Km'; let mustang = new Aircraft(); console.log('Aircraft.range ', Aircraft.range); // 还是 undefined console.log('mustang.range ', mustang.range); // 正常输出 '2,000 Km'
这里的逻辑是:Aircraft.prototype是一个专门的原型对象,所有通过new Aircraft()创建的实例,都会“继承”这个原型对象上的属性和方法。当你访问mustang.range时,因为mustang自己身上没有这个属性,JavaScript会顺着原型链往上找,找到Aircraft.prototype上的range并返回它。
但Aircraft这个构造函数本身,和它的prototype是两个完全独立的对象!Aircraft.range是在找构造函数自己的range属性,而不是它原型上的。如果要访问原型上的这个属性,你得写Aircraft.prototype.range才行。
最后总结几个关键点
- 构造函数(比如
Aircraft)是一个独立的函数对象,它的私有属性是直接挂载在自身上的。 - 用
new创建的实例(比如mustang)是全新的对象,构造函数里的this指向的就是这个实例。 - 原型对象是实例的“共享属性池”,实例能继承原型上的内容,但构造函数本身不会直接共享这些属性。
内容的提问来源于stack exchange,提问作者DR01D
相关产品推荐
相关产品推荐

