开发者

function calling

开发者 https://www.devze.com 2023-03-17 21:44 出处:网络
May 开发者_开发知识库be a simple question to solve... On button click I call a function on the include file and parse a function name (b). Why b is not a function ?

May 开发者_开发知识库be a simple question to solve... On button click I call a function on the include file and parse a function name (b). Why b is not a function ? I have the following files (only a sample of the issue):

comum.js

function f(b){
    var a = eval(b +'();');
}

function a(v){
    $.ajax({url:'update.aspx',
            data: 'q=5',
            success: function(){
                f(v);
            }   
    });
}

default.html

<html>
<head>
<title></title>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="comum.js"></script>
<script language="JavaScript" type="text/javascript">
    $(function(){
        $("#me").click(function(){
            a('b');
        });
    });

    function b(){
        $("#me").attr("disabled","disabled");
    }
</script>
</head>
<body>
<input type="button" id="me" value="click me" />
</body>
</html>


While the others are right that it is better to not use eval in this situation, you did ask a specific question that hasn't been answered.

"Why b is not a function?"

The reason is that you gave the parameter to the f() function the same name as the global b() function. So when b is eval'd, the b parameter that is "shadowing" the b function is referenced.

function f(b){ // <-- Parameter with same name as function.
    var a = eval(b +'();'); // <-- So the eval is a reference right back to the
}                           //       'b' parameter (a string) instead of the
                            //       'b' function.

  // global function b
function b(){
    $("#me").attr("disabled","disabled");
}

So as you can see, the eval() is executed from the local variable scope, and the first b that is found in the scope chain is the same b that you passed to eval.


All you need to do is change the name of the parameter to something other than b.

  // ---------v------ different name so we don't shadow the global "b()" function
function f( func ){
    var a = eval( func +'();' );
}

So here I changed the parameter to func. Now when the string referenced by func is eval'd, it will reference the global b() function because the parameter is no longer in the way.


FYI, another approach would be to access the function directly as a property of window, because global variables are automatically added as properties.

function f( b ){
    var a = window[ b ]();
}

Now you're asking for the b function directly from the window object, instead of evaluating the argument you received as a member of the variable scope chain.


Don't use eval.

Change this:

a('b');

To this instead:

a(b);

And then also:

success: function(){
    v();
} 


I'm not exactly sure what you're trying to do, but when you call a with 'b' as a parameter, you are passing the character 'b', rather than a reference to the function b.

To pass a reference to the function b to a, change a('b'); to a(b);.


The program ends up with calling eval('b()') (in f()), but at this point, the function b() cannot be found, since it's defined locally in the lambda function (within $()).

I guess that you have to define b() as global function in order for eval to work the way you want.


Why don't you just pass an anonymous function instead of passing the function's name (to parse it using eval)?

It would became like this, and it's better.

function f(b){
    var a = b();
}

function a(v){
    $.ajax({url:'update.aspx',
        data: 'q=5',
        success: function(){
            f(function() {
                ....
            });
        }   
    });
}
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号