this & 原型鏈 & 繼承

this 相關

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

apply()和call()方法都是在指定一個this值和參數(shù)的情況下調用某個函數(shù)。
bind()方法創(chuàng)建一個新的函數(shù), 當被調用時,它的this關鍵字被設置為提供的值 ,在調用新函數(shù)時,提供任何一個給定的參數(shù)序列。
區(qū)別

  • apply與call只有一個區(qū)別
    • call()方法接受的是若干個參數(shù)的列表。fun.call(thisArg[, arg1[, arg2[, ...]]])
    • apply()方法接受的是一個包含多個參數(shù)的數(shù)組。fun.apply(thisArg[, argsArray])
  • bind()與call和apply不同之處在于它返回一個函數(shù), fun.bind(thisArg[, arg1[, arg2[, ...]]])

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

var john = { 
  firstName: "John" 
}
function func() { 
  alert(this.firstName + ": hi!")
}
john.sayHi = func
john.sayHi() //輸出john: hi! , 方法調用,this指向調用者

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

func()  //輸出window, this是全局對象
function func() { 
  alert(this)
}

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

document.addEventListener('click', function(e){
    console.log(this);  //輸出document, 在事件處理程序中this代表事件源DOM對象
    setTimeout(function(){
        //輸出window, setTimeout和setInterval執(zhí)行的函數(shù)this是全局對象
        console.log(this);  
    }, 200);
}, false);

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

var john = { 
  firstName: "John" 
}

function func() { 
  alert( this.firstName )
}
func.call(john) //輸出John, call()的第一個參數(shù)指定了this為john對象

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

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //這里的this指$btn
      this.showMsg();  //$btn上沒有showMsg()這個方法
    })
  },
  
  showMsg: function(){
    console.log('饑人谷');
  }
}
// 修改后
var module= {
  bind: function(){
    var _this = this //這時this的值是module, 把值存入_this
    $btn.on('click', function(){
      console.log(this)  //this為$btn 
      _this.showMsg();  //輸出饑人谷
    })
  },
  
  showMsg: function(){
    console.log('饑人谷');
  }
}

原型鏈相關問題

問題7:有如下代碼,解釋Person、 prototype、__proto__ 、p、constructor之間的關聯(lián)。

  • Person是函數(shù)定義的類, 類(函數(shù))自動獲得屬性prototype。
  • p是Person的實例, 每個類的實例都會有一個內部屬性__proto__ ,指向類的prototype屬性
  • prototype是構造函數(shù)內部的原型對象,所以擁有contructor和__proto__ 屬性。constructor指向了構造函數(shù)Person。
function Person(name){
    this.name = name;
}
Person.prototype.sayName = function(){
    console.log('My name is :' + this.name);
}
var p = new Person("若愚")
p.sayName();

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

當調用p.tostring()時, 先會在p里找tostring方法, 找不到會沿著__proto__到 Person.prototype中找,還找不到就接著沿著__proto__找, 直到在object.prototype中找到為止
p.__proto__ ==> Person.prototype.__proto__ ==> object.prototype

原型圖.png

在 javaScript 中,每個對象都有一個指向它的原型(prototype)對象的內部鏈接。這個原型對象又有自己的原型,直到某個對象的原型為 null 為止(也就是不再有原型指向),組成這條鏈的最后一環(huán)。這種一級一級的鏈結構就稱為原型鏈(prototype chain)。

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

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

代碼:

String.prototype.getMostOften = function(){
    var obj = {}
    for(var i=0; i< this.length; i++){
      if(obj[this.charAt(i)]){
        obj[this.charAt(i)]++
      }else if(!obj[this.charAt(i)]){
        obj[this.charAt(i)] = 1
      }
    }
  
  var max = 0,
      val = ''
  for(var key in obj){
    if(obj[key] > max){
      max = obj[key]
      val = key
    }
  }
  return val
}


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

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

語法:object instanceof constructor
instanceof 運算符用來檢測 constructor.prototype 是否存在于參數(shù) object 的原型鏈上。即左側的對象是否是右側類的實例,如果是則表達式返回true;否則返回false。
內部邏輯: 循環(huán)判斷 obj.__proto__.__proto__..... === con.prototype


繼承

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

繼承是指一個對象直接使用另一對象的屬性和方法。
優(yōu)點:

  • 優(yōu)化代碼結構和對象關系
  • 優(yōu)化內存空間, 一些共用的方法和屬性不用重復寫了. 子類需要添加或修改新的方法時, 可以重寫或擴展而不影響父類

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

方法2把printName寫到了原型鏈里, 節(jié)約了代碼量, 提高了性能, 而方法1寫在構造函數(shù)中, 每創(chuàng)造一個實例都要運行一遍printName函數(shù).

//方法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);

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

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

child = Object.create(parent.prototype)
//使child.__proro__ = parent.prototype
ES5兼容性

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

hasOwnPerperty是Object.prototype的一個方法,可以判斷一個對象是否包含自定義屬性而不是原型鏈上的屬性
hasOwnProperty是JavaScript中唯一一個處理屬性但是不查找原型鏈的函數(shù)

obj.hasOwnProperty(prop)
//prop : 要檢查的屬性名
//obj: 要檢查的對象
//返回一個布爾值

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

function Person(name, sex){
    this.name = name;
    this.sex = sex;
}
function Male(name, sex, age){
    //運行構造函數(shù),把屬性賦值到自己內部
    Person.call(this, name, sex);    //call主要是為了把環(huán)境改到自己的作用域內
    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
}

function inherit(superType, subType){
    subType.prototype = Object.create(superType.prototype)
    subType.prototype.constructor = subType
}
inherit(Person, Male)
Male.prototype.getAge = function(){
    console.log(this.age)
};

var ruoyu = new Male('若愚', '男', 27);
ruoyu.getName();
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • this 相關問題 問題1: apply、call 有什么作用,什么區(qū)別 Javascript的每個Functio...
    Maggie_77閱讀 611評論 0 0
  • 一、this 相關問題 知乎上關于this的解答 this 的值到底是什么?一次說清楚 this 的工作原理在js...
    66dong66閱讀 568評論 0 0
  • 1: apply、call 、bind有什么作用,什么區(qū)別 call 和 apply 都是為了改變某個函數(shù)運行時的...
    高進哥哥閱讀 269評論 0 0
  • this 問題1: apply、call 、bind有什么作用,什么區(qū)別 call 和 apply 都是為了改變某...
    好奇而已閱讀 321評論 0 0
  • 1. apply、call 、bind有什么作用,什么區(qū)別? call ,apply的作用:調用一個函數(shù),傳入函數(shù)...
    Rising_suns閱讀 403評論 0 0