Nodejs中jQuery.fn.init.prototype = jQuery.fn;这样写好绕

Nodejs中jQuery.fn.init.prototype = jQuery.fn;这样写好绕

jQuery.fn 为一个对象的话 对象的其中一个方法的原型 是对象自己 而且new jQuery对象为什么非要套在 jQuery.prototype里面其中的一个方法init上来做构造,用个其他的函数是不是更清晰些 ?


         function F(selector, context, rootjQuery){
         return this;
         }
        F.prototype={
             each:function(){
            },
     ....
     

           }
            
        };
       var jQuery = function( selector, context ) {
         // return new jQuery.fn.init( selector, context, rootjQuery );
           return new F( selector, context, rootjQuery );
       }

这样是不是更清晰一些?


7 回复

Node.js 中 jQuery.fn.init.prototype = jQuery.fn; 这样写好绕吗?

前言

在讨论这个问题之前,我们需要了解一些背景知识。jQuery.fn 是 jQuery 的原型对象,而 jQuery.fn.init 是 jQuery 构造函数的原型。jQuery.fn.init.prototype = jQuery.fn; 这行代码的作用是将 jQuery.fn.init 的原型指向 jQuery.fn,这使得 jQuery 实例可以访问到 jQuery 的方法。

问题核心

你提到的问题主要集中在两个方面:

  1. 为什么 jQuery.fn.init.prototype 要指向 jQuery.fn
  2. 是否可以用其他方式来实现相同的功能?

解释

1. 为什么 jQuery.fn.init.prototype 要指向 jQuery.fn

jQuery.fn.init.prototype 指向 jQuery.fn 的目的是为了让通过 new jQuery.fn.init() 创建的实例能够访问到 jQuery 提供的所有公共方法。例如,你可以调用 .html(), .css() 等方法。

2. 是否可以用其他方式来实现相同的功能?

是的,你可以使用自定义的构造函数来达到类似的效果。下面是你的示例代码:

function F(selector, context, rootjQuery) {
    return this;
}

F.prototype = {
    each: function () {
        // 实现 each 方法
    },
    // 其他方法...
};

var jQuery = function (selector, context) {
    return new F(selector, context);
};

示例代码

在这个例子中,我们创建了一个名为 F 的构造函数,并将其原型设置为包含各种方法的对象。然后,我们将 jQuery 函数的返回值设置为 new F() 的结果。

优点

  • 清晰性:这种方式更直观,更容易理解。
  • 灵活性:你可以根据需要添加更多的方法到 F.prototype

缺点

  • 功能限制:这种方法可能无法完全模拟 jQuery 的所有行为,因为 jQuery.fn.init 包含了一些特殊的逻辑和初始化步骤。

结论

虽然 jQuery.fn.init.prototype = jQuery.fn; 这种写法看起来比较复杂,但它确保了 jQuery 实例能够正确地访问其原型链上的方法。如果你不需要完全模拟 jQuery 的行为,可以考虑使用更简单的构造函数方法,如上面的示例代码所示。


(1) $.fn 提供扩展插件 (2)namespace

F需要一个命名空间来放置,如果你放到windows上,则有命名冲突风险。 最后你不得不jQuery.prototype.F = function () {} jQuery.F 不会成功,因为jQuery这时候还没有建立起来. 很明显init比F更有说明性.

jQuery.fn 就是 jQuery.prototype

如果不考虑扩展插件,上面的代码是不是就够用了?

F就放在闭包里面,内部使用,对外只提供window.jQuery jQuery和F指向同一个原型就行了 jQury没有建立起来,但是F建立了,用F来做构建工作, 做完了,再让jQuery与F相同就行了,对外使用和扩展统一用jQuery


var rootjQuery;
       // 构建jQuery对象
        function F(selector, context, rootjQuery){
             console.log('F'); 
        return this;
    }
    F.prototype={
         constructor: jQuery,
         say:function(){
              console.log('hello');
         }
 
    };
   
   var jQuery = function( selector, context ) {
       console.log('jQ');
      // return new jQuery.fn.init( selector, context, rootjQuery );
       return new F( selector, context, rootjQuery );
   }

 jQuery.prototype=   F.prototype;

var a =jQuery(’#ss’); console.log(a); a.say(); jQuery.prototype.addbox=function(){

       console.log("add box ");

   }

   a.addbox();

框架和类库设计思考的区别

这个问题的核心在于理解jQuery的构造方式及其背后的原理。在Node.js环境中,直接使用jQuery并不常见,因为jQuery主要用于浏览器环境,处理DOM操作。不过,我们可以讨论一下这段代码的意义。

原始问题中的代码

原始代码中:

jQuery.fn.init.prototype = jQuery.fn;

这句话的目的是为了将jQuery.fn(即jQuery的实例方法)的原型设置为jQuery.fn.init(即jQuery构造函数的内部构造函数)。这样做是为了确保所有的jQuery实例方法都能通过构造函数初始化,并且可以链式调用。

提问者提出的替代方案

提问者提出了一种不同的构造方式,使用自定义函数F来代替jQuery.fn.init

function F(selector, context, rootjQuery) {
    return this;
}

F.prototype = {
    each: function() {},
    // 其他方法...
};

var jQuery = function(selector, context) {
    return new F(selector, context, rootjQuery);
};

解释

  1. jQuery.fn.init.prototype = jQuery.fn;:

    • 这行代码确保了jQuery实例方法可以通过构造函数初始化。
    • jQuery.fn包含了所有jQuery实例方法。
    • jQuery.fn.init是jQuery的构造函数。
  2. 提问者的替代方案:

    • 使用F函数来代替jQuery.fn.init
    • F函数简单地返回this,这并不是一个完整的解决方案,因为实际的jQuery构造过程包括许多其他逻辑,比如选择器解析、DOM操作等。

示例代码

如果你想要实现一个简单的jQuery-like库,可以参考以下示例:

function jQuery(selector, context) {
    const domElements = Array.from(context.querySelectorAll(selector));
    return {
        length: domElements.length,
        get(index) { return domElements[index]; },
        each(callback) { domElements.forEach((el, i) => callback.call(el, i, el)); }
        // 添加更多方法...
    };
}

const $ = jQuery;

// 使用示例
$(document).ready(function() {
    $('div').each(function(i, el) {
        console.log(i, el);
    });
});

这个简单的示例展示了如何创建一个类似jQuery的对象,包含选择器解析和基本的遍历功能。

回到顶部