В JavaScript зачем передавать контекст в качестве аргумента в вызов функции, если контекст уже определен тем, кто его вызывает? - PullRequest
0 голосов
/ 14 февраля 2020

A прочитайте статью на Medium под названием

Вы должны понимать эти 14 JavaScript функций от bitfi sh

В статье автор пишет о функциях JavaScript разработчик должен знать или понимать, когда / до собеседования - для должности JavaScript разработчика.

В примерах постоянно используется передача контекста в качестве необязательного аргумента. К сожалению, автор не go подробно описывает, почему мы передаем аргумент контекста, как здесь:

mappedArr[i] = fn.call(context, arr[i], i, this); 

Мой вопрос: «В JavaScript, зачем передавать контекст в качестве аргумента при вызове функции когда контекст уже определен тем, кто его называет?

При каких условиях полезно иметь этот контекст доступным (другой контекст)?

Ниже приведен код, приведенный ниже:

let selfMap = function(fn, context) {

   let arr = Array.prototype.slice.call(this);
   let mappedArr = Array();
   for(let i=0; i < arr.length; i++) {

     if (! arr.hasOwnProperty(i)) continue;

     let info = [];
     info.push({ "context" : context } );
     info.push({ "arr[i]" : arr[i] } );
     info.push({ "i" : i } );
     info.push({ "this" : this } );
     console.log(info);

     mappedArr[i] = fn.call(context, arr[i], i, this); 

   } 
   return mappedArr;

 }; 

И затем вызовите его, используя:

Array.prototype. selfMap = selfMap;
[1,2,3].myMap(n => n * 2);

Зачем предоставлять контекст в качестве второго аргумента myMap? Я думаю, что для этого может существовать JavaScript шаблон проектирования, но в настоящее время я не смог найти никаких ссылок из-за всего мусора результатов поиска в Google, которые не связаны с моим поиском.

Я написал функцию и передал в контексте второй аргумент, но я не уверен, хотя я мог придумать свои собственные мысли, какова основная причина для этого?

Вот мой пример использования:

[1,2,3].selfMap((n, o, p) => {

     let info = [];
     info.push({ "n" : n } );
     info.push({ "o" : o } );
     info.push({ "p" : p } );
     info.push({ "this" : this } );
     console.log(info)
     return n * 2;

});

Может ли передать это или окно, или {}

Контекст будет равен текущему контексту, где мы вызвали метод из

[1,2,3].selfMap((n, o, context) => {

         let info = [];
         info.push({ "n" : n } );
         info.push({ "o" : o } );
         info.push({ "context" : context } );
         info.push({ "this" : this } );
         console.log(info)
         return n * 2;

}, this);

Окно как аргумент контекста

[1,2,3].selfMap((n, o, context) => {

     let info = [];
     info.push({ "n" : n } );
     info.push({ "o" : o } );
     info.push({ "context" : context } );
     info.push({ "this" : this } );
     console.log(info)
     return n * 2;

}, window);

И мы могли бы использовать пользовательский объект

[1,2,3].selfMap((n, o, context) => {

     let info = [];
     info.push({ "n" : n } );
     info.push({ "o" : o } );
     info.push({ "context" : context } );
     info.push({ "this" : this } );
     console.log(info)
     return n * 2;

}, { something: 1 });

Итак, я знаю, что контекст можно передать, но я не не знаю, почему я мог бы передать в контексте.

Пожалуйста, в своем ответе предоставьте не только объяснение, но и пример (ы) для уточнения вашего объяснения.

Спасибо

1 Ответ

0 голосов
/ 14 февраля 2020

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

Пожалуйста, рассмотрите следующий пример

class DomManipulation() {
      
    constructor() {
      this.someValue = "someValue"

      this.registerEvent();
    }

    eventListener() {
      console.log(this);  // can you guess the context of this here 
      console.log(this.someValue); // answer is undefined. Since this is pointing to `#oneDomElement` dom here. so access to class DomManipulation variable is overshadowed 
    }

    registerEvent() {
      document.querySelector("#oneDomElement").addEventListener('click', this.eventListener);
    }
 }
    <div id="oneDomElement">Hello</div>

Как видно из приведенного выше примера, значение this затенено элементом Dom, поскольку мы настроили прослушиватель для щелчка событие. Теперь невозможно получить доступ к DomManipulation переменным-членам класса (ie. SomeValue)

Итак, чтобы преодолеть проблему, мы можем сделать следующее

eventListener(event, context) {
      console.log(this); // now this will point to DomManipulation class
      console.log(this.someValue);  // someValue
      // also 
      console.log(context) // you can also use DOM `#oneDomElement` context here 
}

registerEvent() {
       const self = this;
      document.querySelector("#oneDomElement").addEventListener('click',  (event) => {
           self.eventListener.call(self, event, this);
      });
}

С помощью вышеуказанного решения вы можете получить доступ к обоим контекстам здесь: 1. this будет указывать на DomManipulation класс 2. context будет указывать на #oneDomElement элемент DOM.

...