Подтвердить что ты не робот

Почему я не могу назначить новое значение "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];
}

Обе функции уничтожают значение этого параметра и меняют его на [1,2,3], а второй выдает следующую ошибку: Uncaught ReferenceError: Invalid left-hand side in assignment

Я подозреваю, что, поскольку разрешение означает, что я могу потенциально изменить массив на что-то другое (например, на строку), но я надеюсь, что кто-то там точно знает и/или имеет более подробное объяснение.

4b9b3361

Ответ 1

Невозможно присвоить значение 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

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

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

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

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

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

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

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

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

Ответ 3

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

Ответ 4

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

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