javascript中l(wèi)ength屬性的探索
更新時(shí)間:2011年07月31日 21:32:39 作者:
本文中,我將會(huì)通過(guò)類(lèi)數(shù)組對(duì)象(array like object),探索javascript中的length屬性的一些秘密。
例子1:
var obj={0:'a',1:'b'}
alert(obj.length); //undefined
var arr=['a','b']
alert(arr.length); // 2
從上面的例子看,類(lèi)數(shù)組對(duì)象中的length屬性并不和它儲(chǔ)存的數(shù)據(jù)數(shù)量直接掛鉤,無(wú)論是索引屬性(0,1)還是length屬性都作為對(duì)象的普通屬性存在,它們之間并沒(méi)有任何關(guān)系,js引擎并不會(huì)根據(jù)儲(chǔ)存數(shù)據(jù)的數(shù)量來(lái)自動(dòng)計(jì)算類(lèi)數(shù)組對(duì)象的長(zhǎng)度。
但是類(lèi)數(shù)組對(duì)象的length所確實(shí)和存儲(chǔ)的數(shù)據(jù)量沒(méi)有任何關(guān)系么?例子2說(shuō)明并非如此:
例子2:
function myarr(){}
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//IE8以下:undefined 其他瀏覽器:3
alert(m[2]);//IE8以下:undefined 其他瀏覽器:‘xiaoc'
從例子2可以看到,除了IE8以下版本,在通過(guò)強(qiáng)制使用數(shù)組方法為類(lèi)數(shù)組對(duì)象添加元素時(shí),對(duì)象的length屬性也會(huì)被計(jì)算。而IE8以下版本貌似不支持強(qiáng)制使用數(shù)組方法為類(lèi)數(shù)組對(duì)象添加元素。
例子3:
該例子在例子2的myarr構(gòu)造函數(shù)中添加一個(gè)初始化操作,在類(lèi)數(shù)組對(duì)象初始化時(shí)添加一個(gè)元素,怪異的事情發(fā)生了:
function myarr(){this[0]='cc';}
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//ie8以下:undefined 其他:3
alert(m[2]);//ie8以下:undefined 其他:xiaoc
ie8以下版本瀏覽器繼續(xù)貌似不支持強(qiáng)制使用數(shù)組方法,這個(gè)再下一個(gè)例子中會(huì)作討論。而對(duì)于其他瀏覽器,length屬性輸出為3,而索引為2的元素是'xiaoc‘,顯然js引擎完全忽略了類(lèi)數(shù)組對(duì)象原來(lái)所存在的索引為0的元素‘cc'!馬上我們?cè)倏聪乱粋€(gè)例子,這個(gè)例子在例子3的基礎(chǔ)上多加一個(gè)對(duì)length屬性的初始化:
function myarr(){this[0]='cc'; this.length=1;}//多加一個(gè)length的初始化
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//輸出4
alert(m[2]);//輸出'lai‘
奇怪的事再次發(fā)生,這次所有瀏覽器(包括ie6 7)都正確輸出4,索引為2的元素正確輸出為'lai‘,可見(jiàn)IE 6 7添加了length屬性的初始化之后,可以正常使用數(shù)組方法了。
現(xiàn)在再試試把length屬性初始化為不合法類(lèi)型:
例子4:
function myarr(){this[0]='cc'; this.length="bo";}//length設(shè)置為不能轉(zhuǎn)換為number的不合法類(lèi)型
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//輸出 3
alert(m[2]);// 輸出'xiaoc‘
function myarr(){this[0]='cc'; this.length="1";}//length設(shè)置為能轉(zhuǎn)換為數(shù)字的不合法類(lèi)型
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//輸出4
alert(m[2]);//輸出'lai‘
從上面的所有例子來(lái)看,我們可以作出一個(gè)推斷,在使用數(shù)組方法時(shí)(這里以push為例),大概是這樣的流程:
IE6 7:
可見(jiàn)IE6 7并非不支強(qiáng)制持使用數(shù)組方法添加元素,但是會(huì)先判斷l(xiāng)ength屬性是否存在,如果不存在,則返回,不做任何操作。如果length屬性為不合法值,則嘗試轉(zhuǎn)換為number類(lèi)型,如果轉(zhuǎn)換失敗則length設(shè)置為0,這就可以解析例子2,3里輸出的undefined和例子4的正確輸出。
其他瀏覽器:
其他瀏覽器會(huì)根據(jù)length屬性作不同操作,如果length屬性不存在,則設(shè)置length為0,如果length屬性為不合法值,則嘗試轉(zhuǎn)換為number類(lèi)型,如果轉(zhuǎn)換失敗則也length設(shè)置為0。
正因?yàn)閘ength屬性對(duì)于數(shù)組方法有如此決定性的作用,因此js引擎禁止了對(duì)length屬性寫(xiě)入不合法值:
var arr=['1','2','3'];
arr.length='undefined';//報(bào)錯(cuò)invalid array length
從上面的例子中,我們可以得出一個(gè)結(jié)論:當(dāng)我們使用類(lèi)數(shù)組對(duì)象時(shí),為了避各種length計(jì)算不正確引起的怪異問(wèn)題,我們應(yīng)該在初始化類(lèi)數(shù)組對(duì)象時(shí)初始化length屬性的值,如果在初始化時(shí)添加了元素但卻沒(méi)有設(shè)置length屬性的值,在使用數(shù)組方法時(shí),IE6 7會(huì)忽略所有操作,其他瀏覽器則會(huì)忽略初始化時(shí)添加的元素。
另外再介紹length屬性帶來(lái)的另一個(gè)問(wèn)題:
請(qǐng)看例子5:
function myarr(){}
myarr.prototype=new Array();
var m=new myarr();
m.push('cson','lai','xiaoc');
alert(m.length);//IE6 7:0 其他:3
alert(m[2]);//所有瀏覽器:'xiaoc‘
當(dāng)使用原型繼承數(shù)組時(shí),IE 6 7下length會(huì)始終為0,無(wú)論你有多少個(gè)元素,其他瀏覽器則正常。
即使強(qiáng)制設(shè)置length屬性,IE6 7 下死活為0:
function myarr(){}
myarr.prototype=new Array();
var m=new myarr();
m.length=10;
alert(m.length);//IE6 7:0 其他:10
因此得出結(jié)論:IE6 7下對(duì)象原型繼承數(shù)組時(shí)length屬性會(huì)一直為0,因此如果類(lèi)數(shù)組對(duì)象需要使用數(shù)組的方法,不要去繼承數(shù)組,而應(yīng)該使用Array.prototype.xxx.apply(obj,[]);的方法,并且記得正確初始化length屬性的值。
復(fù)制代碼 代碼如下:
var obj={0:'a',1:'b'}
alert(obj.length); //undefined
var arr=['a','b']
alert(arr.length); // 2
從上面的例子看,類(lèi)數(shù)組對(duì)象中的length屬性并不和它儲(chǔ)存的數(shù)據(jù)數(shù)量直接掛鉤,無(wú)論是索引屬性(0,1)還是length屬性都作為對(duì)象的普通屬性存在,它們之間并沒(méi)有任何關(guān)系,js引擎并不會(huì)根據(jù)儲(chǔ)存數(shù)據(jù)的數(shù)量來(lái)自動(dòng)計(jì)算類(lèi)數(shù)組對(duì)象的長(zhǎng)度。
但是類(lèi)數(shù)組對(duì)象的length所確實(shí)和存儲(chǔ)的數(shù)據(jù)量沒(méi)有任何關(guān)系么?例子2說(shuō)明并非如此:
例子2:
復(fù)制代碼 代碼如下:
function myarr(){}
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//IE8以下:undefined 其他瀏覽器:3
alert(m[2]);//IE8以下:undefined 其他瀏覽器:‘xiaoc'
從例子2可以看到,除了IE8以下版本,在通過(guò)強(qiáng)制使用數(shù)組方法為類(lèi)數(shù)組對(duì)象添加元素時(shí),對(duì)象的length屬性也會(huì)被計(jì)算。而IE8以下版本貌似不支持強(qiáng)制使用數(shù)組方法為類(lèi)數(shù)組對(duì)象添加元素。
例子3:
該例子在例子2的myarr構(gòu)造函數(shù)中添加一個(gè)初始化操作,在類(lèi)數(shù)組對(duì)象初始化時(shí)添加一個(gè)元素,怪異的事情發(fā)生了:
復(fù)制代碼 代碼如下:
function myarr(){this[0]='cc';}
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//ie8以下:undefined 其他:3
alert(m[2]);//ie8以下:undefined 其他:xiaoc
ie8以下版本瀏覽器繼續(xù)貌似不支持強(qiáng)制使用數(shù)組方法,這個(gè)再下一個(gè)例子中會(huì)作討論。而對(duì)于其他瀏覽器,length屬性輸出為3,而索引為2的元素是'xiaoc‘,顯然js引擎完全忽略了類(lèi)數(shù)組對(duì)象原來(lái)所存在的索引為0的元素‘cc'!馬上我們?cè)倏聪乱粋€(gè)例子,這個(gè)例子在例子3的基礎(chǔ)上多加一個(gè)對(duì)length屬性的初始化:
復(fù)制代碼 代碼如下:
function myarr(){this[0]='cc'; this.length=1;}//多加一個(gè)length的初始化
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//輸出4
alert(m[2]);//輸出'lai‘
奇怪的事再次發(fā)生,這次所有瀏覽器(包括ie6 7)都正確輸出4,索引為2的元素正確輸出為'lai‘,可見(jiàn)IE 6 7添加了length屬性的初始化之后,可以正常使用數(shù)組方法了。
現(xiàn)在再試試把length屬性初始化為不合法類(lèi)型:
例子4:
復(fù)制代碼 代碼如下:
function myarr(){this[0]='cc'; this.length="bo";}//length設(shè)置為不能轉(zhuǎn)換為number的不合法類(lèi)型
var m=new myarr();
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//輸出 3
alert(m[2]);// 輸出'xiaoc‘
復(fù)制代碼 代碼如下:
function myarr(){this[0]='cc'; this.length="1";}//length設(shè)置為能轉(zhuǎn)換為數(shù)字的不合法類(lèi)型
Array.prototype.push.apply(m,['cson','lai','xiaoc']);
alert(m.length);//輸出4
alert(m[2]);//輸出'lai‘
從上面的所有例子來(lái)看,我們可以作出一個(gè)推斷,在使用數(shù)組方法時(shí)(這里以push為例),大概是這樣的流程:
IE6 7:
可見(jiàn)IE6 7并非不支強(qiáng)制持使用數(shù)組方法添加元素,但是會(huì)先判斷l(xiāng)ength屬性是否存在,如果不存在,則返回,不做任何操作。如果length屬性為不合法值,則嘗試轉(zhuǎn)換為number類(lèi)型,如果轉(zhuǎn)換失敗則length設(shè)置為0,這就可以解析例子2,3里輸出的undefined和例子4的正確輸出。
其他瀏覽器:
其他瀏覽器會(huì)根據(jù)length屬性作不同操作,如果length屬性不存在,則設(shè)置length為0,如果length屬性為不合法值,則嘗試轉(zhuǎn)換為number類(lèi)型,如果轉(zhuǎn)換失敗則也length設(shè)置為0。
正因?yàn)閘ength屬性對(duì)于數(shù)組方法有如此決定性的作用,因此js引擎禁止了對(duì)length屬性寫(xiě)入不合法值:
復(fù)制代碼 代碼如下:
var arr=['1','2','3'];
arr.length='undefined';//報(bào)錯(cuò)invalid array length
從上面的例子中,我們可以得出一個(gè)結(jié)論:當(dāng)我們使用類(lèi)數(shù)組對(duì)象時(shí),為了避各種length計(jì)算不正確引起的怪異問(wèn)題,我們應(yīng)該在初始化類(lèi)數(shù)組對(duì)象時(shí)初始化length屬性的值,如果在初始化時(shí)添加了元素但卻沒(méi)有設(shè)置length屬性的值,在使用數(shù)組方法時(shí),IE6 7會(huì)忽略所有操作,其他瀏覽器則會(huì)忽略初始化時(shí)添加的元素。
另外再介紹length屬性帶來(lái)的另一個(gè)問(wèn)題:
請(qǐng)看例子5:
復(fù)制代碼 代碼如下:
function myarr(){}
myarr.prototype=new Array();
var m=new myarr();
m.push('cson','lai','xiaoc');
alert(m.length);//IE6 7:0 其他:3
alert(m[2]);//所有瀏覽器:'xiaoc‘
當(dāng)使用原型繼承數(shù)組時(shí),IE 6 7下length會(huì)始終為0,無(wú)論你有多少個(gè)元素,其他瀏覽器則正常。
即使強(qiáng)制設(shè)置length屬性,IE6 7 下死活為0:
復(fù)制代碼 代碼如下:
function myarr(){}
myarr.prototype=new Array();
var m=new myarr();
m.length=10;
alert(m.length);//IE6 7:0 其他:10
因此得出結(jié)論:IE6 7下對(duì)象原型繼承數(shù)組時(shí)length屬性會(huì)一直為0,因此如果類(lèi)數(shù)組對(duì)象需要使用數(shù)組的方法,不要去繼承數(shù)組,而應(yīng)該使用Array.prototype.xxx.apply(obj,[]);的方法,并且記得正確初始化length屬性的值。
您可能感興趣的文章:
- Js數(shù)組的操作push,pop,shift,unshift等方法詳細(xì)介紹
- JavaScript使用pop方法移除數(shù)組最后一個(gè)元素用法實(shí)例
- JavaScript數(shù)組函數(shù)unshift、shift、pop、push使用實(shí)例
- JS數(shù)組方法push()、pop()用法實(shí)例分析
- JS Array.slice 截取數(shù)組的實(shí)現(xiàn)方法
- JavaScript截取字符串的Slice、Substring、Substr函數(shù)詳解和比較
- JS數(shù)組操作(數(shù)組增加、刪除、翻轉(zhuǎn)、轉(zhuǎn)字符串、取索引、截取(切片)slice、剪接splice、數(shù)組合并)
- javascript中不易分清的slice,splice和split三個(gè)函數(shù)
- JavaScript中l(wèi)ength屬性的使用方法
- JavaScript 中獲取數(shù)組最后一個(gè)元素方法匯總
相關(guān)文章
JavaScript中call和apply方法的區(qū)別實(shí)例分析
這篇文章主要介紹了JavaScript中call和apply方法的區(qū)別,結(jié)合實(shí)例形式分析call和apply方法的功能、原理及相關(guān)使用操作區(qū)別,需要的朋友可以參考下2018-08-08JS復(fù)制對(duì)應(yīng)id的內(nèi)容到粘貼板(Ctrl+C效果)
這篇文章主要給大家介紹了利用JS實(shí)現(xiàn)復(fù)制指定對(duì)應(yīng)id的內(nèi)容到粘貼板(Ctrl+C效果),文中給出了詳細(xì)的介紹和示例代碼,有需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-01-01js實(shí)現(xiàn)網(wǎng)頁(yè)音樂(lè)播放器
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)網(wǎng)頁(yè)音樂(lè)播放器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06bootstrap treeview 樹(shù)形菜單帶復(fù)選框及級(jí)聯(lián)選擇功能
這篇文章主要介紹了bootstrap treeview 樹(shù)形菜單帶復(fù)選框及級(jí)聯(lián)選擇功能,代碼超簡(jiǎn)單,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-06-06