原型原型鏈腊凶,屬性的擴(kuò)展

原型和原型鏈

原型

  • 所有的變量都有一個(gè)隱式原型proto屬性(錯)
  • 所有的對象都有一個(gè)隱式原型proto屬性(對)
  • 所有的函數(shù)都有一個(gè)顯式原型prototype屬性(錯)
  • 所有的構(gòu)造函數(shù)都有一個(gè)顯式原型prototype屬性(對)
  • 屬性值:原型對象
  • 構(gòu)造函數(shù)prototype指向一個(gè)空的Object對象(錯)
  • 所有構(gòu)造函數(shù)prototype__proto__指向Object的prototype(對)

將偽數(shù)組轉(zhuǎn)化為真數(shù)組&怎么判斷一個(gè)變量是不是數(shù)組

  • 它從 Array.prototype 中繼承了一些它的專屬方法,如 push() , pop() , sort() , slice() , splice() 等,這些方法在偽數(shù)組和Object對象中是沒有的。
  • slice方法返回一個(gè)從開始到結(jié)束(不包括結(jié)束)選擇的數(shù)組的一部分淺拷貝到一個(gè)新數(shù)組對象伞鲫。原始數(shù)組不會被修改。
  • obj instanceof Array可以判斷是否為數(shù)組
    var arr = {length:3,0:"a",1:"b",2:"c"};
        arr.push('d');//報(bào)錯 偽數(shù)組不能使用數(shù)組的方法
        var arr2 = Array.prototype.slice.call(arr);
        arr2.push("d")
        console.log(arr2)

默認(rèn)值

  • Array.prototype指向一個(gè)空數(shù)組
  • Function.prototype指向一個(gè)空的Function
  • map() 方法創(chuàng)建一個(gè)新數(shù)組签舞,其結(jié)果是該數(shù)組中的每個(gè)元素都調(diào)用一個(gè)提供的函數(shù)后返回的結(jié)果秕脓。
  • join() 方法將數(shù)組(或一個(gè)類數(shù)組對象)的所有元素連接到一個(gè)字符串中。
    function test(arr,fn){
            arr =arr||Array.prototype;
            fn =fn||Function.prototype;

            return arr.map(fn).join(" ");
        }
        console.log(test());

==的使用規(guī)則

  • 引用數(shù)據(jù)類型進(jìn)行比較時(shí):
    • 先調(diào)用本身的valueof(),如果valueof方法返回的基本數(shù)據(jù)類型則直接做比較
    • 如果valueof()返回的不是基本數(shù)據(jù)類型,則調(diào)用比較對象本身的tostring()
  • 基本數(shù)據(jù)進(jìn)行比較時(shí):
    • 先通過number()轉(zhuǎn)化成一個(gè)number類型后再做比較
  //正常情況下[""]的valueof方法返回原數(shù)組[""]
    再調(diào)用[""].tostring()返回""
    再調(diào)用number()返回0
  console.log([""]==false)//true

  //方法的重寫
  Array.prototype.valueof = function(){
    return 1;
  }
  console.log([""]==flase)//false

原型鏈的繼承

  • 模擬jQuery中的html() on()
  • 體現(xiàn)出jQuery的鏈?zhǔn)秸{(diào)用 讀寫二合一
  //構(gòu)造函數(shù)   new Element()--->返回一個(gè)真實(shí)的dom節(jié)點(diǎn)
  function Element(id){
       this.ele = document.getElementById(id);
    }

    Element.prototype.innerText= function(val){
       var ele = this.ele;
       if(val){
         ele.innerText = val;
         return this;//鏈?zhǔn)秸{(diào)用
       }else{
         return ele.innerText;
       }
     }

   Element.prototype.on = function(val,fn){
            var ele = this.ele;
            if(ele.addEventListener){
                ele.addEventListener(val,fn);
                return this
            }
        }

     var textNode = new Element("test");
     textNode.innerText("text")//寫
     textNode.innerText("text").innerText()//鏈?zhǔn)秸{(diào)用
     console.log(textNode.innerText("text").innerText())//讀

     textNode.on("click",function(){
            alert(1);
        }).innerText('text')

綜合面試題

    //運(yùn)算符的優(yōu)先級
        //左右查詢
        //原型鏈
        //this
        //屬性的查找
        //提升

        function getName() {
            alert (5);
        }
        function Foo() {
            getName = function () { alert (1); };
            return this;
        }

        Foo.getName = function () {
            alert (2);
        };
        Foo.prototype.getName = function () {
            alert (3);
        };
        var getName = function () {
            alert (4);
        };

        Foo.getName(); //2
        getName();//4
        Foo().getName(); //1
        getName(); //1
        new Foo.getName(); //2
        new Foo().getName()//3

原型&原型鏈

  • 原型對象:它不是一個(gè)空的Object對象儒搭,但是它的proto永遠(yuǎn)指向Object的prototype
  • 原型鏈的頭
    Object.prototype.__proto__===>null
        Function.__proto__ === Function.prototype
        Object.__proto__  === Function.prototype
        Function.prototype.__proto__ === Object.prototype
        Object.prototype.__proto__=== null

javascript中的屬性

變量的查找

  • 左查詢吠架,右查詢

屬性描述符(元屬性)

  • 修飾屬性的屬性(元屬性)
  • 獲取對應(yīng)屬性的描述符
    • Object.getOwnPropertyDescriptor(obj,"name")

      第一個(gè)參數(shù):對應(yīng)的對象;第二個(gè)參數(shù):對應(yīng)對象的屬性
  • writable決定是否可以修改屬性的值
    • 一般和value綁定在一起
    • 當(dāng)writable為false時(shí),對應(yīng)的屬性的值是無法修改的搂鲫。

      在默認(rèn)情況下:繼續(xù)修改的話會靜默失敗

      在嚴(yán)格模式下:會報(bào)錯
  • configurable來決定屬性是否可以配置
    • 是否可以被delete
    • 刪除

      configurable:true 可以刪

      configurable:false 不可以刪
    • 重新配置

      能不能重新定義屬性的描述符

      configurable:true 可以重新配置

      configurable:false

      writable可以從true變?yōu)閒alse

      其他兩個(gè)屬性不可以動
    var damu={};
        Object.defineProperty(damu,"age",{
            value:18,
            writable:true
        })

        Object.defineProperty(damu,"age",{
            value:19,
            configurable:true//報(bào)錯
        })
    console.log(damu)//age:19
    var a=3;
        b=4;

        console.log(Object.getOwnPropertyDescriptor(window,"a"))
        console.log(Object.getOwnPropertyDescriptor(window,"b"))

        delete a;//a configurable:false不能刪除
        delete b;//b configurable:true可以被刪除

        console.log(a)//3
        console.log(b)//報(bào)錯
  • enumerable可枚舉:能否出現(xiàn)在對象的for in循環(huán)
    • 判斷屬性是否可枚舉(不會遍歷原型鏈)obj.propertyIsEnumerable("a")
    • 獲取可枚舉屬性列表(不會遍歷原型鏈)Object.keys(obj)
    • 獲取所有屬性的列表(不會遍歷原型鏈)Object.getOwnPropertyNames(obj)
    var damu={};
        Object.defineProperty(damu,"a",{
            enumerable:false
        })
        Object.defineProperty(damu,"b",{
            enumerable:true
        })
        Object.defineProperty(damu,"c",{
            enumerable:true
        })
        Object.defineProperty(damu,"d",{
            enumerable:true
        })
        Object.defineProperty(damu,"e",{
            enumerable:false
        })
        Object.defineProperty(damu,"f",{
            enumerable:false
        })

    for(item in damu){
            console.log(item);//輸出b,c,d
        }

        for(item in damu){
            if(damu.hasOwnProperty(item)){
                console.log(item);
            }
        }

    Object.defineProperty(Object.prototype,"text",{
      value:"text"
        enumerable:true
    })
    console.log(damu.text)//text可以找到

    console.log(damu.propertyIsEnumerable("f"))//false
    console.log(damu.propertyIsEnumerable("text"))//false不會在原型鏈上找
    console.log(Object.keys(damu))傍药;//可枚舉類型(不會在原型鏈上找)
    console.log(Object.getOwnPropertyNames)//所有屬性列表(不會在原型鏈上找)

定義對象屬性的兩種方法

  • 語法糖(讓定義對象更簡單)
    • 默認(rèn)屬性描述符都為true
    var damu={
            wife:"zdy"
        }
        damu.wife="fbb";
    console.log(damu);
  • 普通定義
    • 默認(rèn)屬性描述符都為false
    var damu={}
        Object.defineProperty(damu,"age",{
            value:18
        })
        console.log(damu);

對象的不變性

對象的常量屬性

  • 將屬性的writableconfigurable設(shè)置為false

禁止對象擴(kuò)展

  • Object.preventExtensions(obj)傳入一個(gè)對象

密封對象

  • 在禁止對象擴(kuò)展Object.preventExtensions(obj)的基礎(chǔ)上把現(xiàn)有屬性的configurable都調(diào)整為false
  • 調(diào)用Object.seal(obj)密封一個(gè)對象
  • 密封之后禁止了對象去擴(kuò)展屬性,原有的屬性不可以進(jìn)行重新定義或者刪除魂仍,但屬性值是可以修改的

冰封對象

  • 在密封對象(Object.seal(obj))的基礎(chǔ)上把現(xiàn)有屬性的writable都調(diào)整為false
  • 調(diào)用Object.freeze(obj)密封一個(gè)對象
  • 凍結(jié)之后禁止了對象去擴(kuò)展屬性拐辽,原有的屬性不可以進(jìn)行重新定義或者刪除,屬性值不可以進(jìn)行修改

深度凍結(jié)對象

  • 在js中2磷谩Qρ怠!所有方法的創(chuàng)建都是淺不變形的仑氛,他們只會影響目標(biāo)對象和他的直接屬性
  • 一般項(xiàng)目中不會深度凍結(jié)對象(如果需要使用,考慮是不是設(shè)計(jì)錯誤)
  • 如果使用深度凍結(jié)對象時(shí)需要使用for in一直循環(huán)
    var obj={
            hoddy:{
                hoddy1:"a",
                hoddy2:"b",
                hoddy3:"c",
                hoddy4:"d",
                hoddy5:"e"
            }
        };

        Object.freeze(obj);
        obj.hoddy.hoddy1 = "g"http://hoddy1會發(fā)生改變
        console.log(obj)

    for(item in obj){
      Object.freeze(obj[item]);
    }

存在性檢查

  • in(會遍歷原型鏈)"a" in obj
  • hasOwnProperty(不會遍歷原型鏈,只在對象中查找)obj.hasOwnProperty("a")

訪問描述符

  • 當(dāng)你給一個(gè)屬性定義set或者get锯岖,或者兩者都有時(shí)介袜,這個(gè)屬性會被定義為訪問描述符
  • 對于訪問描述符來說,Javascript會忽略他們的value和writable特性出吹。取而代之的是set和get函數(shù)遇伞。
  • value writableset get只能有一組
  • 訪問描述符可以使我們在對屬性進(jìn)行取賦值操作時(shí)預(yù)先變規(guī)定邏輯(比如if else)
  • 訪問描述符可以使我們的屬性變的更加安全!4防巍p椤!封裝

總結(jié)

  • 屬性描述符

    用來修飾屬性的屬性(元屬性) 5個(gè)
  • 數(shù)據(jù)描述符

    具有writable和value屬性描述符的屬性 我們稱之為數(shù)據(jù)描述符
  • 訪問描述符

    具有set和get屬性描述符的屬性 我們稱之為訪問描述符
  • writable為true的數(shù)據(jù)描述符
    • 屬性的查找:在實(shí)例對象的直接屬性沒有找到對應(yīng)的屬性則上原型鏈秋麸,如果整條原型鏈都沒有該屬性渐排,返回undefined
    • 屬性的設(shè)置:不管什么情況,設(shè)置操作只會影響對象的直接屬性

屬性的查找

  • 在對象中查找是否具有相同名稱的屬性灸蟆,如果找到驯耻,就會返回這個(gè)屬性的值。
  • 如果沒有找到炒考,則遍歷原型鏈
  • 無論·如何都沒找到可缚,返回undefined

屬性的設(shè)置

  • 如果屬性直接存在于對象中 不在原型鏈上(或者屬性直接存在于對象中 也在原型鏈上) 找到直接存在于對象中的屬性
    • 數(shù)據(jù)描述符(沒有setter/getter):直接修改對象中的屬性的值(注意writbale的值)
    • 訪問描述符:直接調(diào)用set方法
  • 如果屬性不直接存在于對象中 在原型鏈上
    • 該屬性是數(shù)據(jù)描述符(沒有setter/getter)
      • writbale為true

        直接在對象中添加一個(gè)屬性,我們稱之為屏蔽屬性
      • writbale為false

        報(bào)錯斋枢,不會生成屏蔽屬性
    • 該屬性是訪問描述符

      調(diào)用set帘靡,不會生成屏蔽屬性
  • 如果屬性不直接存在于對象中 也不在原型鏈上 在對象的直接屬性中添加一個(gè)屬性(數(shù)據(jù)描述符)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市瓤帚,隨后出現(xiàn)的幾起案子描姚,更是在濱河造成了極大的恐慌,老刑警劉巖缘滥,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轰胁,死亡現(xiàn)場離奇詭異,居然都是意外死亡朝扼,警方通過查閱死者的電腦和手機(jī)赃阀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來擎颖,“玉大人榛斯,你說我怎么就攤上這事÷酰” “怎么了驮俗?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長允跑。 經(jīng)常有香客問我王凑,道長搪柑,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任索烹,我火速辦了婚禮工碾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘百姓。我一直安慰自己渊额,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布垒拢。 她就那樣靜靜地躺著旬迹,像睡著了一般。 火紅的嫁衣襯著肌膚如雪求类。 梳的紋絲不亂的頭發(fā)上奔垦,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機(jī)與錄音仑嗅,去河邊找鬼宴倍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛仓技,可吹牛的內(nèi)容都是我干的鸵贬。 我是一名探鬼主播,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼脖捻,長吁一口氣:“原來是場噩夢啊……” “哼阔逼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起地沮,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嗜浮,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后摩疑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體危融,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年雷袋,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吉殃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,144評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡楷怒,死狀恐怖蛋勺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情鸠删,我是刑警寧澤抱完,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站刃泡,受9級特大地震影響巧娱,放射性物質(zhì)發(fā)生泄漏碉怔。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一禁添、第九天 我趴在偏房一處隱蔽的房頂上張望眨层。 院中可真熱鬧,春花似錦上荡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至纳账,卻和暖如春逛薇,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疏虫。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工永罚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人卧秘。 一個(gè)月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓呢袱,卻偏偏與公主長得像,于是被迫代替她去往敵國和親翅敌。 傳聞我的和親對象是個(gè)殘疾皇子羞福,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,092評論 2 355

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