最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Function Arguments Passing and Return - Stack Overflow

programmeradmin4浏览0评论
  var foo = {
    bar: function() { return this.baz; },
    baz: 1
  };
  (function(){
    return typeof arguments[0]();
  })(foo.bar);

Why does this code return undefined?

I would assume arguments[0] would hold the foo.bar, which is a function. When invoked via arguments[0]() it should return the result of the function evaluation in, this case 1. Hence, typeof arguments[0]() should return "Number" (like typeof 1). Instead, it returns undefined. Why?

  var foo = {
    bar: function() { return this.baz; },
    baz: 1
  };
  (function(){
    return typeof arguments[0]();
  })(foo.bar);

Why does this code return undefined?

I would assume arguments[0] would hold the foo.bar, which is a function. When invoked via arguments[0]() it should return the result of the function evaluation in, this case 1. Hence, typeof arguments[0]() should return "Number" (like typeof 1). Instead, it returns undefined. Why?

Share Improve this question edited Jul 10, 2012 at 10:32 Peter-Paul van Gemerden 7,00932 silver badges37 bronze badges asked Dec 21, 2011 at 9:39 Vikram BhaskaranVikram Bhaskaran 4375 silver badges9 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 8

To understand why this is not a reference to the object on which the function resides, you have to understand that JavaScript doesn't have classes. It has functions.

In JavaScript, functions are never strictly "bound" to objects like they are in classful languages like Java, C#, whatever. A javascript function is just another type, like string and number, which means that you can pass functions around in variables like any other type. In your example, the function contained in foo.bar isn't aware of foo at all. It's just a function, minding its own business.

So what does the this keyword do? It points to the execution context. In your example, you call the function inside foo.bar from the global scope (i.e. window), so that's what it points to. You can use apply() to call the function in the correct scope, but for that you would need access to that scope (in this case, the foo object). This negates any of the security advantages of passing along just the function, without the object.

To "fix" this "problem", ECMAScript 5 (the future version of JavaScript) introduces bind(). This handy function lets you bind a function to a certain execution scope before passing it to another function, like this:

var foo = {
    bar: function() { return this.baz; },
    baz: 1
};

var callback = foo.bar.bind(foo);

(function(){
    return typeof arguments[0]();
}(callback));

the code won't work because inside the anonymous function you lose the reference to this.baz of foo object when used in another context

you can use the apply() method to redefine the context, like so

var foo = {
   bar: function() { return this.baz; },
   baz: 1
};

(function(){
   return arguments[0].apply(foo);
})(foo.bar);

and this returns correctly 1 because apply() method change the execution context to the object passed as argument

typeof arguments[0].apply(foo);

returns numberas expected

You can reffering to foo by this statement.

You should write a wrapper like below which will very helpfull if will we wanted to change the name of the foo when we will have a lot of function in foo

var foo = {
    bar: function() { return this.baz; },
    baz: 1
  };

(function(a){
 for( var i in a){ 
    if( typeof a[i] === "function" ){

      a[i] = (function(f){  
            return function(){
                return f.apply(a,arguments);
            }
      })(a[i])
    }
 }
})(foo);

  (function(){
    return typeof arguments[0]();
  })(foo.bar);

this refer to bar function itself.

var foo = {
    bar: function() {return foo.baz; },
    baz:1
  };
  (function(){
    return typeof arguments[0]();
  })(foo.bar);

fiddle : http://jsfiddle/W9Jqb/

发布评论

评论列表(0)

  1. 暂无评论