JavaScript從數(shù)組的indexOf()深化之Object的Property機制__第1頁
JavaScript從數(shù)組的indexOf()深化之Object的Property機制__第2頁
JavaScript從數(shù)組的indexOf()深化之Object的Property機制__第3頁
JavaScript從數(shù)組的indexOf()深化之Object的Property機制__第4頁
JavaScript從數(shù)組的indexOf()深化之Object的Property機制__第5頁
已閱讀5頁,還剩8頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、JavaScript從數(shù)組的indexOf()深化之Object的Property機制_ 這篇文章主要介紹了JavaScript從數(shù)組的indexOf()深化Object的Property機制的相關(guān)資料,需要的伴侶可以參考下 在JavaScript中,數(shù)組可以用法Array構(gòu)造函數(shù)來創(chuàng)建,或用法快速創(chuàng)建,這也是首選的方法。數(shù)組是繼承自O(shè)bject的原型,并且他對typeof沒有特別的返回值,他只返回'object'。 js中,可以說萬物皆對象(object),一個數(shù)組也是一個對象(array)。 許多對象都有許多很便利的方法 比如數(shù)組的push,concat,slice等等,但

2、是假如一些對象,它沒有實現(xiàn)這些方法,我們還是想用法這些功能。那該怎么辦呢? 1、許多方法都供應(yīng)了特別高效的實現(xiàn), 我們可以仿照它們的實現(xiàn)。 比如IE8以下的掃瞄器不支持Array的indexOf方法,為了讓數(shù)組支持indexOf,我們可以自己寫一個方法,實現(xiàn)indexOf方法: (用IE掃瞄器調(diào)試 按F12,可以選擇掃瞄器版本到IE5。) var arr = , , , ; if (Atotype.indexOf) alert("你的掃瞄器支持indexOf方法。"); else alert("你的掃瞄器不支持indexOf方法。");

3、if (!Atotype.indexOf) Atotype.indexOf = function(item) for (var i = ; i this.length; i+) if(thisi=item) return i; return -; alert(arr.indexOf(); alert(arr.indexOf(); 當然這個方法是很垃圾的。在這里具體的實現(xiàn) 我就不獻丑了,供應(yīng)一個百度上copy的版本: 有愛好的話可以看看v8引擎是怎么實現(xiàn)的: if (!Atotype.indexOf) Atotype.indexOf

4、 = function(elt /*, from*/) var len = this.length ; var from = Number(arguments) | ; from = (from ) ? Math.ceil(from) : Math.floor(from); if (from ) from += len; for (; from len; from+) if (from in this thisfrom = elt) return from; return -; ; 2、繼承call和apply方法 假如我們每有一個對象,那每個對象就要自己寫一遍實現(xiàn)是不是很麻煩? 在高級語言中

5、,我們可以用繼承來解決問題,比如下面的java代碼: public class MyListE extends ArrayListE public void myAdd(E e) super.add(e); System.out.println("Add:"+e); 但是js中沒有繼承的概念啊,我們可以用call和apply來解決這樣的問題。 上面的代碼就可以改寫為: var myObject = function() myOtotype.add = function() Atotype.push.call(this,arguments);

6、 /輸出arguments for(var i=;iarguments.length;i+) console.log("Add:"+argumentsi); var obj = new myObject(); obj.add(,); 這里可以看到:雖然用高級語言的繼承方式實現(xiàn)了myAdd方法,但是現(xiàn)在myAdd方法只能傳一個參數(shù),假如要傳多個參數(shù),則需要再寫一個public void myAdd(E e)方法,甚至是public void myAdd(ListE e)方法。而JS用一個方法就可以搞定,用arguments對象表示輸入的全部參數(shù),這是高級語言難以做到的。 (p

7、s,其實在java中可以寫public void myAdd(E. e),這個是不定參數(shù),用法上public void myAdd(E e)是一樣的) call和apply方法用于轉(zhuǎn)變函數(shù)內(nèi)this指針的指向,call只有兩個參數(shù),而apply通常是知道參數(shù)個數(shù)之后才用法的,下面以例子說明: var Obj = function(name) = name; Ototype.getName = function() return ; var obj1 =new Obj("zou"); var obj2 = name:'

8、andy' var name = obj1.getName.call(obj2); alert(name); 參考是: apply(object,arg1,arg2,.) call(object,arg1,arg2,.) call后面只能跟一個“數(shù)組”,包括了全部的參數(shù)。而apply則是一顆語法糖,假如知道參數(shù)的個數(shù),用apply將很便利。 上面的object也可以是null或者undefined,這樣,這個object就是global object(window),例如,還是接著上例: var name = 'goo' alert(obj1.getName.call(

9、null); (在嚴格模式下,由于全局對象是null,故會拋出特別:Uncaught TypeError: Cannot read property 'name' of null) 3、Object.defineProperty (留意:不要在IE8以下用法該類特性) 微軟:將屬性添加到對象,或修改現(xiàn)有屬性的特性。 getter、setter, 其實js中對于對象的屬性也有g(shù)etter和setter函數(shù),不過個人覺得js中的getter和setter更像C#一些。 例如下面的代碼就定義了一個getter/setter: function myobj() Object.defin

10、eProperty(totype,'length', get:function() return this.length_; /這里不能是length。 , set:function(value) return this.length_=value; ); 說明的地方不能是length,否則會無限遞歸。 也可以去掉set,讓length變量只讀。 Object.defineProperty(totype,'length', get:function() return this.length_; /這里不能是length。 ,

11、/*set:function(value) return this.length_=value; */ ); myobj.length = 3; 這個代碼會拋出特別:Uncaught TypeError: Cannot set property length of #myobj which has only a getter。 要讓對象的屬性只讀,還可以用writable:false, Object.defineProperty(totype,'length', writable:false ); writable:false不能與get set共存,否則會拋

12、出Type Error。 configurable:是否能用delete語句刪除,但是configurable屬性似乎在嚴格模式下才有效,這樣的代碼在非嚴格模式下仍舊能執(zhí)行:(嚴格模式報錯) Object.defineProperty(totype,'length', configurable:false ); var obj = new myobj(); delete obj.length; value:指定該對象的固定值。value:10,表示這個對象初始值為10. 在非嚴格模式下,這樣的代碼不會報錯,嚴格模式下會報錯: Object.defineProp

13、erty(totype,'length', writable:false, value:'10' ); var obj = new myobj(); obj.length = 100; 可以用getOwnPropertyDescriptor來獵取并修改這些值,比如說,現(xiàn)在我的length屬性是只讀的。 運行這樣的代碼,結(jié)果卻報錯了: Object.defineProperty(totype,'length', value:, writable:false, ); var descriptor = Object.

14、getOwnPropertyDescriptor(totype, "length"); descriptor.writable = true; Object.defineProperty(totype,'length',descriptor); Uncaught TypeError: Cannot redefine property: length 這是由于configurable的默認值是false,在調(diào)用了defineProperty之后,configurable就具有false屬性,這樣就不能逆轉(zhuǎn)了。以后就不能改了。

15、 所以必需用法 configurable:true,這個對象屬性才是可以修改的,完整的代碼如下: Object.defineProperty(totype,'length', value:, writable:false, configurable:true ); var descriptor = Object.getOwnPropertyDescriptor(totype, "length"); descriptor.writable = true; Object.defineProperty(toty

16、pe,'length',descriptor); totype.length = ; var obj = new myobj(); alert(obj.length); 可以加上一句descriptor.configurable = false; 表示這個屬性我修改了,以后你們都不能再修改了 這個特性在許多時候也有用,數(shù)組Array的push pop等方法,假如用法call、apply,要求對象的length可變。假如對象的length屬性只讀,那么調(diào)用call、apply時,會拋出特別。 就比如DOMTokenList對象,它的length就是不行以變的。我

17、拿到了一個DOM對象DOMTokenList, 但是它的configurable是true,我們可以修改讓它的length屬性可以變?。?觀察沒,這個configurable是true,而setter是undefined,我們給它寫一個set方法,不就可以了嗎? var descriptor = Object.getOwnPropertyDescriptor(DOMTokenLtotype,'length'); descriptor.set = function(value) this.length = value; Object.defineProperty(D

18、OMTokenLtotype,'length',descriptor); 然后運行, 又拋出了一個特別,Uncaught RangeError: Maximum call stack size exceeded() 這是由于,我們在set this.length時,它會在我們寫的那個set方法中無限遞歸。 因此,我們需要用法delete消退length屬性的影響,也就是: var descriptor = Object.getOwnPropertyDescriptor(DOMTokenLtotype,'length'); descriptor.set = function(value) delete DOMTokenLtotype.length; this.length = value; Object.defineProperty(DOMTokenLtotype,'length',descriptor); 這樣,DOM

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論