属性 添加到 JS 对象作为原型被提升,而原型函数不是
Property added to a JS object as a prototype is hoisted, whereas a prototype function is not
我(或者至少我认为我是)非常熟悉 JavaScript 中 Hoisting 的概念。
考虑以下陈述:
A function declaration will be hoisted along with its body, whereas a function expression will not; only the var statement will be hoisted.
“Function declarations and function variables are always moved (‘hoisted’) to the top of their JavaScript scope by the JavaScript interpreter” - Berry Cherry
现在考虑以下函数:
function User() {
this.name = "";
this.life = 100;
this.heal = function heal(player) {
player.life+=5;
console.log("\nHey" + player.name + "! Player " + this.name + " healed you for 5.");
}
}
...以及以下用户:
var Dan = new User("Danny");
var Liz = new User("Lizzy");
说我想以原型函数的形式向已经定义的用户添加一个新的skill,就像这样(附加到代码):
User.prototype.uppercut = function uppercut(player) {
player.life-=10;
console.log("\nBaaam! " + player.name + ", player " + this.name + " uppercuted you for 10 damage.");
};
... 现在,使用所说的 skill (在原型之前添加) :
Liz.uppercut(Dan);
Liz.uppercut(Dan);
...我将收到以下错误:
Liz.uppercut(Dan);
^
TypeError: Liz.uppercut is not a function
我是否应该使用原型向 User 对象添加一个 属性,但在原型声明之前的代码中访问它,它将 起作用(吊装):
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
User.prototype.mana = 100;
基本上,这向我证实了适用于函数和变量的相同 提升 原则也适用于原型。
问题 1:这个逻辑是否有效,如果有效,您能解释一下原因吗?
问题 2:如果有办法避免这种情况w/o将原型表达式移动到原型函数调用之上?
谢谢祝你玩得开心!
代码片段:
function User(name) {
this.name = name;
this.life = 100;
this.heal = function heal(player) {
player.life+=5;
console.log("Hey" + player.name + "! Player " + this.name + " healed you for 5.");
}
}
var Dan = new User("Danny");
var Liz = new User("Lizzy");
Liz.uppercut(Dan);
Liz.uppercut(Dan);
console.log(Liz.name + " you know have " + Liz.life + " life.");
User.prototype.mana = 100;
User.prototype.uppercut = function (player) {
player.life-=10;
console.log("Baaam " + player.name + "! Player " + this.name + " uppercuted you for 10 damage.");
};
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
Dan.mana = 200;
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
不,分配(原型属性或其他)没有提升。
代码
function User() { this.name = ""; … }
var Dan = new User("Danny");
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
User.prototype.mana = 100;
不起作用,它将记录 Hey there ! You have undefined remaining mana.
。
您在这里混淆了变量和属性。变量被提升,属性没有。
在您的示例中,Dan
是一个变量,mana
是 Dan
的 属性。
JavaScript 处理 undefined
变量的方式不同于 undefined
属性。
变量在声明时 提升,通过拆分声明的左侧。即 var Dan = new User("Danny");
被分成两个语句,var Dan; Dan = new User("Danny");
。 var Dan
然后 提升 到函数的顶部。但分配保持不变。
如果您的代码仅包含 Dan = new User("Danny");
,您将收到 ReferenceError,因为您将尝试对未声明的变量进行赋值。缺少声明,因此从未提升变量。
另一方面,属性的运作方式不同。 属性 访问器 return 对父对象进行哈希查找的结果。在Dan.mana
的情况下,定义了父对象,所以没有ReferenceError,但是mana
不是Dan
的属性,所以哈希查找return s undefined
。没有发生提升,因为没有声明变量。
因此,原型不能绑定提升,因为它们是严格的赋值操作。即使在函数开头修改了原型,也不会受到提升的影响,因为提升 仅 影响声明变量,而不是赋值(发生在调用的右侧)。
访问未在对象上定义的 属性 将得到 undefined
。这里没有提升规则。
Liz.mana
会给你 undefined
.
Liz.uppercut
也会给你 undefined
.
Liz.agility
也会给你 undefined
.
调用 Liz.uppercut(Dan)
会引发错误,因为您正试图将 Liz.uppercut
(即 undefined
)作为函数调用。这会导致“undefined is not a function”错误。
我(或者至少我认为我是)非常熟悉 JavaScript 中 Hoisting 的概念。
考虑以下陈述:
A function declaration will be hoisted along with its body, whereas a function expression will not; only the var statement will be hoisted.
“Function declarations and function variables are always moved (‘hoisted’) to the top of their JavaScript scope by the JavaScript interpreter” - Berry Cherry
现在考虑以下函数:
function User() {
this.name = "";
this.life = 100;
this.heal = function heal(player) {
player.life+=5;
console.log("\nHey" + player.name + "! Player " + this.name + " healed you for 5.");
}
}
...以及以下用户:
var Dan = new User("Danny");
var Liz = new User("Lizzy");
说我想以原型函数的形式向已经定义的用户添加一个新的skill,就像这样(附加到代码):
User.prototype.uppercut = function uppercut(player) {
player.life-=10;
console.log("\nBaaam! " + player.name + ", player " + this.name + " uppercuted you for 10 damage.");
};
... 现在,使用所说的 skill (在原型之前添加) :
Liz.uppercut(Dan);
Liz.uppercut(Dan);
...我将收到以下错误:
Liz.uppercut(Dan);
^
TypeError: Liz.uppercut is not a function
我是否应该使用原型向 User 对象添加一个 属性,但在原型声明之前的代码中访问它,它将 起作用(吊装):
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
User.prototype.mana = 100;
基本上,这向我证实了适用于函数和变量的相同 提升 原则也适用于原型。
问题 1:这个逻辑是否有效,如果有效,您能解释一下原因吗?
问题 2:如果有办法避免这种情况w/o将原型表达式移动到原型函数调用之上?
谢谢祝你玩得开心!
代码片段:
function User(name) {
this.name = name;
this.life = 100;
this.heal = function heal(player) {
player.life+=5;
console.log("Hey" + player.name + "! Player " + this.name + " healed you for 5.");
}
}
var Dan = new User("Danny");
var Liz = new User("Lizzy");
Liz.uppercut(Dan);
Liz.uppercut(Dan);
console.log(Liz.name + " you know have " + Liz.life + " life.");
User.prototype.mana = 100;
User.prototype.uppercut = function (player) {
player.life-=10;
console.log("Baaam " + player.name + "! Player " + this.name + " uppercuted you for 10 damage.");
};
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
Dan.mana = 200;
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
不,分配(原型属性或其他)没有提升。
代码
function User() { this.name = ""; … } var Dan = new User("Danny"); console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana."); User.prototype.mana = 100;
不起作用,它将记录 Hey there ! You have undefined remaining mana.
。
您在这里混淆了变量和属性。变量被提升,属性没有。
在您的示例中,Dan
是一个变量,mana
是 Dan
的 属性。
JavaScript 处理 undefined
变量的方式不同于 undefined
属性。
变量在声明时 提升,通过拆分声明的左侧。即 var Dan = new User("Danny");
被分成两个语句,var Dan; Dan = new User("Danny");
。 var Dan
然后 提升 到函数的顶部。但分配保持不变。
如果您的代码仅包含 Dan = new User("Danny");
,您将收到 ReferenceError,因为您将尝试对未声明的变量进行赋值。缺少声明,因此从未提升变量。
另一方面,属性的运作方式不同。 属性 访问器 return 对父对象进行哈希查找的结果。在Dan.mana
的情况下,定义了父对象,所以没有ReferenceError,但是mana
不是Dan
的属性,所以哈希查找return s undefined
。没有发生提升,因为没有声明变量。
因此,原型不能绑定提升,因为它们是严格的赋值操作。即使在函数开头修改了原型,也不会受到提升的影响,因为提升 仅 影响声明变量,而不是赋值(发生在调用的右侧)。
访问未在对象上定义的 属性 将得到 undefined
。这里没有提升规则。
Liz.mana
会给你undefined
.Liz.uppercut
也会给你undefined
.Liz.agility
也会给你undefined
.
调用 Liz.uppercut(Dan)
会引发错误,因为您正试图将 Liz.uppercut
(即 undefined
)作为函数调用。这会导致“undefined is not a function”错误。