一直很難理解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
建立一個構造函數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
建立如下函數對象
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( ) 函數會建立一個新函數(稱爲綁定函數),新函數與被調函數(綁定函數的目標函數)具備相同的函數體(在 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會當即執行函數