JavaScript 原型的實際應用之實現一個 jQuery
阿新 • • 發佈:2019-05-22
我們平時使用jQuery大概是這樣:
let $p = $('p');
$p.css('fontSize', '40px');
我們生成jQuery例項物件後,就可以使用原型上的css(), html()等方法,這就體現了原型繼承:由建構函式生成的例項物件,可以繼承建構函式的原型物件上的屬性和方法。
我們可以試著手寫一個迷你的jQuery,思路大概是這樣:
1-通過匿名自執行函式來存放我們的程式碼,將window物件作為引數傳入,防止全域性作用域的汙染。
2-利用工廠函式,在呼叫jQuery或者$的時候,返回建構函式的例項物件
3-建構函式定義為jQuery.fn.init,初始化時處理dom元素,將dom元素繫結在例項物件上
4-將建構函式的prototype屬性指向jQuery.fn,此時建構函式的例項便可以繼承jQuery.fn裡的屬性和方法
5-jQuery.fn是一個物件,裡面存放了所有的jQuery方法,讓外部來呼叫
程式碼實現:
完整程式碼請檢視 my-jquery
// my-jquery.js (function(window) { var jQuery = function (selector) { // 通過new關鍵字,找到建構函式 return new jQuery.fn.init(selector); }; // 初始化 jQuery.fn jQuery.fn = jQuery.prototype = { constructor: jQuery, css: function(key, value) { let that = this; for (var i = 0; i < that.length; i++) { that[i].style[key] = value; } }, html: function (value) { return this[0].innerHTML; }, }; // 定義建構函式 var init = jQuery.fn.init = function(selector) { var slice = Array.prototype.slice; var dom = slice.call(document.querySelectorAll(selector)); var i, len = dom ? dom.length : 0; for (i = 0; i < len; i++) { this[i] = dom[i]; } this.length = len; this.selector = selector || ''; }; // 定義原型 init.prototype = jQuery.fn; window.$ = jQuery; })(window);
這裡有個問題:這裡為什麼不直接把init.prototype賦值為一個物件,而是要通過jQuery.fn做中轉呢?
jQuery.fn = {...};
init.prototype = jQuery.fn;
這就體現了原型的擴充套件性,jQuery.fn
| $.fn
是用來擴充套件外掛用的,將外掛擴充套件統一到$.fn.xxx
這一個介面,也是符合對修改封閉,對擴充套件開放的原則。
下面我們來寫一個簡單的jQuery外掛。
$.fn.getNodeName = function () { return this[0].nodeName; } // 測試 alert($box.getNodeName()); // DIV
小結:
本篇文章總結了以下幾個問題
- jQuery是如何使用原型的?
- 如何實現一個小型的jQuery?
- jQuery的外掛擴充套件機制