Узнайте, является ли функция анонимной или определена в объекте - PullRequest
4 голосов
/ 17 декабря 2009

Я пытаюсь написать вспомогательный метод в JavaScript. Он должен действовать иначе, если кто-то отправляет функцию или ссылку на функцию.

Я хочу использовать это так:

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

Что я не могу понять, так это: как внутри вспомогательной функции определить разницу между ними?

Я думаю, это связано с тем, что JavaScript сначала оценивает obj.fn перед тем, как отправить его. Единственный обходной путь, который я нашел, - это отправить объект obj.fn как объект, т. Е.

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

Тогда я могу сказать разницу между двумя с помощью typeof. Но мне действительно нравится какой-то способ сделать это без дополнительного объявления объекта.

Ответы [ 3 ]

2 голосов
/ 17 декабря 2009

ОБНОВЛЕНО * (СНОВА): Я думал, что метод 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 голос
/ 17 декабря 2009

Я думал, что добавлю еще один альтернативный ответ, главным образом потому, что я не хотел добавлять в суп, который является моим другим ответом, но также потому, что он не очень понравился избирателям стека переполнения, которые не уходят конструктивные комментарии; -)

В качестве альтернативы тому, что вы пытаетесь сделать, вы можете добавить третий параметр к вспомогательной функции:

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

Просто предложение и работает так же хорошо, как ваш текущий обходной путь, или даже лучше.

0 голосов
/ 17 декабря 2009

Вы можете использовать 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, которой не было в других браузерах и которая больше не действительна в IE начиная с версии 9. Однако вы все равно можете назначать именованные функции как свойства объекта, используя выражение именованной функции:

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

Это работает во всех браузерах, но IE 8 и ниже не соответствуют спецификации, в которой говорится, что функция доступна только под этим именем внутри своего блока.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...