ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript「jquery継承」の使い方で知っておきたいこと(詳細コード解説)

JavaScript「jquery継承」の使い方で知っておきたいこと(詳細コード解説)

奋力向前
奋力向前転載
2021-08-19 11:49:362165ブラウズ

前回の記事「JSの配列reduceメソッドを徹底分析(コード付き)」では、JSの配列reduceメソッドについて理解していただきました。次の記事では、JS 継承で jQuery を使用する方法を説明します。友人はそれを参照してください。

JavaScript「jquery継承」の使い方で知っておきたいこと(詳細コード解説)

jquery現時点ではバージョン 3.3.1 です。現在、さまざまなブラウザの普及により、フロントエンド フレームワークはjquery は世界で唯一のものです。私はコードを書くときにのみ jquery を使用します。コードを拾って実行するだけの輝かしい時代は終わりました。

2006 年に jQuery の最初のバージョンがリリースされ、その簡潔かつ柔軟なプログラミング スタイルが開発者に愛されました。これ自体は JavaScript フレームワークであり、その設計目的は「write Less, Do More」です。つまり、コードの記述を減らし、より多くのことを実行することを推奨しています。いろいろ。一般的に使用される JavaScript 関数コードをカプセル化し、シンプルな JavaScript 設計パターンを提供し、HTML ドキュメント操作、イベント処理、アニメーション設計、および Ajax# を最適化します。 ##交流。

以前に人気があり、現在は廃止されるまで、多くのフロントエンド エンジニアは、

jQuery について、多数の操作 DOM が便利ではあるものの、今後もそう言いました。ページのパフォーマンスが大幅に犠牲になります。一方、現段階では、ReactVueAngularjs などの主流のフロントエンド フレームワークは jQuery に依存していません。独立して使用できます。さらに、ブラウザの互換性の問題はますます少なくなり、ブラウザの互換性が問題でなくなると、jQuery の価値は大幅に低下します。

Microsoft が

github を買収してから 52 日目、 github 変更も放棄されました jquery、奇妙な代替案はネイティブ js を使用します:

  • は ## を使用します# querySelectorAll

    DOM ノードをクエリします;

  • ajax

    の代わりに fetch を使用します;

  • イベント処理ではイベント プロキシを使用します;
  • DOM

    標準化を使用して polyfill;## を作成します

    #カスタム要素が使用されます。

使用していなくても学習できますJavaScript「jquery継承」の使い方で知っておきたいこと(詳細コード解説)

この記事は大まかな実装です

jquery

ready, each, binding, ``$.fn.extend, $.extendInitialization

$

<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 === &quot;function&quot;) { this.elements.push(document); this.ready(selector); } else { var context = context || document; var isDocument = (ele) =&gt; Object.prototype.toString.call(ele) == &quot;[object HTMLDocument]&quot; || &quot;[object Document]&quot;; if (isDocument(selector)) { this.elements.push(selector); } else { /** * 如果是字符串的话就查询该节点 $(&amp;#39;.class&amp;#39;) | $(&amp;#39;#id&amp;#39;) */ if (context.querySelectorAll) { var arr = context.querySelectorAll(selector); for (var i = 0; i &lt; 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> 準備完了

<pre class="brush:php;toolbar:false">//实现ready ready: function (callback) { var isDocument = (ele) =&gt; Object.prototype.toString.call(ele) == &amp;#39;[object HTMLDocument]&amp;#39; || &amp;#39;[object Document]&amp;#39; //如果已经取得了节点 if (isDocument(this.elements[0])) { if (document.addEventListener) { //判断火狐、谷歌 /** * DOM树构建完成的时候就会执行DOMContentLoaded * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload * 这也就是$(document).ready() 比 window.onload 执行早的原因 * * arguments.callee 博客里面有一篇文章 [js-递归] 里面专门讲到了,这里不再解释了 */ document.addEventListener(&amp;#39;DOMContentLoaded&amp;#39;, function () { document.removeEventListener(&amp;#39;DOMContentLoaded&amp;#39;, arguments.callee, false) callback() }, false) } else if (document.attachEvent) { //判断IE document.attachEvent(&amp;#39;onreadystatechange&amp;#39;, function () { if (document.readyState == &amp;#39;complete&amp;#39;) { document.detachEvent(&amp;#39;onreadystatechange&amp;#39;, arguments.callee); callback() } }) } else if (document.lastChild == document.body) { //body已经加载完了,就直接回调了 callback() } } },</pre>

<pre class="brush:php;toolbar:false">//实现each each: function (callback) { if (this.elements.length &gt; 0) { for (var i = 0; i &lt; this.elements.length; i++) { callback.call(this, this.elements[i], i); } } },</pre>
バインド

<pre class="brush:php;toolbar:false">//实现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(&amp;#39;on&amp;#39; + type, callback) }) } else { this.each(function (item, i) { //其他浏览器 egg: item.onclick = function(){} item[&amp;#39;on&amp;#39; + type] = callback }) } }</pre>
$.fn.extend/$.extend

$.fn.extend

は、クエリ ノード オブジェクトの拡張メソッドであり、以下に基づいています。

# プロトタイプの拡張メソッド $.extend

は拡張通常メソッドであり、$

の静的メソッドです。公式の説明は次のとおりです。 :

jQuery.extend()

: 2 つ以上のオブジェクトの内容を最初のオブジェクトに結合します (2 つ以上のオブジェクトを最初のオブジェクトに結合します)

jQuery.fn.extend()

:オブジェクトのコンテンツを jQuery プロトタイプにマージして、新しい jQuery インスタンス メソッドを提供します (オブジェクトを

jQueryprototype にマウントします) Attribute、新しい 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) === &#39;[object Object]&#39;;
  $.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) === &#39;[object Object]&#39;;
...
_$.extend = function (obj) {
    if (isObj(obj)) {
        for (var i in obj) {
            this[i] = obj[i]; //注意这里的this指向是 $
        }
    }
}
と区別するためこれら 2 つはまったく同じに見えますが、違いはありません。コメントで述べたように、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.extend(object);

jQuery クラス自体を拡張するには、そのクラス自体に新しいメソッドを追加します。 $.xxx()jQuery.fn.extend(object);

メソッドを

jQuery オブジェクトに追加します$('# test').xxx()$.extend

一般的な使用法

#

//在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: &#39;http&#39;,host: &#39;chuchur.com&#39;, hash: { a: 1, b: 1,c:2 } }

var result = $.extend(false, {}, a, b);
console.log(result); //{ protocol: &#39;http&#39;,host: &#39;chuchur.com&#39;, hash: { b: 1, c:2 } }
#完全なコード # <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 === &quot;function&quot;) { this.elements.push(document); this.ready(selector); } else { var context = context || document; var isDocument = (ele) =&gt; Object.prototype.toString.call(ele) == &quot;[object HTMLDocument]&quot; || &quot;[object Document]&quot;; if (isDocument(selector)) { this.elements.push(selector); } else { /** * 如果是字符串的话就查询该节点 $(&amp;#39;.class&amp;#39;) | $(&amp;#39;#id&amp;#39;) */ if (context.querySelectorAll) { var arr = context.querySelectorAll(selector); for (var i = 0; i &lt; arr.length; i++) { this.elements.push(arr[i]); } } } } }, //实现each each: function (callback) { if (this.elements.length &gt; 0) { for (var i = 0; i &lt; this.elements.length; i++) { callback.call(this, this.elements[i], i); } } }, //实现ready ready: function (callback) { var isDocument = (ele) =&gt; Object.prototype.toString.call(ele) == &quot;[object HTMLDocument]&quot; || &quot;[object Document]&quot;; //如果已经取得了节点 if (isDocument(this.elements[0])) { if (document.addEventListener) { //判断火狐、谷歌 /** * DOM树构建完成的时候就会执行DOMContentLoaded * 页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了,才会触发window.onload * 这也就是$(document).ready() 比 window.onload 执行早的原因 * * arguments.callee 博客里面有一篇文章 js-递归里面专门讲到了,这里不再解释了 */ document.addEventListener( &quot;DOMContentLoaded&quot;, function () { document.removeEventListener( &quot;DOMContentLoaded&quot;, arguments.callee, false ); callback(); }, false ); } else if (document.attachEvent) { //判断IE document.attachEvent(&quot;onreadystatechange&quot;, function () { if (document.readyState == &quot;complete&quot;) { document.detachEvent(&quot;onreadystatechange&quot;, 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(&quot;on&quot; + type, callback); }); } else { this.each(function (item, i) { //其他浏览器 egg: item.onclick = function(){} item[&quot;on&quot; + type] = callback; }); } }, }; /** * 让两个作用于不一样的对象共享一个方法,让他们的原型指向一直,即Init.prototype = _$.prototype * 那么指向之后 就可以共享this.elements 属性了。 */ _$.prototype.Init.prototype = _$.prototype; var isObj = (o) =&gt; Object.prototype.toString().call(o) === &quot;[object Object]&quot;; $.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);</pre>【終了】

推奨学習:

jQuery ビデオ チュートリアル

以上がJavaScript「jquery継承」の使い方で知っておきたいこと(詳細コード解説)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はchuchur.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。