茄子在线看片免费人成视频,午夜福利精品a在线观看,国产高清自产拍在线观看,久久综合久久狠狠综合

    <s id="ddbnn"></s>
  • <sub id="ddbnn"><ol id="ddbnn"></ol></sub>

  • <legend id="ddbnn"></legend><s id="ddbnn"></s>

    JavaScript從數(shù)組的indexOf()深入之Object的Property機制
    來源:易賢網(wǎng) 閱讀:1290 次 日期:2016-07-01 14:19:40
    溫馨提示:易賢網(wǎng)小編為您整理了“JavaScript從數(shù)組的indexOf()深入之Object的Property機制”,方便廣大網(wǎng)友查閱!

    這篇文章主要介紹了JavaScript從數(shù)組的indexOf()深入——Object的Property機制的相關資料,需要的朋友可以參考下

    在JavaScript中,數(shù)組可以使用Array構造函數(shù)來創(chuàng)建,或使用[]快速創(chuàng)建,這也是首選的方法。數(shù)組是繼承自Object的原型,并且他對typeof沒有特殊的返回值,他只返回'object'。

    js中,可以說萬物皆對象(object),一個數(shù)組也是一個對象(array)。

    很多對象都有很多很方便的方法 比如數(shù)組的push,concat,slice等等,但是如果一些對象,它沒有實現(xiàn)這些方法,我們還是想使用這些功能。那該怎么辦呢?

    1、很多方法都提供了非常高效的實現(xiàn), 我們可以仿照它們的實現(xiàn)。

    比如IE8以下的瀏覽器不支持Array的indexOf方法,為了讓數(shù)組支持indexOf,我們可以自己寫一個方法,實現(xiàn)indexOf方法:

    (用IE瀏覽器調試 按F12,可以選擇瀏覽器版本到IE5。)

    var arr = [, , , ];

    if (Array.prototype.indexOf) {

    alert("你的瀏覽器支持indexOf方法。");

    } else {

    alert("你的瀏覽器不支持indexOf方法。");

    }

    if (!Array.prototype.indexOf) {

    Array.prototype.indexOf = function(item) {

    for (var i = ; i < this.length; i++) {

    if(this[i]==item){

    return i;

    }

    }

    return -;

    }

    }

    alert(arr.indexOf());

    alert(arr.indexOf());

    當然這個方法是很垃圾的。在這里具體的實現(xiàn) 我就不獻丑了,提供一個百度上copy的版本:

    有興趣的話可以看看v8引擎是怎么實現(xiàn)的:https://github.com/v8/v8/blob/master/src/js/array.js

    if (!Array.prototype.indexOf)

    {

    Array.prototype.indexOf = 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 &&

    this[from] === elt)

    return from;

    }

    return -;

    };

    }

    2、繼承——call和apply方法

    如果我們每有一個對象,那每個對象就要自己寫一遍實現(xiàn)是不是很麻煩?

    在高級語言中,我們可以用繼承來解決問題,比如下面的java代碼:

    public class MyList<E> extends ArrayList<E>

    {

    public void myAdd(E e){

    super.add(e);

    System.out.println("Add:"+e);

    }

    }

    但是js中沒有繼承的概念啊,我們可以用call和apply來解決這樣的問題。

    上面的代碼就可以改寫為:

    var myObject = function(){

    }

    myObject.prototype.add = function(){

    Array.prototype.push.call(this,arguments);

    //輸出arguments

    for(var i=;i<arguments.length;i++){

    console.log("Add:"+arguments[i]);

    }

    }

    var obj = new myObject();

    obj.add(,,);

    這里可以看到:雖然用高級語言的繼承方式實現(xiàn)了myAdd方法,但是現(xiàn)在myAdd方法只能傳一個參數(shù),如果要傳多個參數(shù),則需要再寫一個public void myAdd(E[] e)方法,甚至是public void myAdd(List<E> e)方法。而JS用一個方法就可以搞定,用arguments對象表示輸入的所有參數(shù),這是高級語言難以做到的。

    (ps,其實在java中可以寫public void myAdd(E... e),這個是不定參數(shù),用法上public void myAdd(E[] e)是一樣的)

    call和apply方法用于改變函數(shù)內this指針的指向,call只有兩個參數(shù),而apply通常是知道參數(shù)個數(shù)之后才使用的,下面以例子說明:

    var Obj = function(name){

    this.name = name;

    }

    Obj.prototype.getName = function(){

    return this.name;

    }

    var obj1 =new Obj("zou");

    var obj2 = {name:'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(null)); 

    (在嚴格模式下,由于全局對象是null,故會拋出異常:Uncaught TypeError: Cannot read property 'name' of null)

    3、Object.defineProperty

    (注意:不要在IE8以下使用該類特性)

    微軟:將屬性添加到對象,或修改現(xiàn)有屬性的特性。

    getter、setter,

    其實js中對于對象的屬性也有getter和setter函數(shù),不過個人覺得js中的getter和setter更像C#一些。

    例如下面的代碼就定義了一個getter/setter:

    function myobj(){

    }

    Object.defineProperty(myobj.prototype,'length',{

    get:function(){

    return this.length_; //這里不能是length。

    },

    set:function(value){

    return this.length_=value;

    }

    });

    注釋的地方不能是length,否則會無限遞歸。

    也可以去掉set,讓length變量只讀。

    Object.defineProperty(myobj.prototype,'length',{

    get:function(){

    return this.length_; //這里不能是length。

    }, 

    /*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(myobj.prototype,'length',{

    writable:false

    });

    writable:false不能與get set共存,否則會拋出Type Error。

    configurable:是否能用delete語句刪除,但是configurable屬性好像在嚴格模式下才有效,這樣的代碼在非嚴格模式下仍然能執(zhí)行:(嚴格模式報錯)

    Object.defineProperty(myobj.prototype,'length',{

    configurable:false

    });

    var obj = new myobj();

    delete obj.length;

    value:指定該對象的固定值。value:10,表示這個對象初始值為10.

    在非嚴格模式下,這樣的代碼不會報錯,嚴格模式下會報錯:

    Object.defineProperty(myobj.prototype,'length',{

    writable:false,

    value:'10'

    });

    var obj = new myobj();

    obj.length = 100;

    可以用getOwnPropertyDescriptor來獲取并修改這些值,比如說,現(xiàn)在我的length屬性是只讀的。

    運行這樣的代碼,結果卻報錯了:

    Object.defineProperty(myobj.prototype,'length',{

    value:,

    writable:false,

    });

    var descriptor = Object.getOwnPropertyDescriptor(myobj.prototype, 

    "length");

    descriptor.writable = true;

    Object.defineProperty(myobj.prototype,'length',descriptor); 

    Uncaught TypeError: Cannot redefine property: length

    這是因為configurable的默認值是false,在調用了defineProperty之后,configurable就具有false屬性,這樣就不能逆轉了。以后就不能改了。

    所以必須使用 configurable:true,這個對象屬性才是可以修改的,完整的代碼如下:

    Object.defineProperty(myobj.prototype,'length',{

    value:,

    writable:false,

    configurable:true

    });

    var descriptor = Object.getOwnPropertyDescriptor(myobj.prototype, 

    "length");

    descriptor.writable = true;

    Object.defineProperty(myobj.prototype,'length',descriptor);

    myobj.prototype.length = ;

    var obj = new myobj();

    alert(obj.length);

    可以加上一句descriptor.configurable = false;

    表示這個屬性我修改了,以后你們都不能再修改了

    這個特性在很多時候也有用,數(shù)組Array的push pop等方法,如果使用call、apply,要求對象的length可變。如果對象的length屬性只讀,那么調用call、apply時,會拋出異常。

    就比如DOMTokenList對象,它的length就是不可以變的。我拿到了一個DOM對象DOMTokenList,

    但是它的configurable是true,我們可以修改讓它的length屬性可以變?。?/P>

    名單

    看見沒,這個configurable是true,而setter是undefined,我們給它寫一個set方法,不就可以了嗎?

    var descriptor = Object.getOwnPropertyDescriptor(DOMTokenList.prototype,'length');

    descriptor.set = function(value){

    this.length = value;

    }

    Object.defineProperty(DOMTokenList.prototype,'length',descriptor);

    然后運行,

    又拋出了一個異常,Uncaught RangeError: Maximum call stack size exceeded(…)

    這是因為,我們在set this.length時,它會在我們寫的那個set方法中無限遞歸。

    因此,我們需要使用delete消除length屬性的影響,也就是:

    var descriptor = Object.getOwnPropertyDescriptor(DOMTokenList.prototype,'length');

    descriptor.set = function(value){

    delete DOMTokenList.prototype.length;

    this.length = value;

    }

    Object.defineProperty(DOMTokenList.prototype,'length',descriptor);

    這樣,DOMTokenList也就支持了push,pop等等操作了。

    Array.prototype.push.call(document.body.classList,'abc')

    然后再行封裝

    DOMTokenList.prototype.push = function(){

    Array.prototype.push.call(document.body.classList,Array.prototype.slice.call(arguments));

    }

    Array.prototype.slice.call(arguments)方法用于把arguments對象轉換為數(shù)組。

    更多信息請查看網(wǎng)絡編程

    2026上岸·考公考編培訓報班

    • 報班類型
    • 姓名
    • 手機號
    • 驗證碼
    關于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
    工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
    聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
    咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網(wǎng)