2014-02-17 4 views
5
var name = "Bob"; 

var book = { 
    name: "Harry Potter", 
    writeName: function() { 
     return function() { 
      document.writeln(this.book.name); 
     } 
    } 
}; 

Когда я называю этосфера и переменные Javascript

book.writeName()(); 

Я хочу, чтобы напечатать Гарри Поттер (не Боб), который он делает выше, однако это:

var book2 = book; 
book = null; 
book2.writeName()(); 

Сейчас ищет this.book (то есть null), где он должен искать this.book2

Как я могу ссылаться на переменную?

+6

Не используйте 'this'. – Bergi

+0

@Bergi Но когда я перехожу к книге2, он все еще ищет книгу –

+0

ОК, извините, мне нужно уточнить: не используйте 'this', где неуместно, как здесь, внутри возвращенной функции, где [' this'] (https: // разработчик .mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this) относится к глобальному объекту :-) – Bergi

ответ

5

Что вам нужно здесь является переменная в writeName закрытия:

var book = { 
    name: "Harry Potter", 
    writeName: function() { 
     var name = this.name; // turn dynamic property into closure variable 
     return function() { 
      document.writeln(name); 
     } 
    } 
}; 
book.writeName()(); // Harry Potter 

Вместо того, чтобы хранить только name в закрытие, вы также можете сохранить ссылку на объект, как в ответе @ Quentin. Это может иметь значение, если вы планируете изменить свойство .name перед вызовом возвращаемой функции.

На вопрос, следует ли использовать this или book для ссылки на ваш объект, см. Javascript: Object Literal reference in own key's function instead of 'this'.

2

попробовать это: http://jsbin.com/pagumiwi/4/edit

var name = "Bob"; 

var book = { 
    name: "Harry Potter", 
    writeName: function() { 
     return function() { 
      document.writeln(this.name); 
     } 
     }() 
    }; 



book.writeName(); //would also work 
var book2 = book; 
book = null; 
book2.writeName(); //would also work 
+0

@KevinBowersox да отметил это. –

+0

Это IEFE совершенно бессмысленно. Убери это. – Bergi

+0

@RoyiNamir Я не хочу изменять способ, которым я вызываю функции, поэтому я все еще хочу вызвать book.writeName()(); –

3

Поскольку вы возвращаете функцию, вы будете терять любой контекст, вы получили от вызова функции, которая генерирует его.

Этот объект необходим для ссылки на объект, поэтому вам необходимо его сохранить.

writeName: function() { 
    var myBook = this; 

Затем нужно использовать этот сохраненный контекст:

return function() { 
     document.writeln(myBook.name); 
    } 
1

Поскольку this изменяется при изменении контекста, необходимо сохранить ссылку на оригинал this. Здесь я использовал _this

var book = { 
    name: "Harry Potter", 
    writeName: function() { 
    var _this = this; 
    return function() { 
     console.log(_this.name); 
    } 
    } 
}; 

book.writeName()() // Harry Potter 

var book2 = book; 
book = null; 
book2.writeName()(); // Harry Potter 

Demo

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