this_原型鏈_繼承

1:apply谬运、call 隙赁、bind有什么作用,什么區(qū)別

call 和 apply 都是為了改變某個函數運行時的上下文(context)而存在的梆暖,換句話說伞访,就是為了改變函數體內部 this 的指向。
apply轰驳、call 的區(qū)別
對于 apply厚掷、call 二者而言弟灼,作用完全一樣,只是接受參數的方式不太一樣蝗肪。例如袜爪,有一個函數定義如下:

var func = function(arg1, arg2) {

};
就可以通過如下方式來調用:
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])

其中 this 是你想指定的上下文,他可以是任何一個 JavaScript 對象(JavaScript 中一切皆對象)薛闪,call 需要把參數按順序傳遞進去辛馆,而 apply 則是把參數放在數組里。

JavaScript 中豁延,某個函數的參數數量是不固定的昙篙,因此要說適用條件的話,當你的參數是明確知道數量時用 call 诱咏。而不確定的時候用 apply苔可,然后把參數 push 進數組傳遞進去apply 和 call 。

再來說說bind袋狞,bind() 方法與 apply 和 call 很相似焚辅,也是可以改變函數體內 this 的指向。
而bind苟鸯,MDN的解釋是:bind()方法會創(chuàng)建一個新函數同蜻,稱為綁定函數,當調用這個綁定函數時早处,綁定函數會以創(chuàng)建它時傳入 bind()方法的第一個參數作為 this湾蔓,傳入 bind() 方法的第二個以及以后的參數加上綁定函數運行時本身的參數按照順序作為原函數的參數來調用原函數。

apply砌梆、call默责、bind比較
那么 apply、call咸包、bind 三者相比較桃序,之間又有什么異同呢?何時使用 apply烂瘫、call葡缰,何時使用 bind 呢。簡單的一個栗子:

var obj = {
    x: 81,
};
var foo = {
    getX: function() {
        return this.x;
    }
}
console.log(foo.getX.bind(obj)());  //81
console.log(foo.getX.call(obj));    //81
console.log(foo.getX.apply(obj));   //81

三個輸出的都是81忱反,但是注意看使用 bind() 方法的,他后面多了對括號滤愕。
區(qū)別是温算,當你希望改變上下文環(huán)境之后并非立即執(zhí)行,而是回調執(zhí)行的時候间影,使用 bind() 方法注竿。而 apply/call 則會立即執(zhí)行函數。

總結一下:

  • apply 、 call 巩割、bind 三者都是用來改變函數的this對象的指向的裙顽;
  • apply 、 call 宣谈、bind 三者第一個參數都是this要指向的對象愈犹,也就是想指定的上下文;
  • apply 闻丑、 call 漩怎、bind 三者都可以利用后續(xù)參數傳參;
    bind 是返回對應函數嗦嗡,便于稍后調用勋锤;apply 、call 則是立即調用 侥祭。

2: 以下代碼輸出什么?

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

輸出:John:hi!
誰在調用函數叁执,誰就是this,所以this是john矮冬,代碼執(zhí)行后彈出John:hi!

3: 下面代碼輸出什么谈宛,為什么

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

輸出 window
在函數被直接調用時this綁定到全局對象。在瀏覽器中欢伏,window 就是該全局對象

4:下面代碼輸出什么

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

輸出 document,window
綁定事件函數時入挣,this表示觸發(fā)此事件的DOM對象。
setTimeout硝拧、setInterval這兩個方法執(zhí)行的函數this也是全局對象

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

var john = { 
  firstName: "John" 
}
function func() { 
  alert( this.firstName )
}
func.call(john)

輸出 John ,call方法可以在函數調用的時候將第一個參數設置為this值障陶,所以現在的this就是傳入的參數對象john滋恬。

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

var module= {
  bind: function(){
    $btn.on('click', function(){
      console.log(this) //this指什么
      this.showMsg();
    })
  },

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

這里的this指的是觸發(fā)此事件的DOM對象抱究,不是module恢氯。
this.showMsg(); //由于this是$btn,所以在執(zhí)行這句是會報錯鼓寺。

var module= {
  bind: function(){
    var _this=this;
    $btn.on('click', function(){
      console.log(_this) //this指什么
      _this.showMsg();
    })
  },

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

7:有如下代碼勋拟,解釋Person、 prototype妈候、proto敢靡、p、constructor之間的關聯苦银。

function Person(name){
    this.name = name;
}
Person.prototype.sayName = function(){
    console.log('My name is :' + this.name);
}
var p = new Person("wang")
p.sayName();

Person是構造函數啸胧,也是一個對象赶站,這個對象里面存在一個prototype屬性,而構造函數內部定義了實例的屬性和方法纺念,這些屬性和方法是屬于該類的所有實例的特征贝椿;
p是通過構造函數Person構造出來的實例,也是擁有proto屬性陷谱。

p.__proto__ === Person.prototype;

prototype是構造函數內部的原型對象烙博,所以擁有contructor和proto屬性,其中contructor屬性指向構造函數Person叭首,proto指向該對象的原型习勤,即

Person.prototype.__proto__ === Object.prototype;
Person.prototype.constructor == Person

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

原型鏈

如圖所示,p.toString()方法是繼承構造函數Object的原型對象里定義的toString方法眷唉,首先p會找自己的toString方法予颤,如果沒有找到,會沿著proto屬性繼續(xù)到構造函數Person的prototype里找toString方法冬阳,如果還未找到蛤虐,再繼續(xù)往Person.prototype的proto即Object.prototype找toString方法,最后找到toString()方法肝陪。

原型鏈:由于原型對象本身也是對象驳庭,而每個javascript對象都有一個原型對象,每個對象都有一個隱藏的proto屬性氯窍,原型對象也有自己的原型饲常,而它自己的原型對象又可以有自己的原型,這樣就組成了一條鏈狼讨,這個就是原型鏈贝淤。在訪問對象的屬性時,如果在對象本身中沒有找到政供,則會去原型鏈中查找播聪,如果找到,直接返回值布隔,如果整個鏈都遍歷且沒有找到屬性离陶,則返回undefined。原型鏈一般實現為一個鏈表衅檀,這樣就可以按照一定的順序來查找枕磁。

9:對String做擴展,實現如下方式獲取字符串中頻率最高的字符

var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現了5次
var str = 'ahbbccdeddddfg';
   function String(str){
     this.str=str;
   }
   String.prototype.getMostOften=function(){
     var obj={};
     for(var i=0;i<this.str.length;i++){
       if(obj[this.str[i]]){
         obj[this.str[i]]++;
       }else{
         obj[this.str[i]]=1;
       }
     }
     console.log(obj);
     var count=0,maxValue;
     for(var key in obj){
       if(obj[key]>count){
         maxValue=key;
         count=obj[key];
       }
     }
     console.log("出現頻率最多的字符為"+maxValue+",共有"+count+"個");
   }
   str=new String(str);
   var ch = str.getMostOften();
   console.log(ch);

10: instanceOf有什么作用术吝?內部邏輯是如何實現的计济?

instanceOf:判斷一個對象是否為另一個對象的實例
instanceof 運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性。
語法
object instanceof constructor
參數
object
要檢測的對象.
constructor
某個構造函數

內部邏輯
function instanceOf(obj,fn) {
  var oldProto = obj.__proto__;
  do {
  if (oldProto=== fn.prototype){
    return true;
  }else {
    oldProto = oldProto.__proto__
  }
  }while(oldProto){
  return false;
}

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('wang', 2)
//方法2
function Person(name, sex){
    this.name = name;
    this.sex = sex;
}

Person.prototype.printName = function(){
    console.log(this.name);
}
var p1 = new Person('hu', 27);

  • 第一種方式是將所有的屬性和方法都寫在構造函數中淘衙,那么創(chuàng)建的每一個實例都會存有相同的方法传藏,會造成很大的內存浪費。
  • 而第二種是將方法定義在原型上彤守,這樣只有在原型對象上才會有這個公有方法毯侦,所有實例對象都可以共享。

13: Object.create 有什么作用具垫?兼容性如何侈离?

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

Object.create(proto, [ propertiesObject ])
兼容性

14: hasOwnProperty有什么作用筝蚕? 如何使用卦碾?

obj,hasOwnProperty(pro) 判斷某個對象是否含有指定的屬性但是該方法會忽略掉那些從原型鏈上繼承到的屬性

function People(){
  this.name='lwk'
}
People.prototype.sayName=function(){console.log(this.name)}
var p = new People()
p.hasOwnProperty('name')//true
p.hasOwnProperty('sayName')//false

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調用Person方法,指定Person方法中的this為Male起宽,并傳入參數sex洲胖,age

16: 補全代碼,實現繼承

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

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

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

    Male.prototype = Object.create(Person.prototype);
    Male.prototype.constructor = Male;

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

    Male.prototype.printName = function(){
       this.getName();
       this.getAge();
    }

    var ruoyu = new Male('王虎', '男', 26);
    ruoyu.printName();
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末坯沪,一起剝皮案震驚了整個濱河市绿映,隨后出現的幾起案子,更是在濱河造成了極大的恐慌腐晾,老刑警劉巖叉弦,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異赴魁,居然都是意外死亡卸奉,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門颖御,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榄棵,“玉大人,你說我怎么就攤上這事潘拱≌铞” “怎么了?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵芦岂,是天一觀的道長瘪弓。 經常有香客問我,道長禽最,這世上最難降的妖魔是什么腺怯? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任袱饭,我火速辦了婚禮,結果婚禮上呛占,老公的妹妹穿的比我還像新娘虑乖。我一直安慰自己,他們只是感情好晾虑,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布疹味。 她就那樣靜靜地躺著,像睡著了一般帜篇。 火紅的嫁衣襯著肌膚如雪糙捺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天笙隙,我揣著相機與錄音洪灯,去河邊找鬼。 笑死逃沿,一個胖子當著我的面吹牛婴渡,可吹牛的內容都是我干的。 我是一名探鬼主播凯亮,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼边臼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了假消?” 一聲冷哼從身側響起柠并,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎富拗,沒想到半個月后臼予,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡啃沪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年粘拾,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片创千。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡缰雇,死狀恐怖,靈堂內的尸體忽然破棺而出追驴,到底是詐尸還是另有隱情械哟,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布殿雪,位于F島的核電站暇咆,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜爸业,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一其骄、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沃呢,春花似錦年栓、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纸兔。三九已至惰瓜,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汉矿,已是汗流浹背崎坊。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留洲拇,地道東北人奈揍。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像赋续,于是被迫代替她去往敵國和親男翰。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內容

  • 1: apply纽乱、call 蛾绎、bind有什么作用,什么區(qū)別 call 和 apply 都是為了改變某個函數運行時的...
    高進哥哥閱讀 256評論 0 0
  • 一鸦列、this 相關問題 知乎上關于this的解答 this 的值到底是什么租冠?一次說清楚 this 的工作原理在js...
    66dong66閱讀 552評論 0 0
  • this 相關問題 apply、call 薯嗤、bind有什么作用顽爹,什么區(qū)別? apply語法格式:function....
    小囧兔閱讀 268評論 0 0
  • 1. this2.原型鏈-instanceof實現3.繼承的實現 ** this 相關問題 ** ** 1繁仁、 ap...
    饑人谷_阿靖閱讀 353評論 0 0
  • 一庸诱、this 相關問題 問題1: apply捻浦、call 晤揣、bind有什么作用,什么區(qū)別 作用:都是用來改變函數的t...
    冰灘波紋閱讀 228評論 0 0