Установить переменную "this" легко? - PullRequest
135 голосов
/ 19 января 2009

Я довольно хорошо понимаю Javascript, за исключением того, что не могу найти хороший способ установить переменную "this". Рассмотрим:

var myFunction = function(){
    alert(this.foo_variable);
}

var someObj = document.body; //using body as example object
someObj.foo_variable = "hi"; //set foo_variable so it alerts

var old_fn = someObj.fn;   //store old value
someObj.fn = myFunction;   //bind to someObj so "this" keyword works
someObj.fn();              
someObj.fn = old_fn;       //restore old value

Есть ли способ сделать это без последних 4 строк? Это довольно раздражает ... Я пытался связать анонимную функцию, которая, на мой взгляд, была красивой и умной, но безрезультатно:

var myFunction = function(){
    alert(this.foo_variable);
}

var someObj = document.body;        //using body as example object
someObj.foo_variable = "hi";        //set foo_variable so it alerts
someObj.(function(){ fn(); })();    //fail.

Очевидно, что передача переменной в myFunction - это вариант ... но не в этом вопрос.

Спасибо.

Ответы [ 5 ]

216 голосов
/ 19 января 2009

Для всех функций в JavaScript определены два метода: call() и apply(). Синтаксис функции выглядит так:

call( /* object */, /* arguments... */ );
apply(/* object */, /* arguments[] */);

То, что делают эти функции, вызывает функцию, к которой они были вызваны, присваивая значение параметра object для this .

var myFunction = function(){
    alert(this.foo_variable);
}
myFunction.call( document.body );
54 голосов
/ 19 января 2009

Я думаю, что вы ищете call:

myFunction.call(obj, arg1, arg2, ...);

Это вызывает myFunction с this, установленным на obj.

Существует также немного другой метод apply, который принимает параметры функции в виде массива:

myFunction.apply(obj, [arg1, arg2, ...]);
18 голосов
/ 08 июля 2011

Если вы хотите «сохранить» значение this для функции, чтобы вы могли без проблем вызвать его позже (например, когда у вас больше нет доступа к этому значению), вы можете bind его (не доступно) хотя во всех браузерах):

var bound = func.bind(someThisValue);

// ... later on, where someThisValue is not available anymore

bound(); // will call with someThisValue as 'this'
0 голосов
/ 07 декабря 2018

Установка ключевого слова this в javascript.

Javascript имеет 3 встроенных метода для удобной установки ключевого слова this. Все они расположены на объекте Function.prototype, поэтому каждая функция может использовать их (поскольку каждая функция наследуется от этого прототипа через наследование прототипа). Эти функции следующие:

  1. Function.prototype.call(): эта функция принимает объект, который вы хотите использовать, в качестве this в качестве первого аргумента. Тогда остальные аргументы являются соответствующими аргументами вызываемой функции.
  2. Function.prototype.apply(): эта функция принимает объект, который вы хотите использовать, в качестве this в качестве первого аргумента. Тогда второй аргумент является массивом, который содержит значения аргументов вызываемой функции (первый элемент массива является первым аргументом функции, второй аргумент массива является вторым аргументом функции и т. Д.).
  3. Function.prototype.bind(): эта функция возвращает новую функцию с другим значением, равным this. В качестве первого аргумента он принимает объект, который вы хотите установить в качестве значения this, а затем возвращает новый функциональный объект.

Разница между вызовом / применением и связыванием:

  • call и apply схожи в том, что они немедленно вызывают функцию (с предопределенным значением this)
  • bind отличается от call и apply тем, что эта функция возвращает новую функцию с другой привязкой значения this.

Примеры:

const thisObj = {
  prop1: 1,
  prop2: 2,
};

function myFunc(arg1, arg2) {
  console.log(this.prop1, this.prop2);
  console.log(arg1, arg2);
}

// first arg this obj, other arguments are the  
// respective arguments of the function
myFunc.call(thisObj, 'Call_arg1', 'Call_arg2');

// first arg this obj, other argument is an array which  
// are the respective arguments of the function
myFunc.apply(thisObj, ['Apply_arg1', 'Apply_arg2']);


// the bind method returns a new function with a different
// this context which is stored in the newMyFunc variable
const newMyFunc = myFunc.bind(thisObj);

// now we can call the function like a normal function 
newMyFunc('first', 'second');
0 голосов
/ 14 октября 2016

Мой поиск о том, как связывать this, привел меня сюда, поэтому я публикую свои выводы: в 'ECMAScript 2015' мы также можем установить это лексически, используя функции стрелок, для.

См .: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Вместо:

function Person() {
  setInterval(function growUp() {
    // The callback refers to the `self` variable of which
    // the value is the expected object.
    this.age++;
  }.bind(this), 1000);
}

Теперь мы можем сделать:

function Person(){
  this.age = 0;

  setInterval(() => {
    this.age++; // |this| properly refers to the person object
  }, 1000);
}

var p = new Person();
...