之前的文章《深入解析JS中數組reduce方法(附程式碼)》中,給大家了解JS中數組reduce方法。以下這篇文章給大家了解JS-繼承之jquery使用方法,小夥伴可以參考一下。
jquery
截止到目前已經3.3.1 版本了,如今隨著各種瀏覽器的盛行,前端的框架層出不窮, jquery
獨步天下,老夫寫程式只用jquery
,拿起程式碼就是乾的輝煌時代已經過去了。
2006 年,jQuery
的第一個版本的面世,憑藉著簡潔、靈活的程式設計風格受到了開發者的喜愛。而它本身就是一個JavaScript
框架,它的設計的宗旨是“write Less
,Do More
”,即倡導寫更少的程式碼,做更多的事情。它封裝了JavaScript
常用的功能程式碼,提供一個簡單的JavaScript
設計模式,優化HTML
文件操作、事件處理、動畫設計和 Ajax
互動。
從之前的風靡到如今的被拋棄,究其原因,不少前端工程師表示,對於jQuery
來說,大量的操作DOM
雖然方便,但是會犧牲很多頁面的效能。另一方面,現階段React
、Vue
和Angularjs
等主流前端框架並不依賴jQuery
,都可以獨立使用。況且瀏覽器的相容問題越來越少,當瀏覽器相容不再是問題時,jQuery的價值就大打折扣了
就在微軟收購github
的52 天,github
改變也已經放棄了jquery
,奇人替代方案使用了原生的 js
:
querySelectorAll來查詢
DOM節點;
fetch來取代
ajax;
事件處理使用了事件代理程式;
DOM標準化寫了polyfill
;
使用了自訂元素。
假如不用,學習下還是可以的
本文粗燥的實作jquery
的
ready、each、bind、``$.fn.extend、$.extend
#初始化
##<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">(function (win) {
var _$ = function (selector, context) {
/**
* 通常咱们定义一个 函数 var Fun = function(){}
* 然后定义一个 Fun.prototype.init = function(){}
* 那么咱们调用init 的时候 得先要实例化对象 var f = new Fun()
* 然后f.init()
* 这里就省去了 var $ = new $()
*/
return new _$.prototype.Init(selector, context);
};
_$.prototype = {
//初始化$
Init: function (selector, context) {
this.elements = [];
/**
* 传入的类型是function 就执行ready事件,如果是document 就将document对象插入到this.elements
* 主要就是判断$(document).ready 和 $(function(){}) 这两种的ready事件的写法
*/
if (typeof selector === "function") {
this.elements.push(document);
this.ready(selector);
} else {
var context = context || document;
var isDocument = (ele) =>
Object.prototype.toString.call(ele) == "[object HTMLDocument]" ||
"[object Document]";
if (isDocument(selector)) {
this.elements.push(selector);
} else {
/**
* 如果是字符串的话就查询该节点 $(&#39;.class&#39;) | $(&#39;#id&#39;)
*/
if (context.querySelectorAll) {
var arr = context.querySelectorAll(selector);
for (var i = 0; i < arr.length; i++) {
this.elements.push(arr[i]);
}
}
}
}
},
//实现each
each: function (callback) {},
//实现ready
ready: function (callback) {},
//实现bind
bind: function (type, callback) {},
};
/**
* 让两个作用域不一样的对象共享一个方法,让他们的原型指向一致,即Init.prototype = _$.prototype
* 那么原型一致之后 就可以共享this.elements 属性了。
*/
_$.prototype.Init.prototype = _$.prototype;
window.$ = _$;
})(window || global);</pre><div class="contentsignin">登入後複製</div></div>
ready
//实现ready ready: function (callback) { var isDocument = (ele) => Object.prototype.toString.call(ele) == '[object HTMLDocument]' || '[object Document]' //如果已经取得了节点 if (isDocument(this.elements[0])) { if (document.addEventListener) { //判断火狐、谷歌 /** * DOM树构建完成的时候就会执行DOMContentLoaded * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload * 这也就是$(document).ready() 比 window.onload 执行早的原因 * * arguments.callee 博客里面有一篇文章 [js-递归] 里面专门讲到了,这里不再解释了 */ document.addEventListener('DOMContentLoaded', function () { document.removeEventListener('DOMContentLoaded', arguments.callee, false) callback() }, false) } else if (document.attachEvent) { //判断IE document.attachEvent('onreadystatechange', function () { if (document.readyState == 'complete') { document.detachEvent('onreadystatechange', arguments.callee); callback() } }) } else if (document.lastChild == document.body) { //body已经加载完了,就直接回调了 callback() } } },
each#//实现each
each: function (callback) {
if (this.elements.length > 0) {
for (var i = 0; i < this.elements.length; i++) {
callback.call(this, this.elements[i], i);
}
}
},
//实现bind bind: function (type, callback) { if (document.addEventListener) { //判断火狐、谷歌 this.each(function (item, i) { item.addEventListener(type, callback, false) }) } else if (document.attachEvent) { //判断IE this.each(function (item, i) { item.attachEvent('on' + type, callback) }) } else { this.each(function (item, i) { //其他浏览器 egg: item.onclick = function(){} item['on' + type] = callback }) } }
$.fn.extend/$.extend$.fn.extend
是為查詢的節點物件擴充方法,是基於
$的原型擴充的方法
$.extend
是擴充常規方法,是$的靜態方法
官方給出解釋:
#jQuery.extend(): Merge the contents of two or more objects together into the first object.(把兩個或更多的物件合併到第一個當中)
#jQuery.fn.extend():Merge the contents of an object onto the jQuery prototype to provide new jQuery instance methods.(把物件掛載到
jQuery
prototype屬性,來擴充一個新的
jQuery實例方法)
$.fn.extend
$( "").newMetod()這樣訪問,實際上就是給
$原型加一個
extend方法。這中間的
fn
$.extend作區分$.fn.extend
; (function (win) { ... _$.prototype.Init.prototype = _$.prototype; _$.fn = _$.prototype; //把对象挂载到jQuery的prototype属性 var isObj = (o) => Object.prototype.toString().call(o) === '[object Object]'; $.fn.extend = function (obj) { if (isObj(obj)) { for (var i in obj) { this[i] = obj //注意这里的this指向是 $.prototype } } }
#
var isObj = (o) => Object.prototype.toString().call(o) === '[object Object]'; ... _$.extend = function (obj) { if (isObj(obj)) { for (var i in obj) { this[i] = obj[i]; //注意这里的this指向是 $ } } }
this指向不同。咱們來看個例子:
<!DOCTYPE html> <html> <head> <title>jQuery.extend()与jQuery.fn.extend()区别</title> <meta charset="utf-8" /> <script type="text/javascript" src="jquery.js"></script> <!-- 开始扩展 --> <script type="text/javascript"> (function ($) { $.extend({ sayHello: function () { console.log("Hello"); }, }); $.fn.extend({ sayHello: function () { console.log("Hello"); }, }); })(jQuery); </script> <!-- 调用 --> <script type="text/javascript"> $(document).ready(function () { //$.extend扩展调用 $.sayHello(); //$.fn.extend扩展调用 $("#test").sayHello(); }); </script> </head> <body> <div id="test"></div> </body> </html>
//在jquery全局对象中扩展一个net命名空间。 $.extend({ net: {} }); //方法扩展到之前扩展的Jquery的net命名空间中去。 $.extend($.net, { sayHello: function () { console.log("Hello"); }, }); //extend方法还有一个重载原型 //extend(boolean,dest,src1,src2,src3...),第一个参数boolean代表是否进行深度拷贝 var a = { protocol: "http", hash: { a: 1, b: 2 } }; var b = { host: "chuchur.com", hash: { b: 1, c: 2 } }; var result = $.extend(true, {}, a, b); console.log(result); //{ protocol: 'http',host: 'chuchur.com', hash: { a: 1, b: 1,c:2 } } var result = $.extend(false, {}, a, b); console.log(result); //{ protocol: 'http',host: 'chuchur.com', hash: { b: 1, c:2 } }
(function (win) { var _$ = function (selector, context) { /** * 通常咱们定义一个 函数 var Fun = function(){} * 然后定义一个 Fun.prototype.init = function(){} * 那么咱们调用init 的时候 得先要实例化对象 var f = new Fun() * 然后f.init() * 这里就省去了 var $ = new $() */ return new _$.prototype.Init(selector, context); }; _$.prototype = { //初始化$ Init: function (selector, context) { this.elements = []; /** * 传入的类型是function 就执行ready事件,如果是document 就将document对象插入到this.elements * 主要就是判断$(document).ready 和 $(function(){}) 这两种的ready事件的写法 */ if (typeof selector === "function") { this.elements.push(document); this.ready(selector); } else { var context = context || document; var isDocument = (ele) => Object.prototype.toString.call(ele) == "[object HTMLDocument]" || "[object Document]"; if (isDocument(selector)) { this.elements.push(selector); } else { /** * 如果是字符串的话就查询该节点 $('.class') | $('#id') */ if (context.querySelectorAll) { var arr = context.querySelectorAll(selector); for (var i = 0; i < arr.length; i++) { this.elements.push(arr[i]); } } } } }, //实现each each: function (callback) { if (this.elements.length > 0) { for (var i = 0; i < this.elements.length; i++) { callback.call(this, this.elements[i], i); } } }, //实现ready ready: function (callback) { var isDocument = (ele) => Object.prototype.toString.call(ele) == "[object HTMLDocument]" || "[object Document]"; //如果已经取得了节点 if (isDocument(this.elements[0])) { if (document.addEventListener) { //判断火狐、谷歌 /** * DOM树构建完成的时候就会执行DOMContentLoaded * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload * 这也就是$(document).ready() 比 window.onload 执行早的原因 * * arguments.callee 博客里面有一篇文章 js-递归里面专门讲到了,这里不再解释了 */ document.addEventListener( "DOMContentLoaded", function () { document.removeEventListener( "DOMContentLoaded", arguments.callee, false ); callback(); }, false ); } else if (document.attachEvent) { //判断IE document.attachEvent("onreadystatechange", function () { if (document.readyState == "complete") { document.detachEvent("onreadystatechange", arguments.callee); callback(); } }); } else if (document.lastChild == document.body) { //body已经加载完了,就直接回调了 callback(); } } }, //实现bind bind: function (type, callback) { if (document.addEventListener) { //判断火狐、谷歌 this.each(function (item, i) { item.addEventListener(type, callback, false); }); } else if (document.attachEvent) { //判断IE this.each(function (item, i) { item.attachEvent("on" + type, callback); }); } else { this.each(function (item, i) { //其他浏览器 egg: item.onclick = function(){} item["on" + type] = callback; }); } }, }; /** * 让两个作用于不一样的对象共享一个方法,让他们的原型指向一直,即Init.prototype = _$.prototype * 那么指向之后 就可以共享this.elements 属性了。 */ _$.prototype.Init.prototype = _$.prototype; var isObj = (o) => Object.prototype.toString().call(o) === "[object Object]"; $.fn.extend = function (obj) { if (isObj(obj)) { for (var i in obj) { this[i] = obj; //注意这里的this指向是 $.prototype } } //....这里是简写 }; _$.extend = function (obj) { if (isObj(obj)) { for (var i in obj) { this[i] = obj[i]; //注意这里的this指向是 $ } } //....这里是简写 }; window.$ = _$; })(window || global);
以上是你值得了解的JavaScript「繼承之jquery」使用方法(程式碼詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!