Здесь я собираюсь рассказать, как ключевое слово this играет роль в javascript. Я потратил довольно много времени, чтобы прочитать и понять это из различных ресурсов, включая одну из самых известных книг всех времен о js.
Итак, прежде всего, что такое "это"?
Когда мы создаем и выполняем функцию, JS привязывает новое свойство к функции с именем «this». Мы также можем сказать, что «this» — это контекст выполнения функции в данный момент времени. Значение, связанное с «this», определяется местом вызова этой функции. Call-Site относится к тому, как вызывается функция.
function animal(){ console.log(this.name) } var name = "Cow"; animal(); // Cow
Вы можете подумать о том, как переменная «name» связана с «this.name», когда мы вызываем функцию животного. Как сказано выше, сайт вызова функции animal по умолчанию является объектом окна. Таким образом, «this» внутри функции animal будет привязана к объекту окна, где мы объявили нашу переменную «name».
Значение, привязанное к «this», определяется следующими правилами:
1. Привязка по умолчанию (указанная выше)
2. Неявная привязка
3. Явная привязка
4. новая привязка
Неявное связывание:
function eat(){ console.log(this.name + " is eating "+ this.food); } var animal = { name : "cow", food : "grass", eat : eat } animal.eat() // cow is eating grass
Здесь мы присвоили ссылку функции eat свойству eat объекта animal . Таким образом, когда мы вызываем функцию с точечной нотацией, "this" вызываемой функции будет привязана к вызывающему объекту. В нашем случае, Функция eat«this» связана с объектом животное.
Явная привязка:
Допустим, у нас есть объект alien с тем же свойством, что и у объекта animal, но мы не хотим дублировать тот же метод eat в инопланетный объект. В этом случае мы можем позаимствовать метод съесть для инопланетного объекта.
function eat(){ console.log(this.name + " is eating "+ this.food); } var alien = { name : "xxx", food : "bla bla" } //reuse the eat method to alien object eat.call(alien) // xxx is eating bla bla
Вы можете узнать больше о том, как заимствовать функцию, здесь.
Здесь мы явно устанавливаем this в методе eat, чтобы указать на чужой объект с помощью служебного метода, доступного в функции, вызов.
новая привязка:
Допустим, у нас есть животноводческая ферма, на которой выращиваются разные виды животных.
function eat(){ console.log(this.name + " is eating "+ this.food); } function Animal(name, food){ this.name = name; this.food = food; this.eat = eat; } var cow = new Animal("Cow","grass"); cow.eat(); //Cow is eating grass var tiger = new Animal("Tiger","meat"); tiger.eat(); //Tiger is eating meat
Следующие вещи происходят неявно, когда мы вызываем new functionName().
1. функция создает простой новый объект
2. и связывает вновь созданный объект с объектом-прототипом вызываемой функции
3. Затем вновь созданный объект привязывается к «this» этой вызываемой функции
4. и возвращает вновь созданный объект, если для этой вызываемой функции нет возвращаемого значения по умолчанию
с помощью этих правил мы можем переписать функцию Animal для создания разных видов животных без использования ключевого слова new.
function eat(){ console.log(this.name + " is eating "+ this.food); } function Animal(name, food){ var newObj = {}; // step 1 Object.setPrototypeOf(newObj, Animal.prototype); // step 2 newObj.name = name; // step 3 newObj.food = food; newObj.eat = eat; return newObj; // step 4 } var cow = Animal("Cow","grass"); cow.eat(); var tiger = Animal("Tiger","meat"); tiger.eat(); console.log(cow instanceof Animal)// true
теперь мы знаем, как «this» связывается с функцией, когда мы вызываем функцию с ключевым словом «new».
Это четыре правила, определяющие значение, которое будет привязано к «this» при вызове функции.
ПРИМЕЧАНИЕ.
Это моя первая статья в JS о моем понимании ключевого слова "this".
возможно, я что-то упустил здесь о "это ». Пожалуйста, не стесняйтесь исправлять меня, оставляя комментарии.