1,看一个平时使用jquery或者zepto的例子:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>jquery</title> </head> <body> <p>jquery 1</p> <p>jquery 2</p> <p>jquery 3</p> <div id="div1"> <p>jquery test in div</p> </div> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script> var $p = $('p'); $p.css('color', 'red'); //css是原型方法 console.log($p.html()); //html是原型方法,这里只打印第一个 jquery 1 var $div = $('#div1'); $div.find('p').css('color', 'blue'); //find,css是原型方法 console.log($div.html()); //html是原型方法 <p style="color: blue;">jquery test in div</p> </script> </body> </html>
2,zepto如何使用原型(简化版)-my-zepto.js
(function(window) { // 空对象 var zepto = {}; // 构造函数 function Z(dom, selector) { var i, len = dom ? dom.length : 0; for (i = 0; i < len; i++) { this[i] = dom[i]; } this.length = len; this.selector = selector || ''; } zepto.Z = function(dom, selector) { // 注意,出现了 new 关键字 return new Z(dom, selector); } zepto.init = function(selector) { // 源码中,这里的处理情况比较复杂,但因为本次只针对原型,因此这里就弱化了 var slice = Array.prototype.slice; var dom = slice.call(document.querySelectorAll(selector)); return zepto.Z(dom, selector); } // 使用zepto的$ var $ = function(selector) { return zepto.init(selector); } window.$ = $; $.fn = { constructor: zepto.Z, css: function(key, value) { console.log('css'); }, html: function(value) { // console.log('html'); return '这是一个模拟的html函数'; } } zepto.Z.prototype = Z.prototype = $.fn; //!!! })(window)
测试:新建zepto.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>zepto</title> </head> <body> <p>zepto 1</p> <p>zepto 2</p> <p>zepto 3</p> <div id="div1"> <p>zepto test in div</p> </div> <script src="./my-zepto.js"></script> <script> var $p = $('p'); $p.css('color', 'red'); //css是原型方法 console.log($p.html()); //html是原型方法,这是一个模拟的html函数" </script> </body> </html>
3,jquery如何使用原型(简化版)-my-jquery.js
(function(window) { var jQuery = function(selector) { // 注意new关键字,第一步就找到了构造函数 return new jQuery.fn.init(selector); } window.$ = jQuery; // 初始化 jQuery.fn jQuery.fn = jQuery.prototype = { //!!! constructor: jQuery, // 其他函数 css: function(key, value) { }, html: function(value) { return 'html'; } } // 定义构造函数-简化版 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.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>jquery</title> </head> <body> <p>jquery 1</p> <p>jquery 2</p> <p>jquery 3</p> <div id="div1"> <p>jquery test in div</p> </div> <script src="./my-jquery.js"></script> <script> var $p = $('p'); $p.css('color', 'red'); //css是原型方法 console.log($p.html()); //html是原型方法,这里只打印第一个 "jquery 1" </script> </body> </html>
4,如何体现原型的扩展性-插件机制
思考:为何要把原型方法放在$.fn?:扩展插件。
看一个简单的插件的例子:
$.fn.getNodeName = function(){ return this[0].nodeName; }
好处:
1,只有$会暴露在window全局变量
2,将插件扩展统一到 $.fn.xxx 这一个接口,方便使用
实践:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>jquery</title> </head> <body> <p>jquery 1</p> <p>jquery 2</p> <p>jquery 3</p> <div id="div1"> <p>jquery test in div</p> </div> <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script> <script> // 插件扩展 $.fn.getNodeName = function(){ // console.log(this); console.log(this[0].nodeName); } </script> <script> // 验证 var $p = $('p'); $p.getNodeName() //P $div1 = $('#div1'); $div1.getNodeName() //DIV </script> </body> </html>