为什么我不能在原型函数中为“this”分配一个新值?

IT技术 javascript
2021-01-29 09:54:49

为什么我可以这样做:

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

但我不能这样做:

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

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

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

4个回答

您将对象与引用混淆了。

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

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

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

想象一下,如果你有一个叫莎拉的朋友。你有时也称她为“Ace”。如果有一天莎拉理了发,艾斯也会理发,因为“莎拉”和“艾斯”对于同一个人来说都是不同的名字。

如果您使用像a.push这样的变异数组方法a.spliceconcat但不是一个!),您会更改现有的 Array 对象,并且a仍然引用同一个对象。这就像理发——你可能看起来不同,但你仍然是同一个人。

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

现在this是由 Javascript 生成的特殊名称。它不是像莎拉这样的给定名字,而更像是一个头衔,比如“母亲”。你妈妈可以换个新发型,但你不能找一个新妈妈。同样,您不能this从函数内部更改引用的内容。

不允许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不仅仅是因为调用了某个方法,这对于调用者来说会非常混乱

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

是否可以更改 的值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']and b = ['y'],c = a.concat(b)结果c = ['x','y'], aandb保持不变

现在既然你在数组里面做这个

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

然后你打电话a.foo();,里面a会得到相等a=[]this.splice(0, this.length);然后将[ ][1,2,3]

因此,如果我说 just a.foo(),实际上,如果我不将结果分配给某事,则外部不会发生任何事情,只是 a 保持为空。

如果a被分配给某物

c = a.foo()

然后c将是[1,2,3]a仍然是空的[ ]

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

是否可以更改 this 的值?,不是通过赋值,您不能为 this 赋值