2015-07-16 4 views
0

У меня есть блок кода, который возвращает имя и фамилию, имя и имя в зависимости от того, какую внутреннюю функцию вы используете. Однако при использовании этого ключевого слова firstname возвращает undefined, когда я обращаюсь к внутренней функции lastname или middlename. Если я не использую 'this', то firstname возвращает только штраф. Я не понимаю, почему это происходит. Может ли кто-нибудь объяснить, почему?Почему this.firstName возвращает undefined?

function celebrityName (firstName) { 
     var nameIntro = "This celebrity is "; 
     this.firstName = firstName; 

     return { 
      lastName: function(lastName){ 
       this.lastName = lastName; 
       return nameIntro + this.firstName + ' ' + this.lastName + " (last name)"; 
      }, 

      middleName: function(middleName){ 
       this.middleName = middleName; 
       return nameIntro + this.firstName + ' ' + this.middleName + " (middle name)"; 
      } 
     } 
    } 

    var mjName = celebrityName ("Michael"); 
    console.log(mjName.middleName("Jackson")); 

Вот код без «этого» и отлично работает.

function celebrityName (firstName) { 
     var nameIntro = "This celebrity is "; 

     return { 
      lastName: function(lastName){ 
       return nameIntro + firstName + ' ' + lastName + " (last name)"; 
      }, 

      middleName: function(middleName){ 
       return nameIntro + firstName + ' ' + middleName + " (middle name)"; 
      } 
     } 
    } 

    var mjName = celebrityName ("Michael"); 
    console.log(mjName.middleName("Jackson")); 

ответ

1

Вы ожидаете объем this быть celebrityName функция; однако, это функция middleName, и поэтому this.firstName не существует.

Вы можете использовать псевдоним this в функции celebrityName, но некоторые скажут, что это антипаттерн.

Так, например:

function celebrityName (firstName) { 
    var nameIntro = "This celebrity is "; 
    var celebrity = this; 
    celebrity.firstName = firstName; 

    return { 
     lastName: function(lastName){ 
      celebrity.lastName = lastName; 
      return nameIntro + celebrity.firstName + ' ' + celebrity.lastName + " (last name)"; 
     }, 

     middleName: function(middleName){ 
      celebrity.middleName = middleName; 
      return nameIntro + celebrity.firstName + ' ' + celebrity.middleName + " (middle name)"; 
     } 
    } 
} 
+0

Спасибо за ответ, но, делая это lastName и middleName, теперь становятся неопределенными. – rachiebytes

+0

@RachelAnnJohnson, это не должно. Убедитесь, что вы использовали 'celebrity.' во всех экземплярах сейчас (не только функцию« middleName », но также и« lastName »): [См. JsBin] (http://jsbin.com/zivavisina/edit?js , консоль) – Tom

+0

Понял мою ошибку, спасибо за ответ, теперь имеет полный смысл! – rachiebytes

0

Потому что во время декларации "это" в "this.firstName" является ссылкой на объект Global Window. И «это» в «this.firstName», которое вы ссылаетесь на console.log, ссылается на «объект», который вы вернули. И «это» разные.

function celebrityName (firstName) { 
    var nameIntro = "This celebrity is "; 

    /* Here You defined "this" in the context of Global Object */ 
    this.firstName = firstName; // "this" here is the Global Window Object 

    /* You are returning a different object here */ 
    /* This is the object which is getting referenced when you are trying to access "this.firstName" inside here */ 
    return { 
     lastName: function(lastName){ 

      /* "this" here refers to Current Object which you are returning */ 
      this.lastName = lastName; 

      /* "this" here refers to Current Object which you are returning */ 
      /* and as there is no this.firstName defined for current object, you get undefined */ 
      return nameIntro + this.firstName + ' ' + this.lastName + " (last name)"; 
     }, 

     middleName: function(middleName){ 

      /* "this" here refers to Current Object which you are returning */ 
      this.middleName = middleName; 

      /* "this" here refers to Current Object which you are returning */ 
      /* and as there is no this.firstName defined for current object, you get undefined */ 
      return nameIntro + this.firstName + ' ' + this.middleName + " (middle name)"; 
     } 
    } 
} 

var mjName = celebrityName ("Michael"); 
console.log(mjName.middleName("Jackson")); 
0

Вы возвращаете другой объект, а новый объект не имеет первого имени. Есть две вещи, которые вы могли бы сделать.

function celebrityName(firstname){ 
    this.nameIntro = "This celebrity is "; 
    this.firstName = firstname; 
    this.lastName = function(lastname){ 
    return this.nameIntro+this.firstName+' '+lastName+" (lastname)"; 
    } 
    this.middleName = function(midname){ 
    return this.nameIntro+this.firstName+' '+midName+" (midname)"; 
    } 
} 

И вы могли бы назвать его так: var mjName = new celebrityName("Michael");

Или вы можете вернуть весь объект:

function celebrityName(firstname) { 
    return { 
    nameIntro: "This celebrity is ", 
    firstName: firstname, 
    lastName: function(lastname){ 
     return this.nameIntro+this.firstName+' '+lastName+" (lastname)"; 
    }, 
    middleName: function(middleName){ 
      return nameIntro + this.firstName + ' ' + middleName + " (middle name)"; 
    } 
    } 
} 

И это будет называться, как вы делали раньше: var mjname = celebrityName("Michael");

+0

Значение 'this' в' lastName' будет зависеть от того, как вызывается 'lastName'. Канонический патологический пример - если вы установите ссылку на 'lastName' и попытаетесь вызвать его, например,' var tmp = mjName.lastName'. (Кроме того, вы указали опечатки параметров.) –

+0

Я устал печатать и копировать. Но я просто использовал его, как OP использовал его. Вы правы, хотя обычно вы копируете значение в объект – MiltoxBeyond

Смежные вопросы