高級任務(wù)二

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

  • bind

返回一個新函數(shù),并且使函數(shù)內(nèi)部的 this 為傳入的第一個參數(shù)

  • call

調(diào)用一個函數(shù),為其指定 this , 分別提供參數(shù)

  • apply

調(diào)用一個函數(shù),為其指定 this ,參數(shù)以數(shù)組形式傳入

        var value = 2;
        function sum(a, b) {
            console.log( this.value + a + b )
            //return this.value + a +b
        }

        //直接調(diào)用
        sum(5,6) // 2+5+6 =13

        //apply 指定this ,參數(shù)以數(shù)組的形式傳遞 

        var obj1 = {
            value: 3
        }
        sum.apply(obj1, [5, 6]) // 3+5+6

        //call 指定 this ,分別提供參數(shù)

        var obj2 = {
            value: 1
        }

        sum.call(obj2, 5, 6)  // 2+5+6

        //bind 指定 this ,返回一個新的函數(shù)

        var obj3 = {
            value: 7
        }

        var newSum = sum.bind(obj3)
        newSum(5,6) // 7+5+6

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

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

輸出結(jié)果 John:hi! 因為這里的sayHi 是 john 調(diào)用的,所以 this 指向
join 對象

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

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

在瀏覽器運行時, this 是指window ,因此,代碼運行后,會彈窗顯示 window 對象。

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

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

第一個 this 是指 document , 因為事件綁定自動把this指向?qū)?yīng)元素。第二個 thiswindow ,因為匿名函數(shù)的執(zhí)行是在window全局下的

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

var john = { 
  firstName: "John" 
}

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

彈窗顯示 Jonhn ,因為call 指定thisjohn對象。

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

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

this 指調(diào)用事件的 DOM 元素,要想讓 this 指向?qū)ο蟊旧恚梢员4嬖瓉淼?code>this

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

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

Person 是構(gòu)造函數(shù), prototype 是構(gòu)造函數(shù)的共有屬性。 pPerson的實例,該實例有__proto__對象指向Person.prototype。constructor表示該實例的構(gòu)造器,指向Person。

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

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

p.__proto__ === Person.prototype
Person.prototype.__proto__ === Object.protyotype

toString 是Object的prototype上的方法,所以p可以調(diào)用p.toString()

image.png

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

var str = 'ahbbccdeddddfg';
var ch = str.getMostOften();
console.log(ch); //d , 因為d 出現(xiàn)了5次
String.prototype.getMostOften = function(){
  var arr = {};
  // 找到字符串里所有字母他的個數(shù)保存至對象 arr。
  for(i=0; i<this.length; i++){
    if (arr[ this[i] ]){
      arr[ this[i] ]++;
    }else {
      arr[ this[i] ] = 1;
    }
  }

  var max = 0, maxStr;
  // 遍歷對象 arr 把出現(xiàn)次數(shù)最大值賦值給 max;
  for(var key in arr){
    if (arr[key] > max){
      max = arr[key];
      maxStr = key;
    }
  }
  return maxStr + ",因為 " + maxStr + " 出現(xiàn)了" + max + "次";
};

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

instanceOf用來判斷一個對象是是否是一個構(gòu)造函數(shù)的實例。內(nèi)部是通過判斷instance.__proto__ === Object.prototype是否相同來實現(xiàn)的,假如當前不相等,就會根據(jù)原型鏈往上找,instance.__proto__.__proto__ === Object.prototype,直到null,找到就返回true,否則為false。

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

  • 繼承是面向?qū)ο缶幊痰囊粋€特點之一,一個對象可以使用另一個對象的屬性和方法。它劃分了類的層次,父類代表的是更一般、更泛化的類,而子類則是更為具體、更為細化。

  • 繼承是實現(xiàn)代碼重用、擴展軟件功能的重要手段,子類中與父類完全相同的屬性和方法不必重寫,只需寫出新增或改寫的內(nèi)容,這就是說子類可以復(fù)用父類的內(nèi)容,不必一切從零開始。

問題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('若愚', 27);

方法一:將printName作為對象的自有方法定義,對象實例化后自身擁有這個方法,每次new出來實例,都會產(chǎn)生新的屬性和方法,占用過多不必要的內(nèi)存。

方法二: 將printName放在構(gòu)造方法的prototype屬性中,實例化對象可以通過原型鏈查找調(diào)用這個方法使用原型的好處可以讓所有對象實例共享它所包含的屬性和方法。每次new出來的實例,會產(chǎn)生新的屬性,但方法都在共有的屬性原型鏈(prototype)上,節(jié)省內(nèi)存。

問題13: Object.create 有什么作用?兼容性如何?
Object.create()方法會使用指定的原型對象及其屬性去創(chuàng)建一個新的對象,實現(xiàn)繼承。

Student.prototype = Object.create(Person.prototype);

Object.create().jpg

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

hasOwnProperty()方法返回一個布爾值,指示對象自身屬性中是否具有指定的屬性(是自身屬性,不包含prototype)。

function Person(){
  this.name = 'jack'
}

Person.prototype.commonName = 'Person'
var a = new Person()
console.log(a.hasOwnProperty('name'))

問題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中的this作用域指向Male,實現(xiàn)構(gòu)造函數(shù)繼承

問題16: 補全代碼,實現(xiàn)繼承

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

        Person.prototype.printName = function() {
            console.log('My name is '+ 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(){
            return this.age
        }

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

?著作權(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)容