无法在javascript中访问函数内的函数

时间:2012-09-14 09:15:44

标签: javascript closures

我需要知道我做错了什么因为我不能调用内部函数show或hide?

(function()
{
    var Fresh = {
        notify:function()
        {
            var timeout = 20000;
            $("#notify-container div").get(0).id.substr(7,1) == "1" && (show(),setTimeout(hide(),timeout));
            var show = function ()
            {
                $("body").animate({marginTop: "2.5em"}, "fast", "linear");
                $("#notify-container div:eq(0)").fadeIn("slow");
            },
            hide = function()
            {
               $("#notify-container div").hide();
            }
        }//END notify
    }
    window.Fresh = Fresh;
})();
Fresh.notify();
谢谢,理查德

5 个答案:

答案 0 :(得分:3)

<强>更新

如果您希望能够执行以下操作:Fresh.notify.showMessage(),您需要做的就是为函数notify分配属性:

var Fresh = {notify:function(){return 'notify called';}};
Fresh.notify.showMessage = function () { return this() + ' and showMessage, too!';};
Fresh.notify();//notify called
Fresh.notify.showMessage();//notify called and showMessage, too!

这将指向此处的函数对象,并且可以这样调用(this() === Fresh.notify();)。这就是它的全部。

此代码存在许多问题。首先:你试图使用闭包很棒。但如果你不介意我的说法,你就不会充分利用它们。例如:notify方法包含函数声明和jQuery选择器。这意味着每次调用方法时,都会创建新的函数对象,选择器将导致dom一次又一次地被搜索。最好只保留闭包范围中引用的函数和dom元素:

(function()
{
    var body = $("body");
    var notifyDiv = $("#notify-container div")[0];
    var notifyDivEq0 = $("#notify-container div:eq(0)");
    var show = function ()
    {
        body.animate({marginTop: "2.5em"}, "fast", "linear");
        notifyDivEq0.fadeIn("slow");
    };
    var hide = function()
    {//notifyDiv is not a jQ object, just pass it to jQ again:
        $(notifyDiv).hide();
    };
    var timeout = 20000;
    var Fresh = {
        notify:function()
        {
            //this doesn't really make sense to me...
            //notifyDiv.id.substr(7,1) == "1" && (show(),setTimeout(hide,timeout));
            //I think this is what you want:
            if (notifyDiv.id.charAt(6) === '1')
            {
                show();
                setTimeout(hide,timeout);//pass function reference
                //setTimeout(hide(),timeout); calls return value of hide, which is undefined here
            }
        }//END notify
    }
    window.Fresh = Fresh;
})();
Fresh.notify();

在这种情况下很难提出建议,但是因为这个代码本身并没有多大意义。我建议你设置a fiddle,这样我们就可以看到代码在工作(或者看到代码失败了:P)

答案 1 :(得分:2)

首先,当您尚未定义show时,您尝试使用show值(尽管该范围内存在function test() { show(); // TypeError: show is not a function var show = function() { console.log(42); }; } 变量):

var show

通过将function test() { var show = function() { console.log(42); }; show(); } test(); // 42 行移动到可以调用的点之上,可以轻松修复:

function show() { ... }

...或者如果您以更“传统”的方式定义函数(使用function test() { show(); function show() { console.log(42); }; } test(); // 42 表示法)。

... && (show(), setTimeout(hide, timeout) );

其次,你应该改用它:

setTimeout

...因为它是函数名,而不是函数结果,应作为第一个参数传递给{{1}}。

答案 2 :(得分:1)

我认为调用show,hide的顺序就是问题。我修改了你的代码。它工作正常。请访问该链接 http://jsfiddle.net/dzZe3/1/

答案 3 :(得分:1)

你必须先定义show和hide,然后按照他们的说法更改hide()。 结果将是这样的:

(function()
{
    var Fresh = {
        notify:function()
        {
            var show = function()
            {
                $("body").animate({marginTop: "2.5em"}, "fast", "linear");
                $("#notify-container div:eq(0)").fadeIn("slow");
            },
            hide = function()
            {
               $("#notify-container div").hide();
            },
            timeout = 20000;
            $("#notify-container div").get(0).id.substr(7,1) == "1" && ( show(), setTimeout(hide,timeout) );

        }//END notify
    }
    window.Fresh = Fresh;
})();
Fresh.notify();

答案 4 :(得分:0)

的     (显示(),setTimeout的(隐藏(),超时));

至少需要

(show(),setTimeout(function() {hide()},timeout)); 

(show(),setTimeout(hide,timeout));