Javascript 在函数上下文中使用此关键字的回调

Javascript callback using this keyword in context of function

我们正在尝试创建我们自己的 Javascript 库来替换 jQuery 并减少开销。我们想使用 this 关键字从全局范围调用函数,但脚本在我们的 foreach 循环中中断。我们如何使用 $(this).getAtt('data-src') 函数而不是 a.getAttribute('data-src')

回调内部对象或自定义 "each" 函数

this 默认为 window 的对象。这是我们库的最小化版本

var $=(function(){
    'use strict';

    var c = function(w){
        if(!w)return;
        if(w==='document'){this.elems=[document];} 
        else if(w==='window'){this.elems=[window];} 
        else {this.elems=document.querySelectorAll(w);}
    };

    c.prototype.each = function(callback){
        if(!callback || typeof callback !== 'function')return;
        for(var i = 0, length = this.elems.length; i < length; i++){callback(this.elems[i], i);}return this;
    };

    c.prototype.setAtt=function(n,v){this.each(function(item){item.setAttribute(n,v);});return this;};
    c.prototype.getAtt=function(n){return this.elems[0].getAttribute(n);};

    var init=function(w){return new c(w);};return init;
})();

function loadImgs(){
    $("img[data-src]").each(function(a,b){
        console.log(a.getAttribute('data-src'));
        console.log($(this).getAtt('data-src'));
    });
}

以及我们最小化的 HTML :

<a onclick="loadImgs();">lazyload</a><br>
<img src="spacer.gif" alt=""/></div><img class="lazyLoad" data-src="replacer.jpg" alt="">

使用 .call().

将您想要的调用上下文(元素)传递给 getAttribute 方法

如果参数是一个元素,您还需要 c 构造函数来将 elems 属性 设置为参数:

} else if (w instanceof HTMLElement) {
  this.elems = [w];
}
for (var i = 0, length = this.elems.length; i < length; i++) {
  callback.call(this.elems[i], this.elems[i], i);
  //            ^^ "this" in callback
  //                           ^^ first argument to callback
  //                                          ^^ second argument to callback
}

var $ = (function() {
  'use strict';

  var c = function(w) {
    if (!w) return;
    if (w === 'document') {
      this.elems = [document];
    } else if (w === 'window') {
      this.elems = [window];
    } else if (w instanceof HTMLElement) {
      this.elems = [w];
    } else {
      this.elems = document.querySelectorAll(w);
    }
  };

  c.prototype.each = function(callback) {
    if (!callback || typeof callback !== 'function') return;
    for (var i = 0, length = this.elems.length; i < length; i++) {
      callback.call(this.elems[i], this.elems[i], i);
    }
    return this;
  };

  c.prototype.setAtt = function(n, v) {
    this.each(function(item) {
      item.setAttribute(n, v);
    });
    return this;
  };
  c.prototype.getAtt = function(n) {
    return this.elems[0].getAttribute(n);
  };

  var init = function(w) {
    return new c(w);
  };
  return init;
})();

function loadImgs() {
  $("img[data-src]").each(function(a, b) {
    console.log(a.getAttribute('data-src'));
    console.log($(this).getAtt('data-src'));
  });
}
<a onclick="loadImgs();">lazyload</a><br>
<img src="spacer.gif" alt="" /></div><img class="lazyLoad" data-src="replacer.jpg" alt="">