首页 > 代码库 > 通过jQuery源码学习javascript(一)

通过jQuery源码学习javascript(一)

  1. 构造函数(构造器)

    

    (function(){
          
            function jQuery()
            {
            
            }
            
            window.jQuery = window.$ = jQuery;
      })()
      
      console.log(jQuery);

  2.  扩展原型

  javascript为所有函数绑定一个prototype属性,由这个属性指向一个原型对象。我们在原型对象中定义类的继承属性和方法等。

       何为原型:

       原型是js实现继承的根本。

(function(){
    var jQuery = function()
    {
    
    }
    jQuery.fn = jQuery.prototype = { // jQuery.fn为后面用到的工厂对象
    
        version: ‘1.8.3‘,
        
        show: function(){
            console.log(‘hello world!!‘);
        }
    }
    
    window.jQuery = window.$ = jQuery; //实现全局调用

})();

(new jQuery()).show();

  3.  使用工厂方法创建实例

   为什么要用工程方法:

(new jQuery()).show();

   如果jQuery里面的所有方法都要通过这种方法来调用,那么就太糟糕了,产生很多对象,浪费内存。

(function(){
    var jQuery = function()
    {
        return jQuery.fn.init();
    }
    jQuery.fn = jQuery.prototype = {
    
        version: ‘1.8.3‘,
        init: function()
        {
            return this;
        },
        show: function()
        {
            console.log(‘hello world!!‘);
        }
    
    }
    window.jQuery = window.$ = jQuery;
})();

jQuery().show();

   为什么这么设计呢?

   假如这样:

(function(){
    var jQuery = function()
    {
        return this;
    }
    jQuery.fn = jQuery.prototype = {
    
        version: ‘1.8.3‘,
        show: function()
        {
            console.log(‘hello world!!‘);
        }
    
    }
    window.jQuery = window.$ = jQuery;
})();

console.log(jQuery());

   调试发现:this指向window对象。

  再假如这样:

(function(){
    var jQuery = function()
    {
        return new jQuery();
    }
    jQuery.fn = jQuery.prototype = {
    
        version: ‘1.8.3‘,
        show: function()
        {
            console.log(‘hello world!!‘);
        }
    
    }
    window.jQuery = window.$ = jQuery;
})();

console.log(jQuery());

   那么会死循环。因为 var jQuery = function(){}是构造器,每次new jQuery()都会调用这个方法。
 4. 分割作用域。

(function(){
    var jQuery = function(){
        return jQuery.fn.init();
    }
    jQuery.fn = jQuery.prototype = {
    
        version: ‘1.8.3‘,
        init: function()
        {
            this._version = ‘2.0‘;
            return this;
        }
    }
    
    window.jQuery = window.$ = jQuery;

})()

console.log(jQuery()._version);
console.log(jQuery().version);

   init()方法中的this作用域:this关键字引用了init()函数作用域所在的对象,同时也能够访问上一级对象jQuery.fn对象的作用。——这种思路会破坏作用域的独立性,对于jQuery框架来说,很可能造成消极影响。

   那么怎么实现分割呢?

(function(){
    var jQuery = function(){
        return new jQuery.fn.init();
    }
    jQuery.fn = jQuery.prototype = {
    
        version: ‘1.8.3‘,
        init: function()
        {
            this._version = ‘2.0‘;
            return this;
        }
    }
    window.jQuery = window.$ = jQuery;

})()

console.log(jQuery()._version); // 2.0
console.log(jQuery().version);  // undefined

   jQuery()返回的对象已经是  jQuery.fn.init()构造器构造的对象了。

   5. 原型传递

   如果我想返回jQuery的对象呢?

(function(){
    var jQuery = function()
    {
        return new jQuery.fn.init();
    }
    jQuery.fn = jQuery.prototype = {
        
        version: ‘1.8.3‘,
        init: function()
        {
            this._version = ‘2.0‘;
            return this;
        }
    }
    
    jQuery.fn.init.prototype = jQuery.fn;
    window.jQuery = window.$ = jQuery;

})()

console.log(jQuery()._version); // 2.0
console.log(jQuery().version);  // 1.8.3

   把init()对象的prototype指针指向jQuery.fn,这样init()里的this继承了jQuery.fn原型对象定义的方法和属性。

通过jQuery源码学习javascript(一)