开发者

How to break closures in JavaScript

开发者 https://www.devze.com 2023-02-03 02:46 出处:网络
I开发者_Python百科s there any way to break a closure easily in JavaScript? The closest I have gotten is this:

I开发者_Python百科s there any way to break a closure easily in JavaScript? The closest I have gotten is this:

var src = 3;
function foo () {
    return function () {
        return src; }
    }
function bar (func) {
    var src = 9;
    return eval('('+func.toString()+')')(); // This line
}
alert(bar(foo()));

This prints '9', instead of '3', as a closure would dictate. However, this approach seems kind of ugly to me, are there any better ways?


Your code is not breaking the closure, you're just taking the code the makes up a function and evaluating it in a different context (where the identifier src has a different value). It has nothing at all to do with the closure that you've created over the original src.

It is impossible to inspect data that has been captured in a closure. In a sense, such data are even more "private" than private members in Java, C++, C# etc where you can always use reflection or pointer magic to access them anyway.


This could be useful if you are trying to create multiple similar methods in a loop. For example, if you're creating a click handler in a loop that relies on a loop variable to do something a little different in each handler. (I've removed the "eval" because it is unnecessary, and should generally never be used).

// Assign initial value
var src = 3;

// This is the regular js closure.  Variables are saved by reference.  So, changing the later will
// change the internal value.
var byref = function() {
  return src;
}

// To "break" the closure or freeze the external value the external function is create and executed
// immidiatly.  It is used like a constructor function which freezes the value of "src".
var byval = function(s) {
  return function() { return s };
}(src);

src = 9;

alert("byref: " + byref()); // output: 9
alert("byval: " + byval()); // output: 3


As others said this doesn't seem to be the right thing to do. You should explain why you want this and what you want to achieve.

Anyway, one possible approach could be to access properties of an object inside your function. Example:

var src = 3;

function foo (context) {
    context = context || window; // Fall back to the global namespace as default context

    return function () {
        return context.src; 
    }
}

function bar (func) {
    var context = {src: 9};
    return func(context);
}

alert(bar(foo));


If you want to access a variable in a wider scope, just don't reuse the variable name in a narrower scope.

That's how it is supposed to work. Work with it instead of trying to fight it.


Here is the code see if you can understand , closures defined within a loop .

 var clicked  = false;
 for(var i=0;i<temp.length;i++){
  (function(index){
   if(clicked) return false;
   $(temp[index]).on('click',function(){
     if($(temp[index]).text()=="" && !$(".cell1").val()){
       $(this).text(player1Val);
       $(".cell1").val(true);
       console.log("first player clicked ");
       clicked = true;
       $(this).off();
       for(var j=0;j<temp.length;j++){
          $(temp[j]).off('click');
       }
       return false;
    }
    else return false;
   });
 })(i);
}
0

精彩评论

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