2014-01-16 248 views
0

我以为我明白JavaScript范围如何工作到现在。这是我JavaScript范围问题

function MFCommentsHandler(node, type, item) { 
    this.get = function(returnType){ 
     ... 
    } 

    function getButton(){ 
     var button = document.createElement('button'), 
      get = this.get; 
     button.innerHTML = 'Load more comments'; 
     button.onclick = function(){ 
      console.log(get); 
      get('html'); 
     } 
     return button; 
    } 

} 

我使用内部函数通过getButton生成的文档元素追加,但是当我点击它,我得到get is not a function。为什么getonclick函数里面没有定义?

+0

您是否正在全球化? –

+0

,因为'this'是你调用'MFCommentsHandler'的任何上下文。除非你使用'new'构造一个新对象。 –

+0

在你的情况下,我只是使用var get = function ... –

回答

2

this仅取决于如何调用函数。它可以是隐含的,但在你的情况下,你失去了上下文。你需要在上范围缓存this

function MFCommentsHandler(node, type, item) { 
    var self = this; 
    this.get = function(returnType){ 
     ... 
    } 
    function getButton(){ 
     self.get(); // cached reference 
     ... 
    } 
} 

或者当你打电话getButton你可以明确地通过上下文:

function MFCommentsHandler(node, type, item) { 
    this.get = function(returnType){ 
     ... 
    } 
    function getButton(){ 
     this.get(); 
     ... 
    } 
    getButton.call(this); // explicit context 
    ... 
+0

啊..这么简单的错误..谢谢先生。 –

+0

“*这只取决于你如何调用函数*”。究竟。 “*但在你的情况下,你失去了上下文*”。这与第一个陈述有冲突。你的意思是*这个*在呼叫中没有设置为所需的值。 – RobG

+0

我的意思是'this'不是以前所以“你失去了语境”,但从技术上来说,是的,这是因为'this'没有在通话中设置。但是这个调用可以是隐式的,就像在'obj.method()'中那样,但是你可以在没有点符号的情况下调用这个函数,这样你就失去了上下文。我就是这样解释的。 – elclanrs

2

this变化与上下文被引用的。试试这个:

function MFCommentsHandler(node, type, item) { 
    var get = function(returnType){ 
     ... 
    } 

    function getButton(){ 
     var button = document.createElement('button'); 
     button.innerHTML = 'Load more comments'; 
     button.onclick = function(){ 
      console.log(get); 
      get('html'); 
     } 
     return button; 
    } 

} 
+1

但我不能从外面呼叫'get' –

+0

@php_nub_qq这是真的。在这种情况下,请与elclanrs的回答一起。 – Matt

1

你所定义的MFCommentsHandler()函数中定义的getButton()功能是关闭。闭包有权访问其外部函数的变量和参数(但不包括对象)。但是,他们无法访问其外部功能的值。要访问此值,只需将其引用存储在变量中,以便可以从内部函数访问它。

function MFCommentsHandler(node, type, item) { 
    var that = this; //reference to the invocation context 
    //that can be accessed anywhere within this function 

    this.get = function(returnType){ 
     ... 
    } 

    function getButton(){ 
     ... 
     that.get('html'); 
    } 

}