Встановити "цю" змінну легко?


139

Я дуже добре розумію 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 є варіантом ... але це не сенс цього питання.

Дякую.

Відповіді:


221

Існують два методи, визначені для всіх функцій у JavaScript call(), та apply(). Синтаксис функції виглядає так:

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

Те , що ці функції роблять це виклик функції вони викликаються на, привласнюючи значення об'єкта параметра цього .

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

3
Крім того, якщо ви використовуєте jQuery, ви можете використовувати $.proxy(function, element)так, що коли ця функція буде викликана, вона буде в контексті елемента. api.jquery.com/jquery.proxy
Тревін Евері

Ще один корисний метод.bind()
Soroush Falahati

55

Я думаю, ти шукаєш call:

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

Це дзвінки myFunctionіз thisвстановленим на obj.

Існує також дещо інший метод apply, який приймає параметри функції як масив:

myFunction.apply(obj, [arg1, arg2, ...]);

1
Дивіться розділи 15.3.4.3, 15.3.4.4 та 10.1.8 у специфікації мови ECMAScript: ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf
десь

18

Якщо ви хочете "зберегти" thisзначення функції, щоб потім ви могли легко її зателефонувати пізніше (наприклад, коли у вас більше немає доступу до цього значення), ви можете bindце зробити (доступно не у всіх браузерах):

var bound = func.bind(someThisValue);

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

bound(); // will call with someThisValue as 'this'

7
FYI bind, очевидно, доступний в IE9 +, FF4 +, Safari 5.1.4+ та Chrome 7+ (джерело) . Ви також можете зателефонувати прив’язати безпосередньо до анонімної функції:var myFunction = function(){ /* this = something */ }.bind(something);
Адам,

1

Мій пошук, як пов’язати, 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();

0

Встановлення 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');

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.