欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

超越Jquery_01_isPlainObject分析與重構(gòu)

 更新時間:2010年10月20日 11:25:11   作者:  
isPlainObject是Jquery1.4后提供的新方法,用于判斷對象是否是純粹的對象(通過 {} 或者 new Object 創(chuàng)建的)。

isPlainObject是Jquery1.4后提供的新方法,用于判斷對象是否是純粹的對象(通過 "{}" 或者 "new Object" 創(chuàng)建的)。

使用isPlainObject
  首先我們來了解一下什么叫'純粹的對象',簡單的理解'純粹的對象'指的就是由Object構(gòu)造出來的對象。那哪些對象是由Object構(gòu)造出來的呢。首當(dāng)其充的肯定是由new Object()所構(gòu)造出來的對象,注意:在Object后的括號里可沒加任何東西。因為Object是所有'類'的根基,因此它有一些特殊的行為,如當(dāng)調(diào)用new Object(3)的時候,會構(gòu)造一個Number類型的對象。new Object('')會構(gòu)造一個String類型的對象。然后以{}這種形式定義的對象也屬于'純粹的對象'。'{}'的實質(zhì)就是new Object(),只是表現(xiàn)形形式不同。好,讓我們來看一段代碼:

復(fù)制代碼 代碼如下:

var objStr = new Object('');
alert(objStr.constructor);//String
alert(isPlainObject(objStr));//false
var objNum = new Object(3);
alert(objNum.constructor);//Number
alert(isPlainObject(objNum));//false
function Person(){}
var person = new Person();
alert(isPlainObject(person));//false
var obj01 = new Object();
obj01.name = '笨蛋的座右銘';
alert(isPlainObject(obj01));//true
alert(isPlainObject({name:'笨蛋的座右銘'}));//true

isPlainObject源碼分析
以下代碼為Jquery中的isPlainObject的完整版本,注釋已經(jīng)很詳盡了,我就不多說什么了。
復(fù)制代碼 代碼如下:

var toString = Object.prototype.toString,
hasOwnProperty = Object.prototype.hasOwnProperty;
function isPlainObject( obj ) {
// Must be an Object.
// Because of IE, we also have to check the presence of the constructor property.
//Make sure that DOM nodes and window objects don't pass through, as well
//windows objects:toString.call(window):IE [object Object] FF [object Window] chrome [window global] safari [object DOMWindow]
//DOM nodes:toString.call(#div01):IE [object Object] FF [object Window] chrome [object global] safari [object DOMWindow]
//結(jié)論:obj.nodeType || obj.setInterval主要是針對于IE瀏覽器進行判斷
//注:history,location,navigator,screen的setInterval為undefined
if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {
return false;
}
// Not own constructor property must be Object
// 除去自定義對象和內(nèi)置對象的判斷,如function Person(){} var p = new Person();String,Number
if ( obj.constructor //有constructor屬性
&& !hasOwnProperty.call(obj, "constructor") //并且constructor這個屬性必須是在原型鏈中進行定義的
&& !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf")//并且原型中有isPrototypeOf方法,一般只有Object的原型中才有這個方法
) {
return false;
}
// Own properties are enumerated firstly, so to speed up,
// if last one is own, then all properties are own.
//針對于復(fù)雜類結(jié)構(gòu),如有繼承...
/*
//一個簡單的測試
function Animal(name){
}
function Person(name,age){
Animal.call(this,name);
this.age =age;
}
var p = new Person('jxl',20);
for(key in p){
alert(hasOwnProperty.call( p, key ))//true , false
}
*/
var key;
for ( key in obj ) {}
return key === undefined || hasOwnProperty.call( obj, key );
}

提出問題
個人感覺這個實現(xiàn)比較復(fù)雜,而且有BUG。
簡單的BUG,history,location,navigator,screen可以順序通過 isPlainObject的檢測返回true.
來看一個我的解決方案(修改BUG,簡化):
復(fù)制代碼 代碼如下:

function isPlainObject(obj){
if(obj&&Object.prototype.toString.call(obj)==="[object Object]"&&obj.constructor===Object &&!hasOwnProperty.call(obj, "constructor")){
var key;
for ( key in obj ) {}
return key === undefined || hasOwnProperty.call( obj, key );
}
return false;
}

還有BUG,而且是一個無解的BUG:
復(fù)制代碼 代碼如下:

function m(){};
m.prototype.constructor=Object; //必殺
obj=new m;
alert(isPlainObject(obj)); //true

再來一個同理的:
復(fù)制代碼 代碼如下:

function m(){};
m.prototype = {};
obj=new m;
alert(isPlainObject(obj)); //true

這個答案是無解的!

解答無解
本以為這個問題很好解決,結(jié)果深入后,發(fā)現(xiàn)這是一個無解的問題。原因如下:
復(fù)制代碼 代碼如下:

function Person(){};
Person.prototype.constructor=Object;
var person=new Person;

讓我們來看一下person現(xiàn)在的狀態(tài):

person和其構(gòu)造函數(shù)Person唯一的聯(lián)系就是其prototype鏈中的constructor屬性。而在我們判斷是否為'純粹的對象'主要是依據(jù)對象實例的constructor進行的。如果我們將其指向Object,正如圖中看到的那樣,那么person和Person在代碼上就沒有關(guān)系了。也正是因為這一點,讓類型的判斷出現(xiàn)了問題。

相關(guān)文章

  • webuploader分片上傳的實現(xiàn)代碼(前后端分離)

    webuploader分片上傳的實現(xiàn)代碼(前后端分離)

    這篇文章主要介紹了webuploader分片上傳的實現(xiàn)代碼(前后端分離),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • layui table 復(fù)選框跳頁后再回來保持原來選中的狀態(tài)示例

    layui table 復(fù)選框跳頁后再回來保持原來選中的狀態(tài)示例

    今天小編就為大家分享一篇layui table 復(fù)選框跳頁后再回來保持原來選中的狀態(tài)示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • javascript實現(xiàn)的上下無縫滾動效果

    javascript實現(xiàn)的上下無縫滾動效果

    這篇文章主要介紹了javascript實現(xiàn)的上下無縫滾動效果,具有無縫滾動及響應(yīng)鼠標滑過停止?jié)L動的功能,簡便實用,需要的朋友可以參考下
    2016-09-09
  • JavaScript中this詳解

    JavaScript中this詳解

    都說 JavaScript 是一種很靈活的語言,這其實也可以說它是一個混亂的語言。它把函數(shù)式編程和面向?qū)ο缶幊挑酆弦黄?,再加上動態(tài)語言特性,簡直強大無比,下面小編給大家介紹Javascript中this詳解,需要的小伙伴可以來參考下
    2015-09-09
  • js實現(xiàn)Select頭像選擇實時預(yù)覽代碼

    js實現(xiàn)Select頭像選擇實時預(yù)覽代碼

    這篇文章主要介紹了js實現(xiàn)Select頭像選擇實時預(yù)覽代碼,涉及javascript動態(tài)遍歷及設(shè)置select選項的技巧,非常簡單實用,需要的朋友可以參考下
    2015-08-08
  • JavaScript數(shù)據(jù)結(jié)構(gòu)中串的表示與應(yīng)用實例

    JavaScript數(shù)據(jù)結(jié)構(gòu)中串的表示與應(yīng)用實例

    這篇文章主要介紹了JavaScript數(shù)據(jù)結(jié)構(gòu)中串的表示與應(yīng)用,結(jié)合實例形式簡單分析了基于javascript順序操作實現(xiàn)串結(jié)構(gòu)與串的拼接操作相關(guān)技巧,需要的朋友可以參考下
    2017-04-04
  • JavaScript職責(zé)鏈模式概述

    JavaScript職責(zé)鏈模式概述

    這篇文章主要為大家詳細介紹了JavaScript職責(zé)鏈模式,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • javascript延時加載之defer測試

    javascript延時加載之defer測試

    偶爾發(fā)現(xiàn) js 中有個延時加載的標簽 defer,還在疑惑這么好用的東西為什么沒有流行起來,本人今天把它拾起來用了一下,發(fā)現(xiàn)只在ie7,8,9和360安全濟覽器下可以,知道為什么不用它了吧
    2012-12-12
  • 使用javascript做的一個隨機點名程序

    使用javascript做的一個隨機點名程序

    這篇文章主要介紹了使用javascript做的一個隨機點名程序,經(jīng)測試,效果相當(dāng)不錯,需要的朋友可以參考下
    2014-02-02
  • Bootstrap框架下下拉框select搜索功能

    Bootstrap框架下下拉框select搜索功能

    這篇文章主要為大家詳細介紹了Bootstrap框架下下拉框select搜索功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-07-07

最新評論