(function(){ var jQuery = function() { // 函數體 } window.jQuery = window.$ = jQuery; })(); console.log(jQuery);
輸出結果

上面的空函數就是所謂的構造函數,構造函數在面向對象語言中是類的一個基本方法。
(function(){ var jQuery = function() { // 函數體 } jQuery.fn = jQuery.prototype = { // 擴展原型對象 jquery: "1.8.3", test: function() { console.log('test'); } } window.jQuery = window.$ = jQuery; })(); (new jQuery()).test();
上面的方法必須使用下面的方法才能進行調用,這樣就會產生很多對象,從而浪費內存消耗。
(new jQuery()).test();
jQuery源碼使用了很柔和的方法,也是大家比較熟悉的工廠方法,進行調用。
(function(){ var jQuery = function() { // 函數體 return jQuery.fn.init(); } jQuery.fn = jQuery.prototype = { // 擴展原型對象 jquery: "1.8.3", init: function() { return this; }, test: function() { console.log('test'); } } window.jQuery = window.$ = jQuery; })(); jQuery().test();

假想1:讓jQuery函數體直接返回該對象——我用this
(function(){ var jQuery = function() { return this; } jQuery.fn = jQuery.prototype = { // 擴展原型對象 jquery: "1.8.3", test: function() { console.log('test'); } } window.jQuery = window.$ = jQuery; })(); console.log(jQuery());
輸出結果

發現這里的this指向Window對象。
假想2:讓jQuery函數體直接返回類的實例。
(function(){ var jQuery = function() { return new jQuery(); } jQuery.fn = jQuery.prototype = { // 擴展原型對象 jquery: "1.8.3", test: function() { console.log('test'); } } window.jQuery = window.$ = jQuery; })(); console.log(jQuery());
輸出結果

發現上面是一個遞歸死循環,出現內存外溢。
思考1:init()方法返回的this作用域是什么?
(function(){ var jQuery = function() { // 函數體 return jQuery.fn.init(); } jQuery.fn = jQuery.prototype = { // 擴展原型對象 jquery: "1.8.3", init: function() { this.init_jquery = '2.0'; return this; } } window.jQuery = window.$ = jQuery; })(); console.log(jQuery().jquery); console.log(jQuery().init_jquery);
輸出結果

init()方法中的this作用域:this關鍵字引用了init()函數作用域所在的對象,同時也能夠訪問上一級對象jQuery.fn對象的作用。——這種思路會破壞作用域的獨立性,對於jQuery框架來說,很可能造成消極影響。
思考2:怎么把init()中的this從jQuery.fn對象中分隔出來?——實例化init初始化類型。
(function(){ var jQuery = function() { // 函數體 return new jQuery.fn.init(); } jQuery.fn = jQuery.prototype = { // 擴展原型對象 jquery: "1.8.3", init: function() { this.init_jquery = '2.0'; return this; } } window.jQuery = window.$ = jQuery; })(); console.log(jQuery().jquery); console.log(jQuery().init_jquery);
輸出結果

通過實例化init()初始化類型,限定了init()方法里的this,只在init()函數內活動,不讓它超出范圍。
jQuery.fn.init.prototype = jQuery.fn;
全部代碼:
(function(){ var jQuery = function() { // 函數體 return new jQuery.fn.init(); } jQuery.fn = jQuery.prototype = { // 擴展原型對象 jquery: "1.8.3", init: function() { this.init_jquery = '2.0'; return this; } } jQuery.fn.init.prototype = jQuery.fn; window.jQuery = window.$ = jQuery; })(); console.log(jQuery().jquery); console.log(jQuery().init_jquery);
輸出結果

妙棋
把init()對象的prototype指針指向jQuery.fn。——這樣init()里的this繼承了jQuery.fn原型對象定義的方法和屬性。
