为什么我可以这样做:
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
我怀疑这是因为允许赋值意味着我可能会将数组更改为其他东西(比如字符串),但我希望有人能确定和/或有更详细的解释。
您混淆了对象和引用。
数组是一个对象,当您使用像[1,2,3]
这样的文字时,您正在创建一个新数组。
像this
或a
这样的变量名是对对象的引用。如果有帮助的话,把一个对象想象成一个人,把引用想象成他们的昵称。您可以对同一对象有多个引用,例如:
var a = [1,2];
var b = a;
b.push(3);
alert(a.length); // Gives "3"
想象一下,如果你有一个叫莎拉的朋友。你有时也叫她"王牌"。如果有一天Sarah理发,Ace也会理发,因为"Sarah"one_answers"Ace"对同一个人来说都是不同的名字。
如果使用像a.push
或a.splice
这样的可变数组方法(但concat
不是一个!),则更改现有的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']
和b = ['y']
,c = a.concat(b)
导致c = ['x','y']
,而a
和b
保持与相同
现在,既然你在阵列内这样做
a=['a','b','c']
然后调用a.foo();
,在a
内将获得相等的a=[]
,与this.splice(0, this.length);
连接,然后将[ ]
与[1,2,3]
连接
所以,如果我说只是a.foo()
,事实上,如果我不将结果分配给某个东西,那么外部什么都不会发生,只是a保持为空。
如果a
被分配给某个
c = a.foo()
则c
将是[1,2,3]
,并且a
仍然为空[ ]
第二部分,this = [1,2,3]
可以更改这个?的值?,不是通过赋值,您不能给这个赋值