找出函数是匿名的还是在对象中定义的

时间:2009-12-17 10:50:51

标签: javascript function

我正在尝试用JavaScript编写辅助方法。如果发送函数或对函数的引用,它应该采取不同的行为。

我想像这样使用它:

helper('div', function () { return false; })
helper('div', obj.fn)

我无法弄清楚的是:如何在辅助函数里面说明两者之间的区别?

我认为这是因为JavaScript在发送之前首先评估obj.fn。 我找到的唯一解决方法是将obj.fn作为obj发送,即

helper('div', { fn: obj.fn })

然后我可以用typeof来区分两者之间的区别。但我真的很想在没有额外对象声明的情况下实现它。

3 个答案:

答案 0 :(得分:2)

更新*(再次): 我认为toString()方法可能是你前进的唯一方法。但是,它不会以不同方式处理匿名对象的引用。

此代码演示了:

function acceptparam(fn){

            console.log("fn.constructor = " + fn.constructor);
            console.log("typeof fn = " + typeof fn);
            console.log("fn toString " + fn.toString());

            console.log("fn.prototype = " + fn.prototype);
            console.log("fn.prototype.constructor = " + fn.prototype.constructor);
            console.log("this[0] = " + this[0]);
            console.log("---");

        }

        function empty(){
            return ;
        }

        var x = {
            y : function(){return;}
        }

        acceptparam(empty);
        acceptparam(function(){return;});
        acceptparam(x.y);

非常有趣的问题,没有实施自己的解决方案,我认为你不能做到这一点,这篇文章有助于解释原因。它关于父子关系只是一种方式。

http://codingforums.com/showthread.php?t=134855

答案 1 :(得分:1)

我以为我会添加另一个替代答案,主要是因为我不想添加汤,这是我的另一个答案,但也因为它不能很好地与不离开的stackoverflow选民建设性意见; - )

作为您尝试执行的操作的替代方法,您可以向辅助函数添加第三个参数:

function helper (tagName, fn, method)
{
    if (method)
        fn = fn[method];

    //- Do rest of helper function here
}
//- Now if we pass an object method to helper function we can identify it properly
helper('div', obj, "fn"); // method is obj.fn
helper('div', function () { blah(); }); // Still works fine

仅仅是一个建议,并且与您当前的解决方案相比甚至更好。

答案 2 :(得分:0)

您可以使用toString()来确定函数是否是匿名的,假设它被声明为命名函数而不是分配给变量的未命名函数:

function jim () { var h = "hello"; }
function jeff(func) 
{ 
    var fName;
    var inFunc = func.toString();
    var rExp   = /^function ([^\s]+) \(\)/;
    if (fName = inFunc.match(rExp))
       fName = fName[1];

    alert(fName);
}

如果有的话,会给你这个函数的名称。

jeff(function () { blah(); }); // alert: null;
jeff(function joe () { blah(); }); // alert: "joe";
jeff(jack); // "jack" if jack is function jack () { }, null if jack = function() {} 

我之前的编辑提到了一个IE怪癖,它在其他浏览器中不存在,并且从版本9开始在IE中不再有效。但是,您仍然可以使用命名函数表达式将命名函数指定为对象属性:

var obj = {
    fn: function namedFunction () { }
};

这适用于所有浏览器,但IE 8及更低版本不符合规范,该规范表明该功能仅在其自己的块内以此名称提供。