Разница между этими двумя конструкциями кода Javascript

Я случайно наткнулся на следующий код JavaScript, и он прекрасно работает.

var Mario = {
  name: 'Mario',
  sayHello: function(name) {
    return 'Hi I\'m ' + this.name;
  }
};

var Luigi = {
   name: 'xoxox'
};

alert(Mario.sayHello.call(Luigi , name));

Однако, когда я изменяю свойство name на что-то другое (скажем, xyz), вот так:

var Mario = {
  xyz: 'Mario',
  sayHello: function(xyz) {
    return 'Hi I\'m ' + this.xyz;
  }
};

var Luigi = {
   xyz: 'xoxox'
};

alert(Mario.sayHello.call(Luigi , xyz));

Это не работает!!

Что означает это поведение и почему оно не работает? Может кто-нибудь объяснить?

3 ответа

Ну, технически, ваш name пример не работает Это выполняется потому, что есть переменная name в глобальном пространстве имен (window.name).

Ошибка здесь:

var Mario = {
  name: 'Mario',
  sayHello: function(name) {
    return 'Hi I\'m ' + this.name;
  }
};

sayHello - это функция, которая получает имя в качестве параметра и ничего с ним не делает. Вместо этого он возвращает строку со свойством name объекта была вызвана функция.

Mario.sayHello() // Hi I'm Mario
Mario.sayHello.call({ name: 'Foo'}) // Hi I'm Foo

Когда вы делаете Mario.sayHello(myname), функция sayHello вызывается в контексте Марио с name параметр, инициализированный тем, что есть в myname (может даже быть ошибкой, если myname не существует).

Если вы хотите дать имя свойства в качестве параметра, вы можете сделать:

var Mario = {
  name: 'Mario',
  sayHello: function(name) {
    return 'Hi I\'m ' + this[name];
  }
};

var Luigi = {
   xyz: 'xoxox'
};

alert(Mario.sayHello.call(Luigi , 'xyz')); // Hi I'm xoxox

Оба не работают, причина в том, что вы передаете второе, не определенное значение, вызову callвы можете сделать

var Mario = {
  name: 'Mario',
  sayHello: function() {
    return 'Hi I\'m ' + this.name;
  }
};

var Luigi = {
   name: 'xoxox'
};

alert(Mario.sayHello.call(Luigi));

Там нет необходимости проходить name, так как это уже в объекте.

Другие вопросы по тегам