高級2 - this_原型鏈_繼承

this相關(guān)問題

問題1:apply洋访、call有什么作用读串,什么區(qū)別

  • apply()call()函數(shù)都可以 指定this值和參數(shù)值的情況下調(diào)用某個函數(shù)。
  • call()apply()的作用一樣,區(qū)別在于提供給原函數(shù)的參數(shù)的方式不一樣
    • apply()函數(shù)只接受兩個參數(shù),提供給原函數(shù)的參數(shù)以數(shù)組或類數(shù)組對象的形式存在
    • call()接收無限個參數(shù)廓旬, 第二個參數(shù)及其后面的參數(shù)就是提供給原函數(shù)的參數(shù)。

問題2:以下代碼輸出什么

var john = { 
  firstName: "John" 
}
function func() { 
  alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi()     //  彈出John:hi谐腰!

問題3: 下面代碼輸出什么孕豹,為什么

func()   //  彈出window對象

function func() { 
  alert(this)
}
  • 因為在函數(shù)func()被直接調(diào)用時,this綁定到全局對象十气。在瀏覽器中励背,window 就是該全局對象

問題4:下面代碼輸出什么

function fn0(){
    function fn(){
        console.log(this);
    }
    fn();
}

fn0();  //  輸出window對象


document.addEventListener('click', function(e){
    console.log(this);   //  輸出document對象
    setTimeout(function(){
        console.log(this);   //  輸出window對象
    }, 200);
}, false);

問題5:下面代碼輸出什么,why

var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName ) 
}
func.call(john)    //  彈出John
  • func()函數(shù)通過call()函數(shù)調(diào)用砸西,此時this為John對象叶眉,john.firstName存在,輸出"John"

問題6: 以下代碼有什么問題籍胯,如何修改

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) // 這里的this指的是$btn
      this.showMsg();  //  $btn沒有showMsg的屬性竟闪,如果調(diào)用,這里會報錯
    })
  },
  
  showMsg: function(){
    console.log('饑人谷');
  }
}
  • 應(yīng)該改成如下:
var module= {
  bind: function(){
    var self = this;  // 先在外部將this保存成變量杖狼,再在內(nèi)部調(diào)用這個變量
    $btn.on('click', function(){
      console.log(this);
      self.showMsg(); 
    })
  },

  showMsg: function(){
    console.log('饑人谷');
  }
}

這樣,再進行測試妖爷,發(fā)現(xiàn)成功輸出饑人谷

修改之后測試.png

原型鏈相關(guān)問題

問題7:有如下代碼蝶涩,解釋Person、 prototype絮识、__proto__绿聘、p、constructor之間的關(guān)聯(lián)次舌。

function Person(name){
    this.name = name;
}
Person.prototype.sayName = function(){
    console.log('My name is :' + this.name);
}
var p = new Person("若愚")
p.sayName();
  • People是一個構(gòu)建函數(shù)熄攘,protoTypePeople的屬性(原型),即可以通過People.protoType的方式來獲取這個屬性彼念,其類型是一個對象挪圾。
  • pPeople構(gòu)建的實例浅萧,它有一個屬性__proto__,它的值引用了p的父類PeopleprotoType屬性哲思。
  • constructorprotoType的一個屬性洼畅,其值指向函數(shù)本身,例如:People.protoType.constructor就是People本身棚赔。

問題8: 上例中帝簇,對對象 p可以這樣調(diào)用 p.toString()。toString是哪里來的? 畫出原型圖?并解釋什么是原型鏈靠益。

question8.png
  • toString()實際上是Object的方法
    • 如上原型圖所示:對對象p調(diào)用p.toString()時丧肴,JS先從其自身的方法中找toString()方法,沒有找到胧后;
    • 然后通過__proto__屬性找其父元素PeopleprotoType屬性中有沒有toString()方法芋浮,依然沒找到;
    • 然后再通過其父元素PeopleprotoType屬性中的__proto__屬性即Object.protoType繼續(xù)尋找绩卤,在Object.protoType找到了toString()方法途样。
  • 每個對象都有一個隱藏的__proto__屬性,這個屬性就是對其父元素原型對象(protoType)的引用濒憋。
  • 由于原型對象本身也是對象何暇,也有__proto__屬性,它的__proto__屬性又指向了其更高父元素原型對象凛驮。這樣就形成了一條鏈裆站,這就是原型鏈

問題9:對String做擴展黔夭,實現(xiàn)如下方式獲取字符串中頻率最高的字符

// 答案
String.prototype.getMostOften = function(){
    var box = {},
        max = 0,
        maxKey = "";
    for (var i=0, word;i<this.length;i++) {
        word = this[i];
        if (box[word] === undefined) {
            box[word] = 1;
        } else {
            box[word] += 1;
        }
    }
    for (key in box) {
        if (box[key] > max) {
            max = box[key];
            maxKey = key;
        }
    }
    return maxKey
}



// 題目
var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現(xiàn)了5次

問題10: instanceOf有什么作用宏胯?內(nèi)部邏輯是如何實現(xiàn)的?

  • instanceof用來檢查一個對象是不是另一個構(gòu)造對象的實例本姥。
  • 其內(nèi)部邏輯是測試一個對象在其原型鏈中是否存在一個構(gòu)造函數(shù)的 prototype 屬性肩袍。
  • 所以如果表達式obj instanceof Foo 返回true,則并不意味著該表達式會永遠返回true婚惫,因為Foo.prototype屬性的值有可能會改變氛赐,改變之后的值很有可能不存在于obj的原型鏈上,這時原表達式的值就會成為false先舷。

繼承相關(guān)問題

問題11:繼承有什么作用?

  • 繼承的主要作用有兩個
    • 繼承可以使子類共享父類的屬性和方法
    • 繼承可以覆蓋和擴展父類的屬性和方法

問題12: 下面兩種寫法有什么區(qū)別?

//方法1
function People(name, sex){
    this.name = name;
    this.sex = sex;
    this.printName = function(){
        console.log(this.name);
    }
}
var p1 = new People('饑人谷', 2)

//方法2
function Person(name, sex){
    this.name = name;
    this.sex = sex;
}

Person.prototype.printName = function(){
    console.log(this.name);
}
var p1 = new Person('若愚', 27);
  • 第一種方法將會把printName這個方法重新定義在每個構(gòu)建的對象上艰管,這樣如果構(gòu)建的對象比較多,也將會有許多個printName函數(shù)蒋川,將會對性能產(chǎn)生影響
  • 第二種方法會把printName這個方法定義到構(gòu)建函數(shù)的protoType上牲芋,這樣新構(gòu)建的函數(shù)將會通過原型鏈獲取到這個方法,節(jié)約了內(nèi)存
  • 推薦使用第二種方法

問題13: Object.create 有什么作用?兼容性如何缸浦?

  • Object.create方法可以創(chuàng)建一個擁有指定原型和若干個指定屬性的對象夕冲。
  • 在繼承中,Object.create可以用于繼承屬性餐济。
  • Object.create是在ES5中規(guī)定的耘擂,其兼容性見下圖:
Object.create-compatibilty.png

問題14: hasOwnProperty有什么作用? 如何使用絮姆?

  • hasOwnProperty方法會返回一個布爾值醉冤,其用來判斷某個對象是否含有特定的自身屬性,該方法會忽略掉那些從原型鏈上繼承到的屬性篙悯。
  • 語法為obj.hasOwnProperty(prop)蚁阳,參數(shù)prop為要檢測的屬性

問題15:如下代碼中call的作用是什么?

function Person(name, sex){
    this.name = name;
    this.sex = sex;
}
function Male(name, sex, age){
    Person.call(this, name, sex);    //這里的 call 有什么作用
    this.age = age;
}
  • 這里的call的作用是改變構(gòu)造函數(shù)People的作用域,這樣就可以讓PeopleMale的作用域中執(zhí)行鸽照,這樣People中的一些屬性賦值語句也會在Male中執(zhí)行螺捐。
  • 通過這種方式就實現(xiàn)了屬性的繼承。

問題16: 補全代碼矮燎,實現(xiàn)繼承

function Person(name, sex){
    this.name = name;
    this.sex = sex;
}

Person.prototype.getName = function(){
    console.log(this.name);
};    

function Male(name, sex, age){
   Person.call(this, name, sex);
   this.age = age;
}

var _prototype = Object.create(Person.prototype);
_prototype.consturctor = Male;
Male.prototype = _prototype;

Male.prototype.getAge = function(){
    console.log(this.age);
};

var ruoyu = new Male('若愚', '男', 27);
ruoyu.getName();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末定血,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子诞外,更是在濱河造成了極大的恐慌澜沟,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件峡谊,死亡現(xiàn)場離奇詭異茫虽,居然都是意外死亡,警方通過查閱死者的電腦和手機既们,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門濒析,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人啥纸,你說我怎么就攤上這事号杏。” “怎么了斯棒?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵馒索,是天一觀的道長。 經(jīng)常有香客問我名船,道長,這世上最難降的妖魔是什么旨怠? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任渠驼,我火速辦了婚禮,結(jié)果婚禮上鉴腻,老公的妹妹穿的比我還像新娘迷扇。我一直安慰自己百揭,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布蜓席。 她就那樣靜靜地躺著器一,像睡著了一般。 火紅的嫁衣襯著肌膚如雪厨内。 梳的紋絲不亂的頭發(fā)上祈秕,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音雏胃,去河邊找鬼请毛。 笑死,一個胖子當(dāng)著我的面吹牛瞭亮,可吹牛的內(nèi)容都是我干的方仿。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼统翩,長吁一口氣:“原來是場噩夢啊……” “哼仙蚜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起厂汗,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤委粉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后面徽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體艳丛,經(jīng)...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年趟紊,在試婚紗的時候發(fā)現(xiàn)自己被綠了氮双。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡霎匈,死狀恐怖戴差,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情铛嘱,我是刑警寧澤暖释,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站墨吓,受9級特大地震影響球匕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜帖烘,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一亮曹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦照卦、人聲如沸式矫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽采转。三九已至,卻和暖如春瞬痘,著一層夾襖步出監(jiān)牢的瞬間故慈,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工图云, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留惯悠,地道東北人。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓竣况,卻偏偏與公主長得像克婶,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子丹泉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,781評論 2 354

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