为什么我不能在原型函数中为“this”赋值?

时间:2012-03-15 02:48:02

标签: javascript

为什么我可以这样做:

Array.prototype.foo = function() {
    this.splice(0, this.length);
    return this.concat([1,2,3]);
}

但我不能这样做:

Array.prototype.foo = function() {
    return this = [1,2,3];
}

这两个函数都会破坏它的值并将其更改为[1,2,3],但第二个函数会抛出以下错误:Uncaught ReferenceError: Invalid left-hand side in assignment

我怀疑这是因为允许分配意味着我可能会将数组更改为其他内容(如字符串),但我希望有人确切知道和/或有更详细的解释。

4 个答案:

答案 0 :(得分:20)

您将对象与引用混淆。

数组是一个对象,当你使用像[1,2,3]这样的文字时,你正在创建一个新的数组。

thisa等变量名称是对象的引用。如果有帮助,可以将对象想象成一个人,将参考想象成他们的昵称。您可以对同一对象具有多个引用,例如:

var a = [1,2];
var b = a;
b.push(3);
alert(a.length); // Gives "3"

想象一下,如果你有一个名叫莎拉的朋友。你有时也称她为“王牌”。如果Sarah有一天会理发,Ace也会理发,因为“Sarah”和“Ace”都是同一个人的不同名字。

如果您使用变体数组方法,例如a.pusha.spliceconcat但不是一个!),则更改现有的Array对象,a仍然引用对同一个对象。这就像是剪头发 - 你可能看起来不一样,但你仍然是同一个人。

当您使用a = [1,2,3]为新值分配引用时,您将创建一个新数组,并更改a以引用它。这就像找到一个不同头发的新朋友,并决定改为称她为Ace。

现在this是由Javascript生成的特殊名称。这不是像萨拉这样的名字,而是更像是“母亲”的标题。你的母亲可以换一个新的发型,但你不能得到一个新的母亲。同样,您无法更改函数内部this引用的内容。

答案 1 :(得分:14)

不允许在函数中为this赋值。假设您可以执行此操作,并且您的代码类似于:

Array.prototype.foo = function() {
    return this = [1, 2, 3];
}

var a = ["beans", "rice"];
a.foo();
// a now points to an object containing [1, 2, 3]

现在,如果你这样做了:

var a = ["beans", "rice"];
var b = a; // b refers to the same object as a
b.foo();
// what does b refer to now? how about a?

在对象上调用函数.foo()的行为不应更改对象的标识。如果b突然开始引用与a不同的对象,仅仅因为某个方法被调用,这对调用者来说会非常混乱。

答案 2 :(得分:7)

您不能重新分配this。因为与执行上下文关联的 this 值是不可变的。

答案 3 :(得分:3)

是否可以更改this的值?不是通过分配,您无法为this分配值

你的案子:

Array.prototype.foo = function() {
    this.splice(0, this.length);
    return this.concat([1,2,3]);
}
     

但我不能这样做:

Array.prototype.foo = function() {
    return this = [1,2,3];
}

修改原型添加方法foo()时,第一部分使数组变空,等于重新分配其实例。

例如var a = []

然后在返回值中:

return this.concat([1,2,3]);

请记住concat不会破坏数组,它会创建一个新数组并将其返回

鉴于a = ['x']b = ['y']c = a.concat(b)会产生c = ['x','y']ab保持不变

现在,因为你在数组中执行此操作

a=['a','b','c']

然后您拨打a.foo();a内的a=[]将与this.splice(0, this.length);相等,然后将[ ][1,2,3]连接起来

所以,如果我只说a.foo(),事实上,如果我没有将结果分配给某些东西,那么外面没有任何事情发生,只是一个空的。

如果a被分配给

c = a.foo()

然后c[1,2,3]a仍为空[ ]

在第二部分中,this = [1,2,3]

可以更改此值的值,而不是通过赋值,您无法为此赋值