複習javascript中call,apply,bind的用法

一直很難理解js中的call apply bind,在w3schools,mdn閱讀了,也看了不少相關的文章,今天我來寫下我理解的call apply bind

首先建立一個函數

function man(){}

man.prototype = {
    name: "Jack",
    love: "Rose",
    say: function(){
        console.log(this.name +" love " + this.love)
    }
}

var James = new man
James.say()     //Jack love Rose

如今有一個新的對象Mike,但Mike裏沒有say的方法,可是又要使用say方法應該怎麼辦呢,那就能夠用call和apply來調用James的say方法數組

var Mike = {
    name: "唐老鴨",
    love: "小朋友"
}

James.say.call(Mike)
James.say.apply(Mike)

此處能夠看出,call於apply的用法幾乎相同,只有一個區別,就是call()方法接受的是若干個參數的列表,而apply()方法接受的是一個包含多個參數的數組。app

下面的示例,展現了call所傳參數的形式

經過call來實現繼承

建立一個構造函數product函數

function product(name, price){
    this.name = name
    this.price = price
}

再建立一個構造函數food,引用productthis

function food(name, price){
    product.call(this, name, price)
    this.category = "food"
}

var rice = new food("東北大米", "50")
rice    //food {name: "東北大米", price: "50", category: "food"}

使用food構造函數建立的對象實例擁有在country構造函數添加的屬性name和price,但category屬性是在food構造函數中定義的。prototype

這裏也能夠看出,call接受的參數第一位是須要傳遞的this對象,在非嚴格模式下,若是不須要對this進行改變,可把第一個值設爲null,會自動指定到全局對象。後面的值是函數傳遞進來的參數code

使用call調用匿名函數

建立如下函數對象

var animals = [
    {species: "Lion", name: "King"},
    {species: "Whale", name: "Fail"}
]

for (var i = 0; i < animals.length; i++) {
  (function(i) {
    this.print = function() {
      console.log('#' + i + ' ' + this.species + ': ' + this.name)
    }
    this.print()
  }).call(animals[i], i)
}

此函數經過call調用了匿名函數繼承

apply

apply() 方法調用一個函數, 其具備一個指定的this值,以及做爲一個數組(或相似數組的對象)提供的參數。ip

例1,數組之間的追加ci

var arr1 = ["hello", "world"]
var arr2 = ["animals", "friends"]
Array.prototype.push.apply(arr1, arr2)

例2,獲取數組最大最小值

var num = [50, 10, 255, 800]
var maxNum = Math.max.apply(Math, num)
var minNum = Math.min.apply(Math, num)
var maxNum1 = Math.max.call(Math, 50, 10, 255, 800)
console.log(maxNum)  //800
console.log(minNum)  //10

num須要取出最大最小值,使用apply調用Math的方法便可
例3,類數組,僞數組使用數組方法

Array.prototype.slice.apply(document.querySelectorAll("div"))   //打印出全部div
Array.prototype.slice.apply(document.querySelectorAll("div"), [1, 3])
//打印下標1開始3以前結束的div

bind

bind( ) 函數會建立一個新函數(稱爲綁定函數),新函數與被調函數(綁定函數的目標函數)具備相同的函數體(在 ECMAScript 5 規範中內置的call屬性)。當新函數被調用時 this 值綁定到 bind( ) 的第一個參數,該參數不能被重寫。綁定函數被調用時,bind( ) 也接受預設的參數提供給原函數。一個綁定函數也能使用new操做符建立對象:這種行爲就像把原函數當成構造器。提供的 this 值被忽略,同時調用時的參數被提供給模擬函數。

例子:
建立一個函數,使用這個函數不論怎麼調用都只有一個this的值

this.x = 100
var dog = {
    x: 10,
    getX: function() {
        console.log(this.x)
    }
}

dog.getX()  //10

var hello = dog.getX
hello()  //100 這裏由於this指向全局做用域

這裏怎麼才能調用dog的getX方法呢?
bind能夠幫到你

var bindHello = hello.bind(dog)  
bindHello()  //10

從hello函數建立一個綁定函數,把this的值綁定到新的函數上,而後就能夠愉快的調用了

總結

call、apply和bind都是改變函數this對象的指向的,bind返回新的函數,而call和apply會當即執行函數

相關文章
相關標籤/搜索