Home > Article > Web Front-end > What you need to know about the use of JavaScript "jquery inheritance" (detailed code explanation)
In the previous article "In-depth analysis of the array reduce method in JS (with code)", I will give you an understanding of the array reduce method in JS. The following article will teach you how to use jquery in JS-inheritance. Friends can refer to it.
jquery
As of now, it is version 3.3.1. Nowadays, with the popularity of various browsers, front-end frameworks are emerging in endlessly. jquery
is unique in the world. I only use jquery
when writing code. The glorious era of just picking up the code and doing it has passed.
In 2006, the first version of jQuery
was released. It was loved by developers for its concise and flexible programming style. And it itself is a JavaScript
framework. Its design purpose is "write Less
, Do More
", that is, it advocates writing less code and doing more. Many things. It encapsulates JavaScript
commonly used function codes, provides a simple JavaScript
design pattern, and optimizes HTML
document operations, event processing, animation design and Ajax
interaction.
From being popular before to being abandoned now, many front-end engineers said that for jQuery
, although a large number of operations DOM
are convenient, But it will sacrifice a lot of page performance. On the other hand, at this stage, mainstream front-end frameworks such as React
, Vue
and Angularjs
do not rely on jQuery
and can be used independently. Moreover, there are fewer and fewer browser compatibility issues. When browser compatibility is no longer a problem, the value of jQuery will be greatly reduced.
On the 52nd day after Microsoft acquired github
, github
The change has also been abandoned jquery
, the odd alternative uses the native js
:
uses querySelectorAll
to query DOM
nodes;
Use fetch
instead of ajax
;
Event processing uses event proxies;
Using DOM
standardization to write polyfill
;
Custom elements are used.
If you don’t use it, you can still learn it
This article is a rough implementationjquery
ready, each, bind, ``$.fn.extend, $.extend
Initialization$
(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) {}, //实现ready ready: function (callback) {}, //实现bind bind: function (type, callback) {}, }; /** * 让两个作用域不一样的对象共享一个方法,让他们的原型指向一致,即Init.prototype = _$.prototype * 那么原型一致之后 就可以共享this.elements 属性了。 */ _$.prototype.Init.prototype = _$.prototype; window.$ = _$; })(window || global);
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 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
is an extension method for the query node object, which is based on $
The prototype extension method
$.extend
is an extension regular method and a static method of $
The official explanation is:
jQuery.extend()
: Merge the contents of two or more objects together into the first object. (Merge two or more objects into the first one)
jQuery.fn.extend()
:Merge the contents of an object onto the jQuery prototype to provide new jQuery instance methods. (Mount the object into jQuery
prototype
Attribute, to extend a new jQuery
instance method)
$.fn.extend
The original intention of the method is that we can use $( "").newMetod()
Accessing in this way is actually adding an extend
method to the $
prototype. The fn
in the middle is actually similar to the role of a namespace and has no practical significance. To distinguish it from $.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 } } }
$.extend
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指向是 $ } } }
These two look exactly the same, there is no difference. As mentioned in the comments, this
points to different points. Let’s take a look at an example:
<!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>
Now it’s clear. jQuery.extend(object);
To extend the jQuery
class itself, add new methods to itself. $.xxx()
jQuery.fn.extend(object);
Add methods to jQuery
objects$('# test').xxx()
##$.extendCommon usage
//在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 } }
Complete code
(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);【End】 Recommended learning:
The above is the detailed content of What you need to know about the use of JavaScript "jquery inheritance" (detailed code explanation). For more information, please follow other related articles on the PHP Chinese website!