在对象文字中更改<this>

时间:2016-07-13 05:56:48

标签: javascript

我正在创建一个对象文字,我想使用保留字“this”。我遇到的问题是“this”指向对象文字中的窗口对象。我知道这在构造函数中使用时指向当前对象。有没有办法覆盖它,以便“this”指向我的对象文字?

 main = {
     run: function()
     {
         var elements = [];
         var allElements = document.querySelectorAll("*");
         for(var i = 0; i < allElements.length; i++)
         {
             if(allElements[i].nodeType != 3)
             {
                 elements.push(allElements[i]);
             }
         }
         for(var i = 0; i < elements.length; i++)
         {
             // Doesn't work
             // this.parseElement(elements[i]);

             // Works 
             main.parseElement(elements[i]);
         }
     },
     parseElement: function(e)
     {
         // Unimportant code
     } 
 }
 (function()
 {
    main.run();
 })();

1 个答案:

答案 0 :(得分:2)

您声称在您的问题中使用的内容 无法正常工作:

var main = {
     run: (function()
     {
         var elements = [];
         var allElements = document.querySelectorAll("*");
         for(var i = 0; i < allElements.length; i++)
         {
             if(allElements[i].nodeType != 3)
             {
                 elements.push(allElements[i]);
             }
         }
         for(var i = 0; i < elements.length; i++)
         {
             // Doesn't work
             // this.parseElement(elements[i]);

             // Works 
             main.parseElement(elements[i]);
         }
     })(),
     parseElement: function(e)
     {
         // Unimportant code
     } 
 };
<div></div>

从根本上说,你是cannot refer to the object being constructed from within the object initializer。您必须首先创建对象,因为在处理初始化程序期间,当对象确实存在时,您的代码无法使用它。

从名称run,您似乎希望run成为方法它不在您的代码中 < em>(你现在编辑了一个问题,使其成为一个)。只需删除函数周围的()()

var main = {
  run: function() {
    var elements = [];
    var allElements = document.querySelectorAll("*");
    for (var i = 0; i < allElements.length; i++) {
      if (allElements[i].nodeType != 3) {
        elements.push(allElements[i]);
      }
    }
    for (var i = 0; i < elements.length; i++) {
      this.parseElement(elements[i]);
    }
  },
  parseElement: function(e) {
    console.log("Parsing " + e.tagName);
  }
};
main.run();
<div></div>

由于this是由函数调用用于正常函数的方式设置的,因此如果您希望将run绑定到main,那么它就不会无论如何调用它,使用main代替this是在该代码中执行此操作的最简单方法。

但如果您不想使用main,则可以创建绑定功能:

var main = {
  run: function() {
    var elements = [];
    var allElements = document.querySelectorAll("*");
    for (var i = 0; i < allElements.length; i++) {
      if (allElements[i].nodeType != 3) {
        elements.push(allElements[i]);
      }
    }
    for (var i = 0; i < elements.length; i++) {
      this.parseElement(elements[i]);
    }
  },
  parseElement: function(e) {
    console.log("Parsing " + e.tagName);
  }
};
// Bind run
main.run = main.run.bind(main);

// Use it such that `this` would have been wrong
// if we hadn't bound it:
var f = main.run;
f();
<div></div>

作为旁注,我们可以使用Array.prototype.filterArray.prototype.forEach使代码更简洁:

var main = {
  run: function() {
    var allElements = document.querySelectorAll("*");
    var elements = Array.prototype.filter.call(allElements, function(e) {
      return e.nodeType != 3;
    });
    elements.forEach(this.parseElement, this);
  },
  parseElement: function(e) {
    console.log("Parsing " + e.tagName);
  }
};

// Use it
main.run();
<div></div>

假设parseElement只查看它给出的第一个参数(因为forEach将用三个调用它:我们正在访问的条目,它的索引和我们循环的对象通过)。