zoukankan      html  css  js  c++  java
  • [javascript]Preserving Scope in JavaScript (this)


     link: http://neo.dzygn.com/archive/2004/05/preserving-scope-in-javascript

     
    Preserving Scope in JavaScript
    Solution #3: Closures

    In JavaScript you can share variables between functions. Such a shared variable is called a closure. It is said, though, that closures require quite a lot more memory than ordinary properties.

    When we use closures the code looks like this:

    function MyClass(){
    var self = this; /* reference to the right scope */
    this.message = "hello world";
    this.talk = function talk(){ /* remember: because I named the function I can access it directly by it's name */
    if(this != self){
    return talk.apply(self, arguments);
    };
    alert(this.message);
    };
    };
    var instance = new MyClass();
    setTimeout(instance.talk, 1000);


    Comments

       1.
          trs wrote:

          Not a very eloquent solution, at some point there is still global code running so the scope context doesn’t encapsulate the execution. The bottom line is that with functions like setTimeout, the first argument will always run in global scope and there is nothing you can do about it. Probably best use a closure and be careful with references to binded COM objects i.e. DOM nodes (especially in Microsoft Internet Explorer, the MSFT GC has trouble cleaning up after non-JScript owned objects).

          May 8, 2004 @ 7:03 pm. Type: Comment. Permalink.
       2.
          David Schontzler wrote:

          I know I’m replying to this real late, but I thought I should point it out…

          The most eloquent solution would be to just replace all references to this with self. That way you don’t have to do any scope checking or rewrite your code structure.

          September 13, 2004 @ 2:18 am. Type: Comment. Permalink.
       3.
          Mark Wubben wrote:

          David, quite true. This was also pointed out in the linked DHTMLCentral posts (which was lost last Friday).

          As you can see in the sIFR code this is more or less the way I’m (currently) hacking.

          September 13, 2004 @ 3:05 pm. Type: Comment. Permalink.
       4.
          Gustavo Armagno wrote:

          If I want to pass the value of a variable to an event, there’s another ‘dirty’ (what it’s not dirty in js?) way to solve the problem:

          Not working:

          function createAnchor() {
          var str = “hello!!!”;
          var anchor = document.createElement("a");
          anchor.href = “”;
          anchor.onclick = function() {
          alert(str);
          }
          … [appendChild to some document element]
          }

          Variable str is out of the scope when the event is triggered.

          Solution:

          function createAnchor() {
          var str = “hello!!!”;
          var anchor = document.createElement("a");
          anchor.href = “”;
          var evalStr = “anchor.onclick = function() { alert(’” + str + ”‘); }”;
          eval(evalStr);
          … [appendChild to some document element]
          }

          January 20, 2005 @ 2:55 pm. Type: Comment. Permalink.
       5.
          Mark Wubben wrote:

          Gustavo, actually your first example will work because the onclick event is a closure in which str does exist.

          January 20, 2005 @ 2:59 pm. Type: Comment. Permalink.
       6.
          Brent Hendricks wrote:

          Mark,

          I have a similar situation to the one Gustavo posted, but in my case I’m setting several onclick handlers in a loop with str as the iteration variable. So even though the variable exists in the handler, it has the wrong value (the final iteration value). Is there a way to pass the value of a variable without using evalStr?

          January 22, 2005 @ 7:36 pm. Type: Comment. Permalink.
       7.
          Mark Wubben wrote:

          Brent, interesting question. Here’s an idea (haven’t tested it):

          while(str != null){

              node.onclick = (function(str){

              return function(){ alert(str); }

              })(str);

              };

          What this does is calling an anonymous function in block scope with the variable as it’s argument. This function returns a closure in which the variable is available. A new closure is returned every time the anonymous function is invoked, thus the problem of referencing the iteration variable is solved.

     
  • 相关阅读:
    Codeforces 758D:Ability To Convert(思维+模拟)
    Codeforces 758B:Blown Garland(模拟)
    BZOJ-1053 反素数
    BZOJ-1024 生日快乐
    BZOJ-1036 树的统计
    BZOJ-1029 建筑抢修
    BZOJ-1059 矩阵游戏
    BZOJ-1026 windy数
    BZOJ-1019 汉诺塔
    BZOJ-1031 字符加密
  • 原文地址:https://www.cnblogs.com/jinweijie/p/1277097.html
Copyright © 2011-2022 走看看