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

Phi*_*ton 27 javascript

我为什么这样做:

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

但我不能这样做:

Array.prototype.foo = function() {
    return this = [1,2,3];
}
Run Code Online (Sandbox Code Playgroud)

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

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

Tob*_*hen 20

您将对象与引用混淆.

当您使用文字时,数组是一个对象,就像[1,2,3]您正在创建一个新数组一样.

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

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

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

如果使用像a.push或的变异数组方法a.splice(concat但不是一个!),则更改现有的Array对象,并a仍然引用同一个对象.这就像剪头发 - 你可能看起来不一样,但你仍然是同一个人.

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

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


Gre*_*ill 15

不允许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]
Run Code Online (Sandbox Code Playgroud)

现在,如果你这样做了:

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?
Run Code Online (Sandbox Code Playgroud)

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


xda*_*azz 8

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