原型、原型鏈、原型繼承

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

作用: 給函數(shù)指定this。是用來(lái)指定上下文的
區(qū)別: bind:bind()會(huì)創(chuàng)建一個(gè)新的函數(shù),將其中的值,作為原來(lái)函數(shù)的this。例如xx.bind(obj)中,obj為xx的this 。將函數(shù)體中的this綁定到對(duì)象上,然后返回一個(gè)新的函數(shù)。
call: call()是使用一個(gè)指定的this值和相關(guān)參數(shù)的前提下調(diào)用函數(shù)或方法。接受的參數(shù)為若干個(gè)參數(shù)的列表。簡(jiǎn)單來(lái)說(shuō),就是可以指定函數(shù)內(nèi)部this的指向(即在此函數(shù)執(zhí)行時(shí)所在的作用域),讓在所指定的作用域中,調(diào)用該函數(shù)。就是var obj={};function fn(){ return this;};fn.call(obj),call改變this的指向。讓fn的this是指向obj的,在obj的作用域中運(yùn)行
apply: apply()效果同call(),不過(guò)其接受的參數(shù)為數(shù)組。

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

 var john = { 
        firstName: "John" 
          }
    function func() { 
        alert(this.firstName + ": hi!")
    }
    john.sayHi = func
    john.sayHi()  ==》方法調(diào)用
    輸出:  
              john hi!

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

func() 
function func() { 
  alert(this)
}        ==》函數(shù)調(diào)用
輸出: window,因?yàn)樵趂unction中的this,沒(méi)有找到對(duì)象,所以繼續(xù)向外找,
            而function的外部環(huán)境為window,則輸出window

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

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

輸出:document 
           window

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

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

輸出:john

原因:call()函數(shù)為func函數(shù)綁定了this=john

call()函數(shù)將func函數(shù)的this指向了john,并且func的執(zhí)行在john的作用域中

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

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

問(wèn)題:console.log出來(lái)的是$btn 饑人谷 ;//不知道。
當(dāng)調(diào)用module.bind()的時(shí)候。this.showMsg()無(wú)法調(diào)用。因?yàn)檫@里的this指向了$btn。所以將this.showMsg()改為module.showMsg();
或是通過(guò)嫁接方式;var that=this;that.showMsg();
原型鏈相關(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是Person的構(gòu)造對(duì)象,而Person是構(gòu)造函數(shù)。 在new的過(guò)程中,p的-proto-指向 Person,因?yàn)镻erson的原型上綁定一個(gè)方法:sayName,即constructor下有sayName。所以p 擁有屬性:name;和方法sayName()。

問(wèn)題8: 上例中,對(duì)對(duì)象 p可以這樣調(diào)用 p.toString()。toString是哪里來(lái)的? 畫(huà)出原型圖?并解釋什么是原型鏈。
來(lái)自上一級(jí)的原型。
https://www.draw.io/#Hkomolei%2Ftry%2Fmaster%2FUntitled%20Diagram.xml
原型鏈:所有的對(duì)象都有-proto-這個(gè)屬性,這個(gè)鏈接到另一個(gè)-proto-,像這樣一個(gè)個(gè)-proto-相鏈接起來(lái)的樣子,稱為原型鏈。對(duì)于函數(shù),則是prototype了。
問(wèn)題9:對(duì)String做擴(kuò)展,實(shí)現(xiàn)如下方式獲取字符串中頻率最高的字符

 var str = 'ahbbccdeddddfg';
 String.prototype.getMostOften =
  function () {
   // var str = 'ahbbccdeddddfg';
   var str=this;
    // console.log(this);
   var o = {};
   for (var i = 0; i < str.length; i++) {
   var char = str.charAt(i);
   if (o[char]) {
      o[char]++; //次數(shù)加1
    } else {
      o[char] = 1; //若第一次出現(xiàn),次數(shù)記為1
    }
  }
  // console.log(o); //輸出的是完整的對(duì)象,記錄著每一個(gè)字符及其出現(xiàn)的次數(shù)
  //遍歷對(duì)象,找到出現(xiàn)次數(shù)最多的字符的次數(shù)
  var max = 0;
  for (var key in o) {
    if (max < o[key]) {
      max = o[key]; //max始終儲(chǔ)存次數(shù)最大的那個(gè)
    }
  }
  for (var key in o) {
    if (o[key] == max) {
      //console.log(key);
      // console.log("最多的字符是" + key);
      // console.log("出現(xiàn)的次數(shù)是" + max);
      return key;
    }
  }
}
var ch = str.getMostOften();
 console.log(ch);

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

作用: instanceof 運(yùn)算符用來(lái)測(cè)試一個(gè)對(duì)象在其原型鏈中是否存在一個(gè)構(gòu)造函數(shù)的 prototype 屬性。
就是檢測(cè)一個(gè)原型鏈上是否存在某個(gè)prototype。a.instanceof b.prototype :就是a的原型鏈中是否存在b.prototype;
實(shí)現(xiàn)邏輯:讓其一層一層沿著原型鏈去查找,找到就return true;
繼承相關(guān)問(wèn)題

問(wèn)題11:繼承有什么作用?
繼承:一個(gè)對(duì)象繼承另一個(gè)對(duì)象的所有的屬性和方法??梢缘玫搅硪粋€(gè)對(duì)象的屬性和方法。

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

區(qū)別:方法1是 綁定在People上。方法2的printName是綁定到原型上。在new多個(gè)實(shí)例的時(shí)候,方法2可以直接調(diào)用。在多次調(diào)用的時(shí)候可以優(yōu)化內(nèi)存空間。而方法1要多次寫(xiě)入。
同時(shí)方法2中要更改prototype的時(shí)候,其的每一個(gè)實(shí)例的printName都會(huì)改變。而方法1需要每個(gè)都是修改。

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

Object.create() 方法使用指定的原型對(duì)象和其屬性創(chuàng)建了一個(gè)新的對(duì)象。簡(jiǎn)單來(lái)說(shuō)就是可以手動(dòng)的去指定對(duì)象的原型。創(chuàng)建一個(gè)新的對(duì)象,第一層的原型鏈指向?qū)?yīng)的參數(shù)。
兼容性:支持各個(gè)瀏覽器。ie需要ie9以上。

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

作用:看對(duì)象上的屬性是屬于自己的,還是從原型鏈繼承來(lái)的。
使用:object.hasOwnPrototype(" 屬性")

問(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;
}

作用:讓Male繼承Person中的屬性。手動(dòng)將this指向Person。就是將Person中的this引用到Male中。

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

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

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

function Male(name, sex, age){
   //todo ...
    Person.call(this,name,sex)
    this.age=age;
    //this.printName=function(){
      //    console.log(this.name)
      //}
      this.printName=Person.prototype.getName;
  }

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

var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();

或是:

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,sex)
    this.age=age;
    //this.printName=function(){
      //    console.log(this.name)
      //}
      //this.printName=Person.prototype.getName;
  }
  //todo ...  
Male.prototype=new Person() ; //繼承:將一個(gè)對(duì)象的prototype指向要繼承的對(duì)象即可
Male.prototype.getAge = function(){
//       todo ...
  console.log(this.age)
};
var ruoyu = new Male('若愚', '男', 27);
ruoyu.printName();
最后編輯于
?著作權(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)容

  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點(diǎn)點(diǎn)福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運(yùn)大...
    HetfieldJoe閱讀 3,084評(píng)論 4 14
  • 在JavaScript中,原型鏈作為一個(gè)基礎(chǔ),老生長(zhǎng)談,今天我們就來(lái)深入的解讀一下原型鏈。 本章主要講的是下面幾點(diǎn)...
    Devinnn閱讀 1,503評(píng)論 1 6
  • 博客內(nèi)容:什么是面向?qū)ο鬄槭裁匆嫦驅(qū)ο竺嫦驅(qū)ο缶幊痰奶匦院驮瓌t理解對(duì)象屬性創(chuàng)建對(duì)象繼承 什么是面向?qū)ο?面向?qū)ο?..
    _Dot912閱讀 1,537評(píng)論 3 12
  • 1. apply、call 、bind有什么作用,什么區(qū)別? call ,apply的作用:調(diào)用一個(gè)函數(shù),傳入函數(shù)...
    Rising_suns閱讀 439評(píng)論 0 0
  • 20歲,大學(xué)二年級(jí),一個(gè)美好的時(shí)光,有貼心的朋友,沒(méi)有男朋友,也并不打算去擁有,一個(gè)人的自己,我習(xí)慣的很好,很合拍...
    cocohuang閱讀 246評(píng)論 0 3

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