this、原型鏈、繼承

this問題

1.apply、call 、bind有什么作用,什么區(qū)別?

  • .call()、apply()表示調(diào)用一個函數(shù),傳入函數(shù)執(zhí)行上下文及參數(shù),既this指向。但是apply()的參數(shù)是傳入數(shù)組或類數(shù)組,call()的參數(shù)是若干個指定參數(shù)。
  • bind()創(chuàng)建一個新函數(shù),當(dāng)被調(diào)用時,將其this關(guān)鍵字設(shè)置為提供的值,在調(diào)用新函數(shù)時,在任何提供之前提供一個給定的參數(shù)序列

2.以下代碼輸出什么?

var john = { 
  firstName: "John" 
}
function func() { 
  alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi() //輸出 john:hi! ,因為this調(diào)用了sayHi這function的對象john

3.下面代碼輸出什么,為什么?

func() 
function func() { 
  alert(this)
}  //輸出 windowd對象,因為函數(shù)被調(diào)用時是在全局作用域下而不是某個具體的對象下,所以函數(shù)中this指向window

4.下面代碼輸出什么?

document.addEventListener('click', function(e){
    console.log(this);
    setTimeout(function(){
        console.log(this);
    }, 200);
}, false);//輸出document,200ms后輸出window,因為定時器中this指向全局

5.下面代碼輸出什么,why?

var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName )
}
func.call(john) //輸出john,因為func.call(john)為this指定了對象,this指向john

6.以下代碼有什么問題,如何修改

var module= {
  bind: function(){
  var  _this = this  
    $btn.on('click', function(){
      console.log(this) //this指的是$btn
       _this.showMsg(); //報錯:showMsg() is not a function ,替換成全局的 _this即可找到showMsg().
    })
  },

  showMsg: function(){
    console.log('hello');
  }
}

原型鏈問題

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("jack")
p.sayName();

Person是一個構(gòu)造函數(shù),構(gòu)造函數(shù)構(gòu)造出實例 p,p內(nèi)部有proto屬性,Person具有prototype屬性為所屬實例訪問的公共空間,指向Person的原型,該原型擁有constructor屬性,其中Person.prototype.constructor ===Person

Person.prototype.constructor == Person,
Person.prototype == p.__proto__,
p.__proto__.constructor == Person,
Person.prototype.__proto__ == Object.prototype,
Object.prototype.constructor == Object,
Object.prototype.__proto__ == null

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

toString()來自object.prototype
首先p會在自己的方法和屬性里找toString,沒有找到的話會從p.proto,也就是構(gòu)造函數(shù)的Person.prototype中查找,如果還未找到,那就繼續(xù)從Person.prototype.proto,即Object.prototype中查找,因為object.proto = null,這條鏈就是原型鏈。

原型圖

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

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

    String.prototype.getMostOften = function(){
        var Str = {};
        var num;
        for(var i=0;i<this.length;i++){
            num = this[i];
            if(!Str[num]) {
                Str[num] = 1;
            }else{
                Str[num]++;
            }
        }
        var maxNum = 0;
        var strKey;
        for(var key in Str){
            if(Str[key] > maxNum){
                maxNum = Str[key];
                strKey = key;
            }
        }
        return strKey;
    };

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

  • 語法:object instanceof constructor
  • 檢測 constructor.prototype是否存在于參數(shù)Object的原型鏈上
  • 內(nèi)部邏輯:檢查object.proto === constructor.prototype,如果是則返回 true,否則檢查object.proto.proto === constructor.prototype,依次類推,直到檢查到 null ,原型鏈到頭,如果還沒有找到與 constructor.prototype 相等的值,則返回 false 。

繼承問題

11.繼承有什么作用?

通過繼承能實現(xiàn)的東西包括,子類擁有了父類的屬性和方法,同時利用繼承在重復(fù)的時候無需每一次都重寫一次,直接利用繼承的特性就能獲得想要的類,同時如果需要添加則直接使用覆蓋即可,即便更改了,父類本身還是保持不變.

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('jack', 27);
 //方法二通過將方法放在原型鏈上,起到了公共代碼的作用,節(jié)省了代碼量,提升了性能.

13.Object.create 有什么作用?兼容性如何?

Object.create() 方法使用指定的原型對象和其屬性創(chuàng)建了一個新的對象。

14.hasOwnProperty有什么作用? 如何使用?

hasOwnProperty() 方法會返回一個布爾值,指示對象是否具有指定的屬性作為自身(不繼承)屬性。該方法會忽略掉那些從原型鏈上繼承到的屬性

object.hasOwnProperty(prop)

15.如下代碼中call的作用是什么?

function Person(name, sex){
    this.name = name;
    this.sex = sex;
}
function Male(name, sex, age){
    Person.call(this, name, sex);    //這里的 call 有什么作用,call調(diào)用了Person構(gòu)造函數(shù),將Person里面的this替換成指向Male構(gòu)造函數(shù)的對象
    this.age = age;
}

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;
    this.paintName=function(){
        console.log(this.name)
    }
}

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

var ruoyu = new Male('jack', '男', 27);
ruoyu.paintName();

【個人總結(jié),如有錯漏,歡迎指出】
:>

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

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

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