Function inside function javascript this

Ключевое слово this в javascript — учимся определять контекст на практике

По просьбам некоторых читателей решил написать топик про контекст в javascript. Новички javascript часто не понимают значение ключевого слова this в javascript. Данный топик будет интересен не только новичкам, а также тем, кто просто хочет освежить данный аспект в памяти. Посмотрите пример ниже. Если вы затрудняетесь ответить на вопрос «что будет выведено в логе» хотя бы в одном из пунктов или хотите просто посмотреть ответы — добро пожаловать под кат.

var f = function() < this.x = 5; (function() < this.x = 3; >)(); console.log(this.x); >; var obj = >; f(); new f(); obj.m(); new obj.m(); f.call(f); obj.m.call(f); 

1. Теория

В отличие от многих других языков программирования ключевое слово this в javascript не привязывается к объекту, а зависит от контекста вызова. Для упрощения понимания будем рассматривать примеры применительно к браузеру, где глобальным объектом является window.

1.1. Простой вызов функции

В данном случае this внутри функции f равен глобальному объекту (например, в браузере это window, в Node.js — global).

Самовызывающиеся функции (self-invoking) работают по точно такому же принципу.

1.2. В конструкторе
function f() < this.x = 5; console.log(this === window); // false >var o = new f(); console.log(o.x === 5); // true 

При вызове функции с использованием ключевого слова new функция выступает в роли конструктора, и в данном случе this указывает на создаваемый объект.

1.3. В методе объекта
var o = < f: function() < return this; >> console.log(o.f() === o); // true 

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

var o = < f: function() < return this; >> var o2 = ; console.log(o.f() === o);//true console.log(o2.f() === o2);//true 
1.4. Методы apply, call

Методы apply и call позволяют задать контекст для выполняемой функции. Разница между apply и call — только в способе передачи параметров в функцию. Первый параметр обеих функций определяет контекст выполнения функции (то, чему будет равен this).

function f(a,b,c) < return a * b + c; >f.call(f, 1, 2, 3); // аргументы перечисляются через запятую; var args = [1,2,3]; f.apply(f, args); // // аргументы передаются в виде массива; // В обоих случаях вызовется функция f с аргументами a = 1, b = 2, c = 3; 
function f() < >f.call(window); // this внутри функции f будет ссылаться на объект window f.call(f); //this внутри f будет ссылаться на f 
function f() < console.log(this.toString()); // 123 >f.call(123); // this внутри функции f будет ссылаться на объект Number со значением 123 

2. Разбираем задачу

Применим полученные знания к приведенной в начале топика задаче. Опять же для упрощения будем рассматривать примеры применительно к браузеру, где глобальным объектом является window.

Читайте также:  Php check running scripts
2.1. f()
var f = function() < // Функция f вызывается с помощью простого вызова - f(), // поэтому this ссылается на глобальный объект this.x = 5; // window.x = 5; // В пункте 1.1 также указано, что в самовызывающихся функциях this также ссылается на глобальный объект (function() < this.x = 3; // window.x = 3 >)(); console.log(this.x); // console.log(window.x) >; 
2.2. new f();
var f = function() < // Функция f вызывается с использованием ключевого слова new, // поэтому this ссылается на создаваемый объект (обозначим его как object) this.x = 5; // object.x = 5; // В пункте 1.1 также указано, что в самовызывающихся функциях this ссылается на глобальный объект (function() < this.x = 3; // window.x = 3 >)(); console.log(this.x); // console.log(object.x) >; 
2.3. obj.m();
2.4. new obj.m();
2.5. f.call(f);
var f = function() < // Функция f вызывается с помощью метода call // первым параметром в call указана сама функция (точнее объект) f, поэтому // поэтому this ссылается на f this.x = 5; // f.x = 5; // В пункте 1.1 также указано, что в самовызывающихся функциях this ссылается на глобальный объект (function() < this.x = 3; // window.x = 3 >)(); console.log(this.x); // console.log(f.x) >; 
2.6. obj.m.call(f);

Внимание: Если данный пример рассматривать отдельно от остальных, то в логе будет не 5, а undefined. Попробуйте внимательно разобрать пример и объяснить поведение

var f = function() < this.x = 5; (function() < this.x = 3; >)(); console.log(this.x); >; var obj = >; obj.m.call(f); 

Вместо заключения

В статье я постарался описать, как работает ключевое слово this в javascript. В ближайшее время я скорее всего напишу статью, в которой описывается для чего нужно знать эти тонкости (например, jQuery.proxy)

P.S. Если вы заметили ошибки/неточности или хотите что-то уточнить/добавить — напишите в ЛС, поправлю.

Источник

Function inside function javascript this

Last updated: Jan 8, 2023
Reading time · 3 min

banner

# Call a Function inside another Function in JavaScript

To call a function inside another function, define the inner function inside the outer function and invoke it.

When using the function keyword, the function gets hoisted to the top of the scope and can be called from anywhere inside the outer function.

Copied!
function outerFunc(a, b) function innerFunc(a, b) return a + b; > const result = innerFunc(a, b); return result; > console.log(outerFunc(10, 10)); // 👉️ 20 console.log(outerFunc(10, 20)); // 👉️ 30

The following example shows how we can call the inner function before it is declared.

This is because of how hoisting works in JavaScript.

Copied!
function outerFunc() const num1 = 5; const num2 = 10; // 👇️ call inner function before it's declared const result = innerFunc(); function innerFunc() return num1 + num2; > return result; > console.log(outerFunc()); // 👉️ 15

This only works for functions declared using the function keyword (not for arrow functions).

You can imagine that the declaration of the function gets hoisted to the top of the scope, so it can be called from anywhere in the scope.

# Returning the inner function from the outer function

An alternative approach is to return the inner function from the outer one.

Copied!
function outerFunc() function innerFunc(a, b) return a + b; > return innerFunc; > const innerFunc = outerFunc(); console.log(innerFunc(2, 3)); // 👉️ 5 console.log(innerFunc(3, 3)); // 👉️ 6

Notice that we didn’t use parentheses () to invoke the inner function inside the outer one.

We returned the function without invoking it. In other words, we returned a reference to the inner function, not the result of calling it.

This allows us to invoke the inner function as many times as necessary, passing it different arguments every time.

# Inner function remembers variables declared in the outer function

What’s most useful in this scenario is that the inner function remembers the variables declared in the outer function between invocations.

Copied!
function outerFunc() const z = 100; function innerFunc(a, b) return a + b + z; > return innerFunc; > const innerFunc = outerFunc(); console.log(innerFunc(2, 3)); // 👉️ 105 console.log(innerFunc(3, 3)); // 👉️ 106

Notice that the inner function remembers the value of the z variable between invocations.

This concept is called a closure in JavaScript.

The inner function gets bundled with references to its surrounding state.

This means that the inner function has access to the variables declared inside of the outer function’s scope at any time.

This is useful in many different scenarios. For example, you could pass a parameter to the outer function that it will remember for any of the inner function calls.

Copied!
function outerFunc(a) function innerFunc(b, c) return a + b + c; > return innerFunc; > const innerFunc = outerFunc(10); console.log(innerFunc(1, 1)); // 12 console.log(innerFunc(1, 2)); // 13

We passed 10 as a parameter to the outer function and stored the result in a variable.

The innerFunc variable stores a reference to the innerFunc function where the a variable points to a value of 10 .

Now we can omit 10 from the parameters when calling the inner function.

# Returning an object from the outer function

You can also return an object from the outer function.

Copied!
function outerFunc() function innerFunc(a, b) return a + b; > return innerFunc>; > const outer = outerFunc(); console.log(outer.innerFunc(10, 10)); // 20 console.log(outer.innerFunc(20, 15)); // 35

The object contains a single property — the inner function.

You can call the inner function by accessing the property on the object.

I’ve written a detailed article on how to call a function in an object.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.

Источник

JavaScript this

In JavaScript, this keyword refers to the object where it is called.

1. this Inside Global Scope

When this is used alone, this refers to the global object ( window object in browsers). For example,

let a = this; console.log(a); // Window <> this.name = 'Sarah'; console.log(window.name); // Sarah

Here, this.name is the same as window.name .

2. this Inside Function

When this is used in a function, this refers to the global object ( window object in browsers). For example,

function greet() < // this inside function // this refers to the global object console.log(this); >greet(); // Window <>

3. this Inside Constructor Function

In JavaScript, constructor functions are used to create objects. When a function is used as a constructor function, this refers to the object inside which it is used. For example,

function Person() < this.name = 'Jack'; console.log(this); >let person1 = new Person(); console.log(person1.name);

Here, this refers to the person1 object. That’s why, person1.name gives us Jack .

Note: When this is used with ES6 classes, it refers to the object inside which it is used (similar to constructor functions).

4. this Inside Object Method

When this is used inside an object’s method, this refers to the object it lies within. For example,

const person = < name : 'Jack', age: 25, // this inside method // this refers to the object itself greet() < console.log(this); console.log(this.name); >> person.greet();

In the above example, this refers to the person object.

5. this Inside Inner Function

When you access this inside an inner function (inside a method), this refers to the global object. For example,

const person = < name : 'Jack', age: 25, // this inside method // this refers to the object itself greet() < console.log(this); // console.log(this.age); // 25 // inner function function innerFunc() < // this refers to the global object console.log(this); // Window < . >console.log(this.age); // undefined > innerFunc(); > > person.greet();

Here, this inside innerFunc() refers to the global object because innerFunc() is inside a method.

However, this.age outside innerFunc() refers to the person object.

6. this Inside Arrow Function

Inside the arrow function, this refers to the parent scope. For example,

const greet = () => < console.log(this); >greet(); // Window

Arrow functions do not have their own this . When you use this inside an arrow function, this refers to its parent scope object. For example,

const greet = < name: 'Jack', // method sayHi () < let hi = () =>console.log(this.name); hi(); > > greet.sayHi(); // Jack

Here, this.name inside the hi() function refers to the greet object.

You can also use the arrow function to solve the issue of having undefined when using a function inside a method (as seen in Example 5). For example,

const person = < name : 'Jack', age: 25, // this inside method // this refers to the object itself greet() < console.log(this); console.log(this.age); // inner function let innerFunc = () => < // this refers to the global object console.log(this); console.log(this.age); >innerFunc(); > > person.greet();

Here, innerFunc() is defined using the arrow function. It takes this from its parent scope. Hence, this.age gives 25.

When the arrow function is used with this , it refers to the outer scope.

7. this Inside Function with Strict Mode

When this is used in a function with strict mode, this is undefined . For example,

'use strict'; this.name = 'Jack'; function greet() < // this refers to undefined console.log(this); >greet(); // undefined

Note: When using this inside a function with strict mode, you can use JavaScript Function call().

'use strict'; this.name = 'Jack'; function greet() < console.log(this.name); >greet.call(this); // Jack

When you pass this with the call() function, greet() is treated as the method of the this object (global object in this case).

Table of Contents

Источник

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