国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

前端基礎(chǔ)進(jìn)階(十一):詳細(xì)圖解jQuery對(duì)象,以及如何擴(kuò)展jQuery插件

RebeccaZhong / 337人閱讀

摘要:而在構(gòu)造函數(shù)中,返回了的實(shí)例對(duì)象。在中直接返回過的實(shí)例,這里的是的真正構(gòu)造函數(shù)最后對(duì)外暴露入口時(shí),將字符與對(duì)等起來。因此當(dāng)我們直接使用創(chuàng)建一個(gè)對(duì)象時(shí),實(shí)際上是創(chuàng)建了一個(gè)的實(shí)例,這里的正真構(gòu)造函數(shù)是原型中的方法。

早幾年學(xué)習(xí)前端,大家都非常熱衷于研究jQuery源碼。我還記得當(dāng)初從jQuery源碼中學(xué)到一星半點(diǎn)應(yīng)用技巧的時(shí)候常會(huì)有一種發(fā)自內(nèi)心的驚嘆,“原來JavaScript居然可以這樣用!”

雖然隨著前端的發(fā)展,另外幾種前端框架的崛起,jQuery慢慢變得不再是必須。因此大家對(duì)于jQuery的熱情低了很多。但是許多從jQuery中學(xué)到的技巧用在實(shí)際開發(fā)中仍然非常好用。簡(jiǎn)單的了解它也有助于我們更加深入的理解JavaScript。

這篇文章的主要目的就是跟大家分享一下,jquery對(duì)象是如何封裝的。算是對(duì)于大家進(jìn)一步學(xué)習(xí)jQuery源碼的一個(gè)拋磚引玉。

使用jQuery對(duì)象時(shí),我們這樣寫:

// 聲明一個(gè)jQuery對(duì)象
$(".target")

// 獲取元素的css屬性
$(".target").css("width")

// 獲取元素的位置信息
$(".target").offset()

在使用之初可能會(huì)有許多疑問,比如$是怎么回事?為什么不用new就可以直接聲明一個(gè)對(duì)象等等。后來了解之后,才知道原來這正是jQuery對(duì)象創(chuàng)建的巧妙之處。

先直接用代碼展示出來,再用圖跟大家解釋是怎么回事。

;
(function(ROOT) {

    // 構(gòu)造函數(shù)
    var jQuery = function(selector) {

        // 在jQuery中直接返回new過的實(shí)例,這里的init是jQuery的真正構(gòu)造函數(shù)
        return new jQuery.fn.init(selector)
    }

    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,

        version: "1.0.0",

        init: function(selector) {
            // 在jquery中這里有一個(gè)復(fù)雜的判斷,但是這里我做了簡(jiǎn)化
            var elem, selector;
             elem = document.querySelector(selector);
            this[0] = elem;

            // 在jquery中返回一個(gè)由所有原型屬性方法組成的數(shù)組,我們這里簡(jiǎn)化,直接返回this即可
            // return jQuery.makeArray(selector, this);
            return this;
        },

        // 在原型上添加一堆方法
        toArray: function() {},
        get: function() {},
        each: function() {},
        ready: function() {},
        first: function() {},
        slice: function() {}
        // ... ...
    }

    jQuery.fn.init.prototype = jQuery.fn;

    // 實(shí)現(xiàn)jQuery的兩種擴(kuò)展方式
    jQuery.extend = jQuery.fn.extend = function(options) {

        // 在jquery源碼中會(huì)根據(jù)參數(shù)不同進(jìn)行很多判斷,我們這里就直接走一種方式,所以就不用判斷了
        var target = this;
        var copy;

        for(name in options) {
            copy = options[name];
            target[name] = copy;
        }
        return target;
    }

    // jQuery中利用上面實(shí)現(xiàn)的擴(kuò)展機(jī)制,添加了許多方法,其中

    // 直接添加在構(gòu)造函數(shù)上,被稱為工具方法
    jQuery.extend({
        isFunction: function() {},
        type: function() {},
        parseHTML: function() {},
        parseJSON: function() {},
        ajax: function() {}
        // ...
    })

    // 添加到原型上
    jQuery.fn.extend({
        queue: function() {},
        promise: function() {},
        attr: function() {},
        prop: function() {},
        addClass: function() {},
        removeClass: function() {},
        val: function() {},
        css: function() {}
        // ...
    })

    // $符號(hào)的由來,實(shí)際上它就是jQuery,一個(gè)簡(jiǎn)化的寫法,在這里我們還可以替換成其他可用字符
    ROOT.jQuery = ROOT.$ = jQuery;

})(window);

在上面的代碼中,我封裝了一個(gè)簡(jiǎn)化版的jQuery對(duì)象。它向大家簡(jiǎn)單展示了jQuery的整體框架情況。如果了解了整體框架,那么大家去讀jQuery源碼,就會(huì)變得非常輕松。

我們?cè)诖a中可以看到,jQuery自身對(duì)于原型的處理使用了一些巧妙的語法,比如jQuery.fn = jQuery.prototypejQuery.fn.init.prototype = jQuery.fn;等,這幾句正式j(luò)Query對(duì)象的關(guān)鍵所在,下面我用圖給大家展示一下這中間的邏輯是怎么回事。

對(duì)象封裝分析

在上面的實(shí)現(xiàn)中,代碼首先在jQuery構(gòu)造函數(shù)中聲明了一個(gè)fn屬性,并將其指向了原型jQuery.prototype。并在原型中添加了init方法。

jQuery.fn = jQuery.prototype = {
    init: {}
}

之后又將init的原型,指向了jQuery.prototype。

jQuery.fn.init.prototype = jQuery.fn;

而在構(gòu)造函數(shù)jQuery中,返回了init的實(shí)例對(duì)象。

var jQuery = function(selector) {

    // 在jQuery中直接返回new過的實(shí)例,這里的init是jQuery的真正構(gòu)造函數(shù)
    return new jQuery.fn.init(selector)
}

最后對(duì)外暴露入口時(shí),將字符$jQuery對(duì)等起來。

ROOT.jQuery = ROOT.$ = jQuery;

因此當(dāng)我們直接使用$("#test")創(chuàng)建一個(gè)對(duì)象時(shí),實(shí)際上是創(chuàng)建了一個(gè)init的實(shí)例,這里的正真構(gòu)造函數(shù)是原型中的init方法。

注意:許多對(duì)jQuery內(nèi)部實(shí)現(xiàn)不太了解的盆友,在使用jQuery時(shí)常常會(huì)毫無節(jié)制使用$(),比如對(duì)于同一個(gè)元素的不同操作:

var width = parseInt($("#test").css("width"));
if(width > 20) {
    $("#test").css("backgroundColor", "red");
}

通過我們上面的一系列分析,我們知道每當(dāng)我們執(zhí)行$()時(shí),就會(huì)重新生成一個(gè)init的實(shí)例對(duì)象,因此當(dāng)我們這樣沒有節(jié)制的使用jQuery時(shí)是非常不正確的,雖然看上去方便了一些,但是對(duì)于內(nèi)存的消耗是非常大的。正確的做法是既然是同一個(gè)對(duì)象,那么就用一個(gè)變量保存起來后續(xù)使用即可。

var $test = $("#test");
var width = parseInt($test.css("width"));
if(width > 20) {
    $test.css("backgroundColor", "red");
}

擴(kuò)展方法分析

在上面的代碼實(shí)現(xiàn)中,我還簡(jiǎn)單實(shí)現(xiàn)了兩個(gè)擴(kuò)展方法。

jQuery.extend = jQuery.fn.extend = function(options) {

    // 在jquery源碼中會(huì)根據(jù)參數(shù)不同進(jìn)行很多判斷,我們這里就直接走一種方式,所以就不用判斷了
    var target = this;
    var copy;

    for(name in options) {
        copy = options[name];
        target[name] = copy;
    }
    return target;
}

要理解它的實(shí)現(xiàn),我們首先要明確的知道this的指向。如果你搞不清楚,可以回頭去看看我們之前關(guān)于this指向的講解。傳入的參數(shù)options對(duì)象為一個(gè)key: value模式的對(duì)象,我通過for in遍歷options,將key作為jQuery的新屬性,value作為該新屬性所對(duì)應(yīng)的新方法,分別添加到j(luò)Query方法和jQuery.fn中。

也就是說,當(dāng)我們通過jQuery.extend擴(kuò)展jQuery時(shí),方法被添加到了jQuery構(gòu)造函數(shù)中,而當(dāng)我們通過jQuery.fn.extend擴(kuò)展jQuery時(shí),方法被添加到了jQuery原型中。

上面的例子中,我也簡(jiǎn)單展示了在jQuery內(nèi)部,許多方法的實(shí)現(xiàn)都是通過這兩個(gè)擴(kuò)展方法來完成的。

當(dāng)我們通過上面的知識(shí)了解了jQuery的大體框架之后,那么我們對(duì)于jQuery的學(xué)習(xí)就可以具體到諸如css/val/attr等方法是如何實(shí)現(xiàn)這樣的程度,那么源碼學(xué)習(xí)起來就會(huì)輕松很多,也會(huì)節(jié)約更多的時(shí)間。也給一些對(duì)于源碼敬而遠(yuǎn)之的朋友提供了一個(gè)學(xué)習(xí)的可能。

有一個(gè)朋友留言給我,說她被靜態(tài)方法,工具方法和實(shí)例方法這幾個(gè)概念困擾了很久,到底他們有什么區(qū)別?

其實(shí)在上一篇文章中,關(guān)于封裝一個(gè)對(duì)象,我跟大家分享了一個(gè)非常非常干貨,但是卻只有少數(shù)幾個(gè)讀者老爺get到的知識(shí),那就是在封裝對(duì)象時(shí),屬性和方法可以具體放置的三個(gè)位置,并且對(duì)于這三個(gè)位置的不同做了一個(gè)詳細(xì)的解讀。

而在實(shí)現(xiàn)jQuery擴(kuò)展方法的想法中,一部分方法需要擴(kuò)展到j(luò)Query構(gòu)造函數(shù)中,一部分方法需要擴(kuò)展到原型中,當(dāng)我們通讀jQuery源碼,還發(fā)現(xiàn)有一些方法放在了模塊作用域中,至于為什么會(huì)有這樣的區(qū)別,建議大家回過頭去讀讀前一篇文章。

而放在構(gòu)造函數(shù)中的方法,因?yàn)槲覀冊(cè)谑褂脮r(shí),不需要聲明一個(gè)實(shí)例對(duì)象就可以直接使用,因此這樣的方法常常被叫做工具方法,或者所謂的靜態(tài)方法。工具方法在使用時(shí)因?yàn)椴挥脛?chuàng)建新的實(shí)例,因此相對(duì)而言效率會(huì)高很多,但是并不節(jié)省內(nèi)存。

而工具方法的特性也和工具一詞非常貼近,他們與實(shí)例的自身屬性毫無關(guān)聯(lián),僅僅只是實(shí)現(xiàn)一些通用的功能,我們可以通過$.each$("div").each這2個(gè)方法來體會(huì)工具方法與實(shí)例方法的不同之處。

在實(shí)際開發(fā)中,我們運(yùn)用得非常多的一個(gè)工具庫(kù)就是lodash.js,大家如果時(shí)間充裕一定要去學(xué)習(xí)一下他的使用。

$.ajax()
$.isFunction()
$.each()
... ...

而放在原型中的方法,在使用時(shí)必須創(chuàng)建了一個(gè)新的實(shí)例對(duì)象才能訪問,因此這樣的方法叫做實(shí)例方法。也正是由于必須創(chuàng)建了一個(gè)實(shí)例之后才能訪問,所以他的使用成本會(huì)比工具方法高很多。但是節(jié)省了內(nèi)存。

$("#test").css()
$("#test").attr()
$("div").each()

這樣,那位同學(xué)的疑問就很簡(jiǎn)單的被搞定了。我們?cè)趯W(xué)習(xí)的時(shí)候,一定不要過分去糾結(jié)一些概念,而要明白具體怎么回事兒,那么學(xué)習(xí)這件事情就不會(huì)在一些奇奇怪怪的地方卡住了。

所以通過$.extend擴(kuò)展的方法,其實(shí)就是對(duì)工具方法的擴(kuò)展,而通過$.fn.extend擴(kuò)展的方法,就是對(duì)于實(shí)例方法的擴(kuò)展。那么我們?cè)谑褂玫臅r(shí)候就知道如何準(zhǔn)確的去使用自己擴(kuò)展的方法了。

jQuery插件的實(shí)現(xiàn)

我在初級(jí)階段的時(shí)候,覺得要自己編寫一個(gè)jQuery插件是一件高大上的事情,可望不可即。但是通過對(duì)于上面的理解,我就知道擴(kuò)展jQuery插件其實(shí)是一件我們自己也可以完成的事情。

在前面我跟大家分享了jQuery如何實(shí)現(xiàn),以及他們的方法如何擴(kuò)展,并且前一篇文章分享了拖拽對(duì)象的具體實(shí)現(xiàn)。所以建議大家暫時(shí)不要閱讀下去,自己動(dòng)手嘗試將拖拽擴(kuò)展成為jQuery的一個(gè)實(shí)例方法,那么這就是一個(gè)jQuery插件了。

具體也沒有什么可多說的了,大家看了代碼就可以明白一切。

// Drag對(duì)象簡(jiǎn)化代碼,完整源碼可在上一篇文章中查看
;
(function() {

    // 構(gòu)造
    function Drag(selector) {}


    // 原型
    Drag.prototype = {
        constructor: Drag,

        init: function() {
            // 初始時(shí)需要做些什么事情
            this.setDrag();
        },

        // 稍作改造,僅用于獲取當(dāng)前元素的屬性,類似于getName
        getStyle: function(property) {},

        // 用來獲取當(dāng)前元素的位置信息,注意與之前的不同之處
        getPosition: function() {},

        // 用來設(shè)置當(dāng)前元素的位置
        setPostion: function(pos) {},

        // 該方法用來綁定事件
        setDrag: function() {}
    }

    // 一種對(duì)外暴露的方式
    window.Drag = Drag;
})();

// 通過擴(kuò)展方法將拖拽擴(kuò)展為jQuery的一個(gè)實(shí)例方法
(function ($) {
  $.fn.extend({
    becomeDrag: function () {
      new Drag(this[0]);
      return this;   // 注意:為了保證jQuery所有的方法都能夠鏈?zhǔn)皆L問,每一個(gè)方法的最后都需要返回this,即返回jQuery實(shí)例
    }
  })
})(jQuery);

后續(xù)文章內(nèi)容一個(gè)大概預(yù)想

去年年末的時(shí)候就有了想要將JavaScript基礎(chǔ)知識(shí)總結(jié)一下的這樣一個(gè)想法,可是JavaScript基礎(chǔ)知識(shí)確實(shí)并非全部是層層遞進(jìn)的關(guān)系,有很多碎片化的東西,所以之前一直沒有找到一個(gè)合適的整理方法。

直到在segmentfault中我在給題主建議如何快速學(xué)習(xí)一門諸如react/vue這樣的流行框架時(shí),找到了一個(gè)好一點(diǎn)的思路,于是就有了這樣一系列文章,雖然它并不全面,很多知識(shí)沒有涉及到,但是其實(shí)我是圍繞最終通過模塊化來構(gòu)建自己代碼這樣一個(gè)思路來總結(jié)的,因此這系列文章能夠解決大家最核心的問題。

這系列文章,算是對(duì)于大家學(xué)習(xí)方向的一個(gè)具體的,切實(shí)可行的一個(gè)指引,而非簡(jiǎn)單的通過雞湯的方式告訴你應(yīng)該如何學(xué)習(xí)。所以,想要學(xué)習(xí)這些知識(shí)的朋友,趕緊來公眾號(hào)關(guān)注我吧!!!!

前端基礎(chǔ)進(jìn)階系列目錄

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90545.html

相關(guān)文章

  • 前端基礎(chǔ)進(jìn)階目錄

    摘要:不過其實(shí)簡(jiǎn)書文章評(píng)論里有很多大家的問題以及解答,對(duì)于進(jìn)一步理解文中知識(shí)幫助很大的,算是有點(diǎn)可惜吧。不過也希望能夠?qū)φ趯W(xué)習(xí)前端的你有一些小幫助。如果在閱讀中發(fā)現(xiàn)了一些錯(cuò)誤,請(qǐng)?jiān)谠u(píng)論里告訴我,我會(huì)及時(shí)更改。 前端基礎(chǔ)進(jìn)階(一):內(nèi)存空間詳細(xì)圖解 前端基礎(chǔ)進(jìn)階(二):執(zhí)行上下文詳細(xì)圖解 前端基礎(chǔ)進(jìn)階(三):變量對(duì)象詳解 前端基礎(chǔ)進(jìn)階(四):詳細(xì)圖解作用域鏈與閉包 前端基礎(chǔ)進(jìn)階(五):全方位...

    mo0n1andin 評(píng)論0 收藏0
  • 前端資源分享-只為更好前端

    摘要:一團(tuán)隊(duì)組織網(wǎng)站說明騰訊團(tuán)隊(duì)騰訊前端團(tuán)隊(duì),代表作品,致力于前端技術(shù)的研究騰訊社交用戶體驗(yàn)設(shè)計(jì),簡(jiǎn)稱,騰訊設(shè)計(jì)團(tuán)隊(duì)網(wǎng)站騰訊用戶研究與體驗(yàn)設(shè)計(jì)部百度前端研發(fā)部出品淘寶前端團(tuán)隊(duì)用技術(shù)為體驗(yàn)提供無限可能凹凸實(shí)驗(yàn)室京東用戶體驗(yàn)設(shè)計(jì)部出品奇舞團(tuán)奇虎旗下前 一、團(tuán)隊(duì)組織 網(wǎng)站 說明 騰訊 AlloyTeam 團(tuán)隊(duì) 騰訊Web前端團(tuán)隊(duì),代表作品WebQQ,致力于前端技術(shù)的研究 ISUX 騰...

    zxhaaa 評(píng)論0 收藏0
  • 前端資源分享-只為更好前端

    摘要:一團(tuán)隊(duì)組織網(wǎng)站說明騰訊團(tuán)隊(duì)騰訊前端團(tuán)隊(duì),代表作品,致力于前端技術(shù)的研究騰訊社交用戶體驗(yàn)設(shè)計(jì),簡(jiǎn)稱,騰訊設(shè)計(jì)團(tuán)隊(duì)網(wǎng)站騰訊用戶研究與體驗(yàn)設(shè)計(jì)部百度前端研發(fā)部出品淘寶前端團(tuán)隊(duì)用技術(shù)為體驗(yàn)提供無限可能凹凸實(shí)驗(yàn)室京東用戶體驗(yàn)設(shè)計(jì)部出品奇舞團(tuán)奇虎旗下前 一、團(tuán)隊(duì)組織 網(wǎng)站 說明 騰訊 AlloyTeam 團(tuán)隊(duì) 騰訊Web前端團(tuán)隊(duì),代表作品WebQQ,致力于前端技術(shù)的研究 ISUX 騰...

    JouyPub 評(píng)論0 收藏0
  • 前端資源分享-只為更好前端

    摘要:一團(tuán)隊(duì)組織網(wǎng)站說明騰訊團(tuán)隊(duì)騰訊前端團(tuán)隊(duì),代表作品,致力于前端技術(shù)的研究騰訊社交用戶體驗(yàn)設(shè)計(jì),簡(jiǎn)稱,騰訊設(shè)計(jì)團(tuán)隊(duì)網(wǎng)站騰訊用戶研究與體驗(yàn)設(shè)計(jì)部百度前端研發(fā)部出品淘寶前端團(tuán)隊(duì)用技術(shù)為體驗(yàn)提供無限可能凹凸實(shí)驗(yàn)室京東用戶體驗(yàn)設(shè)計(jì)部出品奇舞團(tuán)奇虎旗下前 一、團(tuán)隊(duì)組織 網(wǎng)站 說明 騰訊 AlloyTeam 團(tuán)隊(duì) 騰訊Web前端團(tuán)隊(duì),代表作品WebQQ,致力于前端技術(shù)的研究 ISUX 騰...

    vslam 評(píng)論0 收藏0
  • 【連載】前端個(gè)人文章整理-從基礎(chǔ)到入門

    摘要:個(gè)人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現(xiàn)在已經(jīng)一年的時(shí)間了,由于工作比較忙,更新緩慢,后面還是會(huì)繼更新,現(xiàn)將已經(jīng)寫好的文章整理一個(gè)目錄,方便更多的小伙伴去學(xué)習(xí)。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個(gè)人前端文章整理 從最開始萌生寫文章的想法,到著手...

    madthumb 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<