This val in javascript

Методы объекта, «this»

Объекты обычно создаются, чтобы представлять сущности реального мира, будь то пользователи, заказы и так далее:

// Объект пользователя let user = < name: "John", age: 30 >;

И так же, как и в реальном мире, пользователь может совершать действия: выбирать что-то из корзины покупок, авторизовываться, выходить из системы, оплачивать и т.п.

Такие действия в JavaScript представлены функциями в свойствах.

Примеры методов

Для начала давайте научим нашего пользователя user здороваться:

let user = < name: "John", age: 30 >; user.sayHi = function() < alert("Привет!"); >; user.sayHi(); // Привет!

Здесь мы просто использовали Function Expression (функциональное выражение), чтобы создать функцию приветствия, и присвоили её свойству user.sayHi нашего объекта.

Затем мы можем вызвать ee как user.sayHi() . Теперь пользователь может говорить!

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

Итак, мы получили метод sayHi объекта user .

Конечно, мы могли бы использовать заранее объявленную функцию в качестве метода, вот так:

let user = < // . >; // сначала, объявляем function sayHi() < alert("Привет!"); >// затем добавляем в качестве метода user.sayHi = sayHi; user.sayHi(); // Привет!

Когда мы пишем наш код, используя объекты для представления сущностей реального мира, – это называется объектно-ориентированным программированием или сокращённо: «ООП».

ООП является большой предметной областью и интересной наукой самой по себе. Как выбрать правильные сущности? Как организовать взаимодействие между ними? Это – создание архитектуры, и на эту тему есть отличные книги, такие как «Приёмы объектно-ориентированного проектирования. Паттерны проектирования» авторов Эрих Гамма, Ричард Хелм, Ральф Джонсон, Джон Влиссидес или «Объектно-ориентированный анализ и проектирование с примерами приложений» Гради Буча, а также ещё множество других книг.

Сокращённая запись метода

Существует более короткий синтаксис для методов в литерале объекта:

// эти объекты делают одно и то же user = < sayHi: function() < alert("Привет"); >>; // сокращённая запись выглядит лучше, не так ли? user = < sayHi() < // то же самое, что и "sayHi: function()" alert("Привет"); > >;

Как было показано, мы можем пропустить ключевое слово «function» и просто написать sayHi() .

Нужно отметить, что эти две записи не полностью эквивалентны. Есть тонкие различия, связанные с наследованием объектов (что будет рассмотрено позже), но на данном этапе изучения это неважно. Почти во всех случаях сокращённый синтаксис предпочтителен.

Ключевое слово «this» в методах

Как правило, методу объекта обычно требуется доступ к информации, хранящейся в объекте, для выполнения своей работы.

Например, коду внутри user.sayHi() может потребоваться имя пользователя, которое хранится в объекте user .

Для доступа к информации внутри объекта метод может использовать ключевое слово this .

Значение this – это объект «перед точкой», который используется для вызова метода.

let user = < name: "John", age: 30, sayHi() < // "this" - это "текущий объект". alert(this.name); >>; user.sayHi(); // John

Здесь во время выполнения кода user.sayHi() значением this будет являться user (ссылка на объект user ).

Читайте также:  Import CSV File into MySQL using PHP

Технически также возможно получить доступ к объекту без ключевого слова this , обратившись к нему через внешнюю переменную (в которой хранится ссылка на этот объект):

…Но такой код ненадёжен. Если мы решим скопировать ссылку на объект user в другую переменную, например, admin = user , и перезапишем переменную user чем-то другим, тогда будет осуществлён доступ к неправильному объекту при вызове метода из admin .

let user = < name: "John", age: 30, sayHi() < alert( user.name ); // приведёт к ошибке >>; let admin = user; user = null; // перезапишем переменную для наглядности, теперь она не хранит ссылку на объект. admin.sayHi(); // TypeError: Cannot read property 'name' of null

Если бы мы использовали this.name вместо user.name внутри alert , тогда этот код бы сработал.

«this» не является фиксированным

В JavaScript ключевое слово «this» ведёт себя иначе, чем в большинстве других языков программирования. Его можно использовать в любой функции, даже если это не метод объекта.

В следующем примере нет синтаксической ошибки:

Значение this вычисляется во время выполнения кода, в зависимости от контекста.

Например, здесь одна и та же функция назначена двум разным объектам и имеет различное значение «this» в вызовах:

let user = < name: "John" >; let admin = < name: "Admin" >; function sayHi() < alert( this.name ); >// используем одну и ту же функцию в двух объектах user.f = sayHi; admin.f = sayHi; // эти вызовы имеют разное значение this // "this" внутри функции - это объект "перед точкой" user.f(); // John (this == user) admin.f(); // Admin (this == admin) admin['f'](); // Admin (нет разницы между использованием точки или квадратных скобок для доступа к объекту)

Правило простое: если вызывается obj.f() , то во время вызова f , this – это obj . Так что, в приведённом выше примере это либо user , либо admin .

Мы даже можем вызвать функцию вообще без объекта:

function sayHi() < alert(this); >sayHi(); // undefined

В строгом режиме ( «use strict» ) в таком коде значением this будет являться undefined . Если мы попытаемся получить доступ к this.name – это вызовет ошибку.

В нестрогом режиме значением this в таком случае будет глобальный объект ( window в браузерe, мы вернёмся к этому позже в главе Глобальный объект). Это – исторически сложившееся поведение this , которое исправляется использованием строгого режима ( «use strict» ).

Обычно подобный вызов является ошибкой программирования. Если внутри функции используется this , тогда она ожидает, что будет вызвана в контексте какого-либо объекта.

Если вы до этого изучали другие языки программирования, то вы, вероятно, привыкли к идее «фиксированного this » – когда методы, определённые в объекте, всегда имеют this , ссылающееся на этот объект.

В JavaScript this является «свободным», его значение вычисляется в момент вызова метода и не зависит от того, где этот метод был объявлен, а скорее от того, какой объект вызывает метод (какой объект стоит «перед точкой»).

Читайте также:  Html css черный фон

Эта концепция вычисления this в момент исполнения имеет как свои плюсы, так и минусы. С одной стороны, функция может быть повторно использована в качестве метода у различных объектов (что повышает гибкость). С другой стороны, большая гибкость увеличивает вероятность ошибок.

Здесь наша позиция заключается не в том, чтобы судить, является ли это архитектурное решение в языке хорошим или плохим. Скоро мы поймем, как с этим работать, как получить выгоду и избежать проблем.

У стрелочных функций нет «this»

Стрелочные функции особенные: у них нет своего «собственного» this . Если мы ссылаемся на this внутри такой функции, то оно берётся из внешней «нормальной» функции.

Например, здесь arrow() использует значение this из внешнего метода user.sayHi() :

let user = < firstName: "Ilya", sayHi() < let arrow = () =>alert(this.firstName); arrow(); > >; user.sayHi(); // Ilya

Это особенность стрелочных функций. Она полезна, когда мы на самом деле не хотим иметь отдельное this , а скорее хотим взять его из внешнего контекста. Позже в главе Повторяем стрелочные функции мы увидим больше примеров на эту тему.

Итого

  • Функции, которые находятся в свойствах объекта, называются «методами».
  • Методы позволяют объектам «действовать»: object.doSomething() .
  • Методы могут ссылаться на объект через this .

Значение this определяется во время исполнения кода.

  • При объявлении любой функции в ней можно использовать this , но этот this не имеет значения до тех пор, пока функция не будет вызвана.
  • Функция может быть скопирована между объектами (из одного объекта в другой).
  • Когда функция вызывается синтаксисом «метода» – object.method() , значением this во время вызова является object .

Также ещё раз заметим, что стрелочные функции являются особенными – у них нет this . Когда внутри стрелочной функции обращаются к this , то его значение берётся извне.

Задачи

Использование «this» в литерале объекта

Здесь функция makeUser возвращает объект.

Каким будет результат при обращении к свойству объекта ref ? Почему?

function makeUser() < return < name: "John", ref: this >; > let user = makeUser(); alert( user.ref.name ); // Каким будет результат?

Ответ: ошибка.

function makeUser() < return < name: "John", ref: this >; > let user = makeUser(); alert( user.ref.name ); // Error: Cannot read property 'name' of undefined

Это потому, что правила, которые определяют значение this , никак не смотрят на объявление объекта. Важен лишь момент вызова.

Здесь значение this внутри makeUser() равно undefined , потому что оно вызывается как функция, а не через «точечный» синтаксис как метод.

Значение this одно для всей функции, блоки кода и объектные литералы на него не влияют.

Таким образом, ref: this фактически принимает текущее this функции makeUser() .

Мы можем переписать функцию и вернуть то же самое this со значением undefined :

function makeUser() < return this; // на этот раз нет литерала объекта >alert( makeUser().name ); // Error: Cannot read property 'name' of undefined

Как вы можете видеть, результат alert( makeUser().name ) совпадает с результатом alert( user.ref.name ) из предыдущего примера.

Вот противоположный случай:

function makeUser() < return < name: "John", ref() < return this; >>; > let user = makeUser(); alert( user.ref().name ); // John

Теперь это работает, поскольку user.ref() – это метод. И значением this становится объект перед точкой . .

Читайте также:  Python for if else one line

Источник

This in JavaScript

this” in JavaScript is an object. Every JavaScript function gets a copy of this (except arrow functions). Its value does not depend on where we declare it but on how we invoke it. There are four ways in which we can invoke a function. They are Function invocation, method invocation, Constructor invocation & Explicit invocation. Each of these invocations sets the value of this differently. This tutorial will dive deep into this in JavaScript and learn more about it.

  • What is “this” in Javascript
  • Why “this” in JavaScript is so Confusing
  • This outside a function
  • How to identify this in Javascript
  • Function Invocation or Default Binding
  • Method Invocation (Implicit Binding)
    • Inner function looses this binding
    • Workaround for the inner function
    • Separate method from the object
    • Call
    • Apply
    • Bind
    • Primitive Values & Explicit binding
    • Passing null or undefined to bind, call & apply
    • Arrow functions

    What is “this” in Javascript

    Take a look at the following person object. It contains the method sayHello . How do we get to the person’s name from within sayHello ?

    We use “this” keyword to access the person object.

    Inside the sayHello function, the this keyword refers to the person object. Using this keyword, we can refer to all properties and methods of the person object inside the sayHello function.

    We say this is bound to the person object inside the sayHello function.

    this is an object to which function is bound to in the run time. The run-time binding of a function can change depending on how we invoke it. If there is no binding is found, then it defaults to the global object in nonstrict mode and undefined in strict mode.

    Why “this” in JavaScript is so Confusing

    In languages like c#, java, etc., this always points to the current class instance to which the method belongs. This is very intuitive and easy to grasp. The methods are bound to the class. You cannot change those bindings.

    But there is one critical difference between functions in JavaScript and those in c# or Java. In JavaScript, functions are objects. They are not bound to anything. So, you can assign them to another variable, pass them around, etc.

    For example, look at the following example.

    The obj object declares the foo function and becomes the obj ‘s method. When we invoke the foo function using obj.foo() , it prints the value of a (i.e., 10 ) from the obj and not from the global value of a . Here this inside the foo points to the obj itself. This is precisely how this works in C# & Java.

    Источник

Оцените статью