#jQuery.isPlainObject方法源碼解析

jQuery.isPlainObject方法源碼解析

1.簡述函數(shù)功能:

  --[官方描述](http://www.css88.com/jqapi-1.9/jQuery.isPlainObject/):測試一個(gè)對象是否是純粹對象,但是
  結(jié)合代碼測試你雌,個(gè)人得出該方法是用于判斷不存在屬性值指向函數(shù)原型的對象或者是存在屬性指向函數(shù)原型但是函數(shù)原型必須是
  Object.prototype,請看以下測試代碼能夠驗(yàn)證:

  1).什么是純粹對象姐浮?即是通過{}或者new Object()方式創(chuàng)建的對象;
  
  2).a).noPrototype,ownNoPrototype是不具備屬性指向函數(shù)原型的對象为流;
  
     b).literal,hasPrototype攀例,object,ownHasPrototype是具備屬性指向Object.prototype的對象羡亩;
     
     c).ownObject是具備屬性指向自定義函數(shù)ownDef原型的對象,

     d).ownConObject是constructor是自身屬性的對象
     
  3).通過以下輸出結(jié)果可以斷定isPlainObject函數(shù)的功能的判斷依據(jù)與對象使用什么方式創(chuàng)建無關(guān)状勤,而是與對象是否沒有屬
  
  性指向原型鞋怀,有屬性指向函數(shù)原型的對象,它的函數(shù)原型是否是Object.prototype有關(guān)系持搜;

測試代碼:

    /*Object.create(null)密似,Object.create(Object.prototype),字面量{},內(nèi)置Object()
        Object.create內(nèi)部實(shí)現(xiàn)如下:
        // 傳入一個(gè)對象葫盼,作為F函數(shù)原型
        function create(object) {
            function F(){}
            F.prototype = object;
            return new F();
        }
    */
    
    var noPrototype = Object.create(null);
    console.log($.isPlainObject(noPrototype)); // true

    var literal = {};
    console.log($.isPlainObject(literal)); // true

    var hasPrototype = Object.create(Object.prototype);
    console.log($.isPlainObject(hasPrototype)); // true

    var object = new Object();
    console.log($.isPlainObject(object)); // true

    // 自定義函數(shù)創(chuàng)建對象
    function ownDef() {}
    var ownObject = new ownDef();
    console.log($.isPlainObject(ownObject)); // false

    ownDef.prototype.isPrototypeOf = '';
    var ownHasPrototype = new ownDef();
    console.log($.isPlainObject(ownHasPrototype)); // false
    
    ownDef.prototype.isPropertyOf = 'xxx';
    var owntransProtoProper = new ownDef();
    console.log($.isPlainObject(owntransProtoProper)); // false
    
    ownDef.prototype = null;
    var ownNoPrototype = new ownDef();
    console.log($.isPlainObject(ownNoPrototype)); // true
    
    ownDef.prototype = Object.prototype;
    var ownHasPrototype = new ownDef();
    console.log($.isPlainObject(ownHasPrototype)); // true
    
    function ownConstructor(){
        this.cunstructor = 'ownConstructor';
    }
    var ownConObject =  new ownConstructor();
    console.log($.isPlainObject(ownConObject)); // true

2.源碼解析:

  --整體思路:在js可編程區(qū)域object可能類型太多種了残腌,比如:window(包含BOM對象),DOM對象贫导,js對象(內(nèi)置對象抛猫,自
  
  定義函數(shù)創(chuàng)建對象,字面量,Object.create函數(shù))孩灯,本函數(shù)的流程主要就是如何過濾掉不符合的對象闺金。  

代碼片1:

/* a.!obj過濾了undefined和null;
  b.jQuery.type(obj) !== "object",過濾了不是內(nèi)置對象創(chuàng)建的對象除了Object()函數(shù)創(chuàng)建的;
   c.obj.nodeType,過濾DOM對象,因?yàn)槊總€(gè)DOM對象他的NodeType都存在且不為0;
   d.jQuery.isWindow( obj ),過濾掉window對象
if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
    return false;
}

代碼塊2:

try {
    /* 上一步過濾之后就只剩下自定義函數(shù)峰档,new Object()方法败匹,Object.create()方法,三種方式創(chuàng)建的對象讥巡; 
    結(jié)合以上測試代碼的對象流程圖片分析:
    
        --流程圖可以看出if()中每個(gè)條件篩選后的輸出:
        
        a.obj.constructor用于篩選出沒有constructor的對象一般由是自身沒有constructor哎壳,并且沒有屬性指向原型(由
        Object.create(null)創(chuàng)建比如:noPrototype或者其他原型為空得構(gòu)造函數(shù)創(chuàng)建的比如:ownNoPrototype)
        
        b.!core_hasOwn.call(obj, "constructor")用于篩選出有自身constructor屬性的對象(一般是對對象的構(gòu)造函數(shù)
        自設(shè)置this.constructor = xxx;或者對象添加屬性constructor如obj.constructor = xxx;)所以這里可能會出
        現(xiàn)bug,使得原型不是Object.prototype的構(gòu)造函數(shù)創(chuàng)建的對象在這里逃脫進(jìn)入下面繼續(xù)執(zhí)行,個(gè)人覺得這個(gè)條件去掉才
        能夠篩選出需要的對象:沒有屬性指向原型的對象和有屬性指向Object.prototype原型的對象尚卫;因?yàn)樵诤竺娴拇a中沒有
        對這里逃脫的對象進(jìn)行有效的處理(不知道jQuery設(shè)置這個(gè)條件的意義是什么);

        c.!core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf"),用于篩選出對象有屬性指向
        Object.prototype原型的對象(一般是構(gòu)造函數(shù)原型指向Object.porototype的對象尸红,而原型不是
        Object.prototyp的構(gòu)造函數(shù)通過為原型添加isPrototypeOf屬性的對象會逃脫吱涉,但是在后面代碼塊3會被過濾);
    */
    if ( obj.constructor &&
        !core_hasOwn.call(obj, "constructor") &&
        !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
        return false;
    }
} catch ( e ) {
    // IE8,9 Will throw exceptions on certain host objects #9897 為了兼容IE
    return false;
}
代碼片2過濾流程
###代碼片3:
        /*
            主要為了過濾原型不是Object.prototyp的構(gòu)造函數(shù)通過為原型添加isPrototypeOf屬性的對象比如:
            owntransProtoProper對象,由于這種對象我們對他原型設(shè)置了對象外里,所以isPrototypeOf屬性是可以枚舉的怎爵,我
            們只需要判斷該對象的原型中是否有可枚舉的屬性來達(dá)到目的,有因?yàn)槊杜e屬性總是從自身屬性枚舉到原型屬性盅蝗,所以
            只需判斷對象最后一個(gè)可枚舉屬性不是他原型屬性鳖链;
        */
        var key;
        // 這里是快速獲取最后一個(gè)屬性
        for ( key in obj ) {}
        return key === undefined || core_hasOwn.call( obj, key );
    },
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子芙委,更是在濱河造成了極大的恐慌逞敷,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件灌侣,死亡現(xiàn)場離奇詭異推捐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)侧啼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門牛柒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人痊乾,你說我怎么就攤上這事皮壁。” “怎么了哪审?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵蛾魄,是天一觀的道長。 經(jīng)常有香客問我协饲,道長畏腕,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任茉稠,我火速辦了婚禮描馅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘而线。我一直安慰自己铭污,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布膀篮。 她就那樣靜靜地躺著嘹狞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪誓竿。 梳的紋絲不亂的頭發(fā)上磅网,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天,我揣著相機(jī)與錄音筷屡,去河邊找鬼涧偷。 笑死,一個(gè)胖子當(dāng)著我的面吹牛毙死,可吹牛的內(nèi)容都是我干的燎潮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼扼倘,長吁一口氣:“原來是場噩夢啊……” “哼确封!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤爪喘,失蹤者是張志新(化名)和其女友劉穎颜曾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體腥放,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡泛啸,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了秃症。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片候址。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖种柑,靈堂內(nèi)的尸體忽然破棺而出岗仑,到底是詐尸還是另有隱情,我是刑警寧澤聚请,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布荠雕,位于F島的核電站,受9級特大地震影響驶赏,放射性物質(zhì)發(fā)生泄漏炸卑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一煤傍、第九天 我趴在偏房一處隱蔽的房頂上張望盖文。 院中可真熱鬧,春花似錦蚯姆、人聲如沸五续。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疙驾。三九已至,卻和暖如春郭毕,著一層夾襖步出監(jiān)牢的瞬間它碎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工显押, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留链韭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓煮落,卻偏偏與公主長得像,于是被迫代替她去往敵國和親踊谋。 傳聞我的和親對象是個(gè)殘疾皇子蝉仇,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容