javascript - 了解 jQuery 在内部是如何工作的

标签 javascript jquery

所以我想了解 jQuery在内部工作。 jQuery公开一个全局 $变量,可以像这样使用:

$('.abc') // returns a list of DOM nodes having class abc
$.ajax() // used to perform AJAX requests

如您所见,$是一个函数,来自语句 1,而它是一个对象,来自语句 2。现在我知道这是可能的,因为 function Objects在 JavaScript 中,这意味着函数也是 Object在 JavaScript 中,因此您可以将方法附加到它。但我不确定这是如何在内部实现的?

我在看 this博客文章解释了如何使用“构造器模式”来模仿 jQuery,但是如何在 $ 上附加方法?使用那种模式?还是 jQuery 使用了一些完全不同的模式?这是 jQuery 的一个小实现。这段代码可以做$(selector) , 但是我如何添加 $.method在里面?

// Mini jQuery implementation 
var $ = (function() {
  var JQuery = function(selector) {
    if (selector === "document") {
      this.elements = [document];
    } else if (selector === "window") {
      this.elements = [window];
    } else {
      this.elements = document.querySelectorAll(selector);
    }
    return this;
  };

  JQuery.prototype.each = function(callback) {
    this.elements.forEach(function(element) {
      callback(element);
    });
    return this;
  };

  JQuery.prototype.addClass = function() {
    if (arguments.length === 0) return this;
    else {
      this.each(element => {
        element.classList.add(...arguments);
      });
      return this;
    }
  };

  return function(selector) {
    return new JQuery(selector);
  };
})();

// Use our mini jQuery to turn background of matching Nodes green
$(".abc").addClass("highlight");
.abc {
  background : red;
}

.abc.highlight {
  background: green;
}
		<div class="abc">Node 1</div>
		<div class="abc">Node 2</div>

最佳答案

构造函数模式实际上并没有解决$.method的问题,如果要达到$.method您必须解决一些问题,这是基于您的示例的简单解决方案:

var $ = (function() {
  
  var JQuery = function(selector) {
    if (selector === "document") {
      this.elements = [document];
    } else if (selector === "window") {
      this.elements = [window];
    } else {
      this.elements = document.querySelectorAll(selector);
    }
    return this;
  };

  JQuery.prototype.each = function(callback) {
    this.elements.forEach(function(element) {
      callback(element);
    });
    return this;
  };

  JQuery.prototype.addClass = function() {
    if (arguments.length === 0) return this;
    else {
      this.each(element => {
        element.classList.add(...arguments);
      });
      return this;
    }
  };

  return function(selector) {
    
    // A simple function for extending object properties/values to another object
    $.extend = JQuery.prototype.extend = function(source) {
      if (typeof arguments[0] !== 'object') return;

      for (var prop in source) {
        if (source.hasOwnProperty(prop)) {
          this[prop] = source[prop];
        }
      }
    };
    
    // Extend all the JQuery prototype methods to the '$' object
    $.extend(JQuery.prototype);
    
    // Others extensions that's can only accessed via '$.method' and not '$('selector').method'
    $.extend({
      ajax: function() {},
      noop: function() {},
    });
    
    return new JQuery(selector);
  };
})();

// Use our mini jQuery to turn background of matching Nodes green
$("body").addClass("highlight");
$.addClass.call($('body'), 'selected');
jQuery 不使用 $ 的构造函数模式。或 jQuery对象,如果您检查 this你可以看到那是$jQuery只是init函数的构造函数jQuery.fn.init定义 here ,所有初始化的jQuery对象$("body")方法附在 jQuery.fn ( jQuery.prototype 的别名)(这是一个示例 here ),其他方法如 ajax , noop , isReady直接附加到 $对象(ajax 方法示例 here )。这就是为什么我们可以使用 $.method 访问这些方法的原因。句法。
对不起我的英语不好,我希望这对你有意义。
编辑1:对于任何对 jQuery 内部工作方式感兴趣并想了解更多关于 jQuery 核心的人,我已经创建了这个 github repo how-jQuery-work尤其是为此目的。谢谢!

关于javascript - 了解 jQuery 在内部是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60919267/

相关文章:

javascript - 如何在 Android 中为 WebView 中的 Javascript 转义 MathML 字符串

javascript - 如何水平显示子菜单?

php - 使用 Jquery/Ajax 更新购物车

javascript - jquery 水平动画在 ipad 和平板电脑上失败

javascript - 多个复选框 jquery 手动单击复选框触发,但 'code clicked' 一个不触发

javascript - div .height() 在调整大小后更改而不告诉它

javascript - JS倒计时时钟不倒计时

javascript - 函数在第一次点击后表现异常

javascript - react / typescript : pushing obj into array of object and undefined type

javascript - jQuery :contains selector always triggering?