Чтобы освоить этот момент в JS, вам нужно всего лишь запомнить 5 принципов

JavaScript
Чтобы освоить этот момент в JS, вам нужно всего лишь запомнить 5 принципов

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


Мы все видели это в функциях по-разному, но до сих пор не можем точно определить, к кому это относится в JavaScript, эта статья даст вам полное представление об этом.

5 больших правил

(1) Если новое ключевое слово появляется перед вызываемой функцией, механизм JavaScript создаст новый объект, и это в вызываемой функции указывает на вновь созданную функцию.

function ConstructorExample() {
    console.log(this);
    this.value = 10;
    console.log(this);
}

new ConstructorExample();

// -> ConstructorExample {}
// -> ConstructorExample { value: 10 }

(2) Если функция запускается с помощью применения, вызова или привязки, то this в функции указывает на первый параметр входящей функции.

function fn() {
    console.log(this);
}

var obj = {
    value: 5
};

var boundFn = fn.bind(obj);

boundFn(); // -> { value: 5 }
fn.call(obj); // -> { value: 5 }
fn.apply(obj); // -> { value: 5 }

(3) Если функция является методом объекта, и объект использует точку для запуска функции, то this указывает на объект, функция которого является свойством этого объекта, то есть this указывает на объект слева периода.

var obj = {
    value: 5,
    printThis: function() {
      console.log(this);
    }
};

obj.printThis(); // -> { value: 5, printThis: ƒ }

(4) Если функция вызывается как FFI, это означает, что функция не соответствует ни одному из вышеперечисленных методов вызова, и это указывает на глобальный объект, которым является окно в браузере.

var obj = {
    value: 5,
    printThis: function() {
      console.log(this);
    }
};

obj.printThis(); // -> { value: 5, printThis: ƒ }

Обратите внимание, что правило 4 очень похоже на правило 3, за исключением того, что когда функция вызывается не как метод, она автоматически неявно программирует свойство глобального объекта — окна. То есть, когда мы вызываем fn(), это можно понимать как window.fn() Согласно третьему правилу this в функции fn() указывает на окно.

var obj = {
    value: 5,
    printThis: function() {
      console.log(this);
    }
};

obj.printThis(); // -> { value: 5, printThis: ƒ }

(5) Если вышеуказанные правила накапливаются, приоритет уменьшается с 1 до 4, и балл этого оценивается в соответствии с правилом с наивысшим приоритетом.

Применяйте правила на практике

Взгляните на пример кода и используйте приведенные выше правила, чтобы определить, на что это указывает.

var obj = {
    value: 'hi',
    printThis: function() {
        console.log(this);
    }
};

var print = obj.printThis;

obj.printThis(); // -> {value: "hi", printThis: ƒ}
print(); // -> Window {stop: ƒ, open: ƒ, alert: ƒ, ...}

obj.prinThis() , согласно третьему правилу это указывает на obj. Согласно четвертому правилу print() — это FFI, так что это указывает на window.

Фактически, приведенный выше пример также исследует разницу между вашим значением и ссылкой в ​​JavaScript, вы можете прочитать эту статью:

Примитивные значения против эталонных значений в JavaScript.

Метод printThis в объекте obj на самом деле является ссылкой на адрес функции, когда мы присваиваем obj.printThis для печати, print также содержит ссылку на функцию, которая не имеет ничего общего с объектом obj. obj — это просто свойство, которое имеет ссылку на эту функцию.

Когда функция не запускается объектом obj, эта функция является FFI.

Применить несколько правил

При наличии нескольких вышеуказанных правил "выигрывает" правило с более высоким приоритетом. Если правило 2 и правило 3 существуют одновременно, правило 2 имеет приоритет:

var obj1 = {
    value: 'hi',
    print: function() {
        console.log(this);
    },
};

var obj2 = { value: 17 };

obj1.print.call(obj2); // -> { value: 17 }

Если Правило 1 и Правило 3 применяются одновременно, Правило 1 имеет приоритет:

var obj1 = {
    value: 'hi',
    print: function() {
        console.log(this);
    },
};

new obj1.print(); // -> print {}

Библиотека указана в коде?

Некоторые библиотеки привязывают этот указатель к более полезному объекту, например библиотека jQuery, в обработчиках событий этот указатель не привязывается к глобальному объекту, а привязывается к объекту элемента. Поэтому, если вы обнаружите что-то, что не может быть объяснено вышеуказанными 5 правилами, пожалуйста, прочитайте официальную документацию библиотеки, которую вы используете, чтобы узнать, как библиотека изменяет этот момент, обычно через метод привязки.