Почему «this» ссылается на объект Window в фрагменте кода ниже? - PullRequest
0 голосов
/ 02 июля 2018

Может кто-нибудь помочь мне понять, почему код ниже печатает Внутри функции splitName = [Окно объекта]
Почему «this» относится к объекту Window?

let emp = {
  fName: '',
  lName: '',
  setName: function(name) {
    console.log("Inside setName function = " + this)
    let splitName = function(n) {
      console.log("Inside splitName function = " + this)
      let nameArr = n.split(' ');
      this.fName = nameArr[0];
      this.lName = nameArr[1];
    }
    splitName(name);
  }
}

emp.setName('ABC DEF');
console.log(window.fName);

Ответы [ 5 ]

0 голосов
/ 03 июля 2018

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

let emp = {
  fName: '',
  lName: '',
  setName: function(name) {
    console.log("Inside setName function = " + this)
    let splitName = function(n) {
      console.log("Inside splitName function = " + this)
      let nameArr = n.split(' ');
      this.fName = nameArr[0];
      this.lName = nameArr[1];
    }
    splitName.apply(emp,[name]);
  }
}
emp.setName('ABC DEF');
console.log(window.fName);
0 голосов
/ 02 июля 2018

Из-за контекста и лексической области видимости Лексическая область действия и контекст выполнения в javascript. В javascript каждая функция (не стрелка) имеет контекст выполнения, где, как ES6 функции стрелок не имеют своего собственного контекста выполнения.

для функций конструктора, когда мы запускаем их с помощью нового, движок javascript создает для него контекст выполнения, и вы назначаете его ему. но для неконструктивных функций, если они не вызываются с использованием function.Call или function.Apply, т. е. это не установлено, тогда из-за лексической области видимости они получают область окна, являющуюся самой внешней областью действия.

попробуйте console.log(this) в консоли браузера, это выведет окно (так как это родительский объект или самая внешняя область в DOM).

также взгляните на это . Как работает ключевое слово "this"?

0 голосов
/ 02 июля 2018

Я бы рекомендовал изменить ваш метод splitName, чтобы он был методом для вашего объекта. Таким образом, он будет знать, что this будет ссылаться на ваш объект emp. В противном случае, поскольку это отдельная функция, это будет означать, что this ссылается на window по умолчанию, поскольку нет вызывающего контекста.

let emp = {
  fName: '',
  lName: '',
  splitName: function(n) {
    console.log("Inside splitName function = " + this)
    let nameArr = n.split(' ');
    this.fName = nameArr[0];
    this.lName = nameArr[1];
  },
  setName: function(name) {
    console.log("Inside setName function = " + this)
    this.splitName(name);
  }
}

emp.setName('ABC DEF');
console.log(window.fName);
console.log(emp.fName);
0 голосов
/ 02 июля 2018

Обновите объявление функции splitName как функцию Arrow, тогда оно примет это как область видимости своего родителя и будет работать как положено.

Вы можете узнать о , как «это» работает здесь .
И узнать о функциях стрелок здесь.

let emp = {
  fName: '',
  lName: '',
  setName: function(name) {
    console.log("Inside setName function = " + this)
    let splitName = (n) => {
      console.log("Inside splitName function = " + this)
      let nameArr = n.split(' ');
      this.fName = nameArr[0];
      this.lName = nameArr[1];
    }
    splitName(name);
  }
}

emp.setName('ABC DEF');
console.log(emp.fName + ' ' + emp.lName );
console.log(window.fName);
0 голосов
/ 02 июля 2018

Можно использовать Function#call() для передачи контекста объекта в

let emp = {
  fName: '',
  lName: '',
  setName: function(name) {
    console.log("Inside setName function = " + this)
    let splitName = function(n) {
      console.log("Inside splitName function = " + this)
      let nameArr = n.split(' ');
      this.fName = nameArr[0];
      this.lName = nameArr[1];
    }
    splitName.call(this, name);
  }
}

emp.setName('ABC DEF');
console.log(emp.fName);
...