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

В Javascript есть эквивалент .apply, который не меняет значение этого?

Кажется, достаточно легко, я хочу вызвать функцию с массивом аргументов. Конечно, я могу сказать func.apply(this, ['some', 'arguments']);, но это изменит значение this внутри func. Любая идея, как это сделать, не меняя его?

4b9b3361

Ответ 1

Обратите внимание, что в ES6 вы также можете написать:

func(...someArray)

Здесь this становится Window внутри func, что бесполезно. Но если вы пишете:

obj.func(...someArray)

this внутри func будет obj.

Это может быть особенностью, которую я искал 5 лет назад, но это было 5 лет назад, поэтому кто помнит:)

Ответ 2

Вы не можете, из-за того, как this работает в JavaScript. Читайте дальше:

Переход по "Ввод контекста выполнения" в спецификации ECMAScript: при вызове функции значение this равно определяется тем, что ему осталось (называется объектом активации). Позвольте создать функцию под названием steve и поместить его в объект:

function steve(){}
var obj = { method: steve };

... когда мы называем steve как obj.method(), его this составляет obj, потому что obj был объектом активации.

Трудный случай - когда ничего не осталось слева от вызова функции:

steve(); // Who am I ?!

Нет ничего слева от вызова функции - эффективно, это null - поэтому значение this установлено на значение по умолчанию для глобального объекта (window в веб-браузерах, global в Node.js и т.д.).

Таким образом, вы на самом деле устанавливаете функцию this каждый раз, когда вы ее вызываете.

P.S. вызов steve.apply(null, []) эквивалентен вызову steve().

Ответ 3

Значение this не является тайной при вызове функции в зависимости от того, как она называется "нормально" (без call или apply):

func(); // `this` is the global object, or undefined in ES5 strict mode
obj.func(); // `this` is `obj`

Итак, чтобы избежать "изменения" значения this, просто передайте правильное значение apply, в зависимости от того, как вы бы назвали его "нормально":

func.apply(undefined, []); // global object, or undefined in ES5 strict mode
obj.func.apply(obj, []);

Ответ 4

Если вы вызываете только одну функцию, пройдите null.

func.apply(null, ['some', 'arguments']);

Если вы вызываете функцию, являющуюся методом объекта, передайте этот объект.

var arr = [];
arr.push.apply(arr, ['some', 'arguments']);

Чтобы соответствовать тому, как работает this,

Ответ 5

То, что вы хотите, не имеет большого смысла.

В стандарте ecmascript this определяется следующим образом:

11.1.1 Это ключевое слово. Это ключевое слово оценивает значение ThisBinding текущего исполнения контекст.

Это определение привязки для контекста выполнения функций задается следующим образом:

10.4.3 Ввод кода функции Следующие шаги выполняются, когда управление входит в контекст выполнения для кода функции, содержащегося в функциональный объект F, предоставленный вызывающий thisArg, и вызывающий Список аргументов:

  • Если код функции является строгим кодом, установите значение ThisBinding для thisArg.
  • Если значение thisArg равно null или undefined, установите значение ThisBinding для глобальный объект.
  • Если тип (thisArg) не является объектом, установите для параметра ThisBinding значение ToObject (thisArg).
  • Else задайте значение ThisBinding для этогоArg.
  • Пусть localEnv является результатом вызова NewDeclarativeEnvironment передавая значение [[Область]] внутреннее свойство F как аргумент.
  • Установите для LexicalEnvironment значение localEnv.
  • Задайте переменную окружения localEnv.
  • Пусть код является значением внутреннего свойства Fs [[Code]].
  • Выполнение обязательного связывания с использованием кода функции code и argumentList, как описано в 10.5.

Другими словами: либо вы указываете его, либо автоматически устанавливаете глобальный объект. Он никогда не будет наследовать эту привязку из его родительской области, поэтому единственный способ предоставить этому родительскому объекту thisBindiong родительской области - это либо

  • сохранить его в локальной переменной в родительской области, например var self = this
  • вводить его вызовом/применять как код, который вы указали в своем вопросе.