Почему я не могу присвоить новое значение «this» в функции-прототипе? - PullRequest
26 голосов
/ 15 марта 2012

Почему я могу это сделать:

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 ]

20 голосов
/ 15 марта 2012

Вы путаете объекты со ссылками.

Массив - это объект, когда вы используете литерал типа [1,2,3], вы создаете новый массив.

Имя переменной, напримерthis или a - это ссылка на объект.Если это поможет, представьте объект как личность, а ссылку - как псевдоним.Вы можете иметь более одной ссылки на один и тот же объект, например:

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

Представьте, что у вас есть друг по имени Сара.Вы также иногда называете ее "туз".Если Сара однажды подстриглась, у Эйса тоже будет стрижка, потому что «Сара» и «Эйс» - это разные имена одного и того же человека.

Если вы используете метод мутирующего массива, такой как a.push или a.splice (concat однако не один!), Вы меняете существующий объект Array, а a по-прежнему ссылается на тот же объект.Это похоже на стрижку - вы можете выглядеть по-другому, но вы все равно один человек.

Когда вы присваиваете ссылку на новое значение, с помощью a = [1,2,3] вы создаете новый массиви изменив a для ссылки на него.Это все равно, что найти нового друга с другими волосами и вместо этого решить назвать ее Эйсом.

Теперь this - это специальное имя, созданное Javascript.Это не имя, как Сара, а скорее название, как «мама».Ваша мама может сделать новую стрижку, но вы не можете получить новую маму.Аналогично, вы не можете изменить то, на что this ссылается изнутри функции.

14 голосов
/ 15 марта 2012

Не разрешено присваивать значение 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 просто потому, что был вызван какой-то метод.

7 голосов
/ 15 марта 2012

Вы не можете переназначить this.Поскольку это значение, связанное с контекстом выполнения, является неизменным.

3 голосов
/ 01 мая 2013

Можно ли изменить значение 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 назначено что-то

c = a.foo()

, тогда c будет [1,2,3], а a все еще пусто [ ]

Во второй части this = [1,2,3]

Возможно изменить значение этого ?, не присваивая, вы не можете присвоить значение этому

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...