开发者

javascript object variables and functions

First question

var obj = function(){  
    var a = 0;  
    this.b = 0; 
}

Is there any difference in behavio开发者_开发问答ur of a and b?


Second question

var x = 'a';
var f1 = function(x){ alert(x) }
var f2 = new Function('alert('+x+')')

Is there any difference in behaviour of f1 and f2


Question 1

var obj = function() {
   var a = 0;
   this.b = 0;
}

Within the function, you'll be able to access both variables, but in the case of

var x = new obj();

... you'll be able to access x.b, but not x.a.

Question 2

As your question is written at the moment, it is a syntax error. The following will work:

var x = 'a';
var f1 = function(x){ alert(x) }
var f2 = new Function('alert('+x+')')

... but that would be the same thing as writing:

var x = 'a';
var f1 = function(x){ alert(x) }
var f2 = new Function('alert(a)')

The difference here is obvious. f1 disregards the global variable x and alerts whatever is passed to it, while f2 also disregards the global variable x, and tries to look for a global variable a. This is probably not what you're trying to ask about.

What you probably want is something like this:

var x = 'a';
var f1 = function(){ alert(x) }
var f2 = new Function('alert(x)')

... or this:

var f1 = function(x){ alert(x) }
var f2 = new Function('x', 'alert(x)')

The difference between the two alternatives above is that the first always uses the global variable x, while the second never uses any global variable. The difference between f1 and f2, internally, in both examples, is none at all.

These are two ways of generating the exact same result. The only reason you'd ever want to use the f2 approach would be when generating the code in some dynamic manner that require string input for its definition. In general, try to avoid this practice.


var obj = function() { // function expression, while obj is created before head
                       // it's only assigned the anonymous function at runtime
     var a = 0; // variable local to the scope of this function
     this.b = 0; // sets a property on 'this'
}

Now what this is depends on how you're calling the function.

Also note the difference between function statements and expressions.

var x = 'a'; // string a, woah!
var f1 = function(x){ alert(x) } // another anonymous function expression

// Does not work
// 1. it's "Function"
// 2. It gets evaluated in the global scope (since it uses eval)
// 3. It searches for 'a' in the global scope
var f2 = new function('alert('+x+')') // function constructor

In short, never use the Function constructor, it will never inherit local scope and therefore you can't use closures with it etc.


First question:

 var obj = function() {
    var a = 0;
    this.b = 0;
 }

 instance = new obj();

 instance.showA = function() {
    alert("this.a = " + this.a);
 }

 instance.showB = function() {
    alert("this.b = " + this.b);
 }

 instance.showA();   // output undefined - local scope only, not even to methods.
 instance.showB();   // output 0 - accessible in method

Paste this in your Firebug console and run to see the output and behavior for yourself.

Second question:

  var f2 = new function('alert('+x+')');

This throws a syntax error in Firebug because the f should be capitalized. This is a case where a function is defined inside a string and evaluated. Here is a good example:

  var x = 'a=3';
  var f2 = new Function('alert('+x+')');

  f2();   // outputs 3 because the x passed into the variable is evaluated and becomes nested inside the quotes prior to the alert command being fired.

Here is what the substitution process looks like:

  1:  x = "a=3";    
  2:  'alert(' + x + ')');
  3:  'alert(' + 'a=3' + ')');    // x replaced with a=3
  4:  'alert(a=3)';
  5:  'alert(3);'

When function runs, alert(3) is fired. This can be used to execute other JavaScript pulled down from a remote server, although extreme care should be used for security reasons. When evaluating code that is nested in quotes, it helps to start from the inside and work your way up to the top level context. More information on dealing with nested quotes or embedded code can be found here: http://blog.opensourceopportunities.com/2007/10/nested-nested-quotes.html


Question 1: homework on scoping of variables (var b is local to the enclosing {} (local to the function in this case).

Question 2: Instead of using the Function constructor you could use eval? http://www.w3schools.com/jsref/jsref_eval.asp , as in

eval 'alert('+x+')';


Second question is VERY interesting. Only benchmarks can say the truth.

http://jsperf.com/function-vs-function/

http://jsperf.com/function-vs-function/1..8

http://jsperf.com/function-vs-constructor-vs-eval

http://jsperf.com/function-vs-constructor-vs-eval/1..5

It looks they are almost equal? I can see in modern browsers each variant is optimized enough


BUT BE AWARE OF RECREATING THE FUNCTION IN A LOOP!

http://jsperf.com/function-vs-function/2

Any wise comments?

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜