"this" and inheritance

this 相關(guān)問(wèn)題

問(wèn)題1: apply、call 、bind有什么作用,什么區(qū)別

fn.call(context, param1, param2...)
fn.apply(context, [param1,param2...])
fun.bind(context, param1, param2...)

context:在函數(shù)運(yùn)行時(shí)指定的 this 值。需要注意的是,如果這個(gè)函數(shù)處于非嚴(yán)格模式下,指定為 null 或 undefined 時(shí)會(huì)自動(dòng)指向全局對(duì)象window。

作用:

  1. apply()、call()方法在指定this值和參數(shù)的情況下調(diào)用函數(shù)
  2. bind()是ES5的新方法,該方法創(chuàng)建一個(gè)新的函數(shù)(稱(chēng)為綁定函數(shù)),新函數(shù)與被調(diào)函數(shù)(綁定函數(shù)的目標(biāo)函數(shù))具有相同的函數(shù)體。當(dāng)被調(diào)用時(shí),第一個(gè)參數(shù)決定了運(yùn)行時(shí)的this,之后傳入的參數(shù)將會(huì)作為函數(shù)執(zhí)行時(shí)的實(shí)參來(lái)使用。

相同:
三者都是用來(lái)改變函數(shù)的this對(duì)象的指向的;第一個(gè)參數(shù)都是this要指向的對(duì)象,也就是想指定的上下文;都可以利用后續(xù)參數(shù)傳參;

不同:
bind返回對(duì)應(yīng)的函數(shù),便于稍后調(diào)用;apply,call則是立即調(diào)用。apply參數(shù)是數(shù)組或者類(lèi)數(shù)組對(duì)象,call參數(shù)是參數(shù)列表。

問(wèn)題2: 以下代碼輸出什么?


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


注意:john.sayHi() 相當(dāng)于   john.sayHi.call(john);




問(wèn)題3: 下面代碼輸出什么,為什么

func() 
function func() { 
  alert(this)
}

輸出:window

func()等價(jià)于  func.call(undefinded)
在非嚴(yán)格模式下瀏覽器會(huì)將undefined變?yōu)閃indow


問(wèn)題4:下面代碼輸出什么

document.addEventListener('click', function(e){
    console.log(this);
    setTimeout(function(){
        console.log(this);
    }, 200);
}, false);


結(jié)果:第一個(gè)console.log(this)的結(jié)果是#document,因?yàn)榇颂幍膖his指向被點(diǎn)擊的目標(biāo),setTimeout中的console.log(this)是指向window


注意:setTimeout、setInterval這兩個(gè)方法執(zhí)行的函數(shù)this是全局對(duì)象


問(wèn)題5:下面代碼輸出什么,why


var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName )
}
func.call(john) 


//結(jié)果john ,func.call(john)改變了this的值,當(dāng)前的this變成了john這個(gè)對(duì)象。 

問(wèn)題6: 以下代碼有什么問(wèn)題,如何修改

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //此處的this指的是被點(diǎn)擊的$btn
      this.showMsg(); //但是$btn對(duì)象上并沒(méi)有showMessage這個(gè)方法,所以報(bào)錯(cuò)。
    })
  },
  
  showMsg: function(){
    console.log('饑人谷');
  }
}


-----------修改后

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this);
      this.showMsg(); 
    }.bind(this)); //將this對(duì)象指向module對(duì)象
  },
  
  showMsg: function(){
    console.log('饑人谷');
  }
}



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

問(wè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();



關(guān)聯(lián):

p.__proto__ === Person.prototype
Person.prototype.constructor === Person

問(wèn)題8: 上例中,對(duì)對(duì)象 p可以這樣調(diào)用 p.toString()。toString是哪里來(lái)的? 畫(huà)出原型圖?并解釋什么是原型鏈

首先會(huì)向p中查找有沒(méi)有toString方法,沒(méi)有就向創(chuàng)建p的對(duì)象Person.prototype中查找,發(fā)現(xiàn)也沒(méi)有,Person既是創(chuàng)建p的對(duì)象,同時(shí)也是對(duì)象Object創(chuàng)建的實(shí)例,所以向創(chuàng)建Person的Object.prototype中查找toSring()就查找到了。

問(wèn)題9:對(duì)String做擴(kuò)展,實(shí)現(xiàn)如下方式獲取字符串中頻率最高的字符


var str = 'ahbbccdeddddfg';

String.prototype.getMostOften = function (){
    var obj = {};
    for(var i = 0;i<this.length; i++){
            var j =this[i];
            if(obj[j]){
                obj[j]++;
            }
            else{
                obj[j]= 1;
            }
    }

     var max = 0 ,key= 0 ;

     for(var k in obj){
        if(obj[k]>max){
            max = obj[k];
            key= k;
        }

     }

     return max;

};
var ch = str.getMostOften();
console.log(ch); //d , 因?yàn)閐 出現(xiàn)了5次


問(wèn)題10: instanceOf有什么作用??jī)?nèi)部邏輯是如何實(shí)現(xiàn)的?

instanceof操作符,用于判斷一個(gè)對(duì)象是不是某個(gè)類(lèi)型的實(shí)例,
它是通過(guò)測(cè)試一個(gè)對(duì)象(object)的原型鏈上是否有某個(gè)構(gòu)造函數(shù)的原型(prototype)

A instanceOf B; // 返回true/false

繼承相關(guān)問(wèn)題

問(wèn)題11:繼承有什么作用?

繼承是指一個(gè)對(duì)象直接使用另一對(duì)象的屬性和方法。
繼承提高了代碼復(fù)用性,減少重復(fù)勞動(dòng)。體現(xiàn)了面向?qū)ο笾械亩鄳B(tài)性。

問(wèn)題12: 下面兩種寫(xiě)法有什么區(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);


方法1中printName方法在People的實(shí)例對(duì)象上,當(dāng)每次創(chuàng)建一個(gè)People實(shí)例對(duì)象都會(huì)額外開(kāi)辟內(nèi)存去存放printName,方法2中的printName是寫(xiě)在原型上,當(dāng)實(shí)例對(duì)象要使用該方法只需到原型鏈里調(diào)用就可以了,達(dá)到節(jié)省內(nèi)存的效果。

問(wèn)題13: Object.create 有什么作用?兼容性如何?

Object.create(proto, [ propertiesObject ])

作用:
使用指定的原型對(duì)象及其屬性去創(chuàng)建一個(gè)新的對(duì)象



proto:用作新對(duì)象原型的對(duì)象


propertiesObject:(可選的)一個(gè)為新對(duì)象定義額外屬性的對(duì)象

用法例子

Student.prototype = Object.create(Person.prototype)
這里我們通過(guò)Object.create復(fù)制了一個(gè)新的prototype而不是直接把Person.prtotype直接賦值,因?yàn)橐藐P(guān)系,這樣會(huì)導(dǎo)致后續(xù)修改子類(lèi)的prototype也修改了父類(lèi)的prototype,因?yàn)橐藐P(guān)系修改的是同一個(gè)值。

兼容性:
Object.create是ES5方法,之前版本通過(guò)遍歷屬性也可以實(shí)現(xiàn)淺拷貝

問(wèn)題14: hasOwnProperty有什么作用? 如何使用?

  1. hasOwnProperty可以判斷一個(gè)對(duì)象包含的某個(gè)屬性是否為自定義屬性,而不是原型鏈上的屬性。
  2. hasOwnProperty是JavaScript中唯一一個(gè)處理屬性但是不查找原型鏈的函數(shù)
//語(yǔ)法
Object.hasOwnProperty(attributeName)

問(wèn)題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;
}

起到了繼承Person的作用,當(dāng)new Male時(shí),Male中的this指向創(chuàng)建的對(duì)象,call把Person中的this設(shè)置為創(chuàng)建的對(duì)象,就達(dá)到了繼承Person屬性的目的。

問(wèn)題16: 補(bǔ)全代碼,實(shí)現(xiàn)繼承


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

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

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


Male.prototype = Object.create(Person.prototype);
Male.prototype.constructor = Male;
Male.prototype.printAge = function(){
   console.log("My age is "+this.age);
};




var ruoyu = new Male('xx', '男', 22);
ruoyu.printName();
ruoyu.printAge();

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容