Комплетан водич за ово у ЈаваСцрипт-у

У ЈаваСцрипт-у свака функција има thisреференцу која се аутоматски креира када је пријавите.

ЈаваСцрипт thisје прилично сличан thisреференци у другим језицима заснованим на класама, као што су Јава или Ц # (ЈаваСцрипт је језик заснован на прототипу и нема концепт „класе“): Указује на то који објекат позива функцију (овај објекат се понекад назива као контекст ). У ЈаваСцрипт, међутим, референца унутар функције могу бити везани за различите објекте у зависности од тога где је функција се зове .this

Ево 5 основних правила за thisвезивање у ЈаваСцрипт-у:

Правило 1

Када се функција позове у глобалном опсегу, thisреференца је подразумевано везана за глобални објекат ( windowу прегледачу или globalу Ноде.јс). На пример:

function foo() { this.a = 2; } foo(); console.log(a); // 2

Напомена: Ако foo()горњу функцију декларишете у строгом режиму, тада ову функцију позивате у глобалном опсегу, thisбиће undefinedи додељивање this.a = 2ће избацити Uncaught TypeErrorизузетак.

Правило 2

Погледајмо пример у наставку:

function foo() { this.a = 2; } const obj = { foo: foo }; obj.foo(); console.log(obj.a); // 2

Јасно је да се у горњем исечку foo()функција позива са цонтект ис objобјецт и thisреференца је сада везана за obj. Дакле, када се функција позове са објектом контекста, thisреференца ће бити везана за овај објекат.

Правило 3

.call, .applyи .bindсви се могу користити на локацији позива за изричито везивање this. Коришћење .bind(this)је нешто што ћете можда видети у доста Реацт компоненти.

const foo = function() { console.log(this.bar) } foo.call({ bar: 1 }) // 1

Ево кратког примера како се сваки користи за везивање this:

  • .call(): fn.call(thisObj, fnParam1, fnParam2)
  • .apply(): fn.apply(thisObj, [fnParam1, fnParam2])
  • .bind(): const newFn = fn.bind(thisObj, fnParam1, fnParam2)

Правило 4

function Point2D(x, y) { this.x = x; this.y = y; } const p1 = new Point2D(1, 2); console.log(p1.x); // 1 console.log(p1.y); // 2

Оно што морате приметити је Point2Dфункција која се позива помоћу newкључне речи, а thisреференца је везана за p1објекат. Дакле, када се функција позове са newкључном речи, она ће створити нови објекат и thisреференца ће бити везана за овај објекат.

Напомена: Док позивате функцију са newкључном речи, ми је називамо и функцијом конструктора .

Правило 5

ЈаваСцрипт одређује вредност thisтоком извршавања, на основу тренутног контекста. Тако thisда понекад може да укаже на нешто друго осим онога што очекујете.

Размотрите овај пример класе Цат са позваном методом makeSound(), следећи образац из правила 4 (горе) са функцијом конструктора и newкључном речи.

const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.makeSound(); // Fat Daddy says: Mrrooowww

Покушајмо сада да пружимо мачки пут annoy()људима понављањем његовог звука 100 пута, једном у пола секунде.

const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; this.annoy = function() { let count = 0, max = 100; const t = setInterval(function() { this.makeSound(); // <-- this line fails with `this.makeSound is not a function` count++; if (count === max) { clearTimeout(t); } }, 500); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.annoy();

То не функционише, јер смо унутар setIntervalповратног позива креирали нови контекст са глобалним опсегом, тако да thisвише не показује на нашу мачју инстанцу. У веб прегледачу thisће уместо тога показати на објект Виндов, који нема makeSound()метод.

Неколико начина да то функционише:

  1. Пре креирања новог контекста, доделите thisлокалној променљивој са именом meили self, или како год желите да је позовете, и користите ту променљиву унутар повратног позива.
const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; this.annoy = function() { let count = 0, max = 100; const self = this; const t = setInterval(function() { self.makeSound(); count++; if (count === max) { clearTimeout(t); } }, 500); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.annoy();
  1. Са ЕС6 можете избећи додељивање thisлокалној променљивој помоћу функције стрелице која се везује thisза контекст околног кода тамо где је дефинисана.
const Cat = function(name, sound) { this.name = name; this.sound = sound; this.makeSound = function() { console.log( this.name + ' says: ' + this.sound ); }; this.annoy = function() { let count = 0, max = 100; const t = setInterval(() => { this.makeSound(); count++; if (count === max) { clearTimeout(t); } }, 500); }; } const kitty = new Cat('Fat Daddy', 'Mrrooowww'); kitty.annoy();