Почему «this» приводит к «Undefined» в методе [javascript] - PullRequest
2 голосов
/ 22 марта 2020

Я изучал поведение этих методов внутри объекта и застрял на одном выходе.

Вот код.

'use strict';

let obj, method;

obj = {
  go() { alert(this); }
};

obj.go();               // (1) [object Object]

(obj.go)();             // (2) [object Object]     QUESTION 2

(method = obj.go)();    // (3) undefined

(obj.go || obj.stop)(); // (4) undefined     ------> Doubt  <-------------------

Так что, если четвертый логически эквивалентен ко второму, почему логический ИЛИ приводит к потере контекста?

Часть-2

Пожалуйста, исправьте меня если я ошибаюсь.

  1. Оценка этого события происходит так, как он вызывается / вызывается с помощью объявления / выражения функции.

  2. Внутри функции стрелки this всегда ссылается на своего родительского элемента. [лексический охват]

Ответы [ 3 ]

1 голос
/ 22 марта 2020

На самом деле, # 3 и 4 возвращают [object Window]

См. Комментарии:

let obj, method;

obj = {
  go() { alert(this); }
};

obj.go();               // [object Object] represents obj

(obj.go)();             // [object Object] represents obj

(method = obj.go)();    // [object Window] because the go method is not running in the context of obj

(obj.go || obj.stop)(); //  Same as above
1 голос
/ 22 марта 2020

@ Pointy уже ответил на ваш вопрос. Просто для удовольствия: зная, что вы знаете сейчас, вы можете заставить свой метод obj.go запускаться в своей собственной области, заключая в выражение функции стрелки:

let obj, method, otherMethod, m2;

obj = {
  foo: `obj.foo here, saying: done`,
  go(txt = ``) { console.log(`obj.go here, called as: ${txt} => ${this.foo}`); }
};
(txt => obj.go(txt))(`(txt => obj.go(txt))([...])`);
(method = txt => obj.go(txt))(`(method = txt => obj.go(txt))([...])`);
(obj.go && 
  (txt => obj.go(txt)) || 
  obj.stop)(`(obj.go && txt => obj.go(txt) || obj.stop)([...])`);

// or use a wrapper (factory function)
const wrap = (...[obj, method, txtArg]) => () => obj[method](txtArg);
(otherMethod = wrap(obj, `go`, `(otherMethod = wrap(obj, \`go\`, \`[...]\`))()`))();

// or make `go` a getter and that getter a factory function
let otherObj = {
  foo: `and hithere, here's otherObj.foo`,
  get go() { return txt => 
    console.log( `otherObj.go here, called as: ${txt} => ${this.foo}` ); }
};

(m2 = otherObj.go)(`(m2 = otherObj.go)([...])`);
.as-console-wrapper { top: 0; max-height: 100% !important; }
0 голосов
/ 22 марта 2020

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

В случае 4, однако, оценка || в этих скобках приводит к тому, что эта связь будет потерял; остается только ссылка на функцию без какого-либо связанного объекта. Это потому, что logi c из || не заботится о том факте, что ссылка на функцию получена из поиска свойства объекта, поэтому ее результатом является просто ссылка на функцию "naked".

Что касается Ваши последующие вопросы, ни одно из утверждений не сформулировано правильно. Значение this зависит от того, как вызывается функция, но это не имеет никакого отношения к тому, откуда появилась функция или как она была объявлена. Внутри функций со стрелками значение this не является ссылкой на его лексический родительский элемент, оно совпадает со значением this в лексическом родительском элементе.

...