在javascript中,三者做用是改變某個函數的執行上下文(Execution Context),具體做用是改變函數體內部this的指向。javascript
舉個栗子:java
function example() {} example.prototype = { name: 'will', say: function() { console.log('hi,' + this.name + '!') } } var e = new example() e.say() // hi,will! var obj = { name: 'lucky' } e.say.apply(obj) // hi,lucky! 此時this.name是lucky e.say.call(obj) // hi,lucky! 此時this.name是lucky e.say.bind(obj)() // hi,lucky! 此時this.name是lucky
apply、call只是接受參數的方式不太同樣,並且會當即執行,bind會產生一個新函數,須要再次調用纔會執行數組
舉個栗子:app
function func(arg1, arg2) { console.log(arg1 + arg2) } func.apply(this, [1, 2]) // apply接受的參數,第一個是對象,第二個是數組 func.call(this, 1, 2) // call接受的參數,第一個是對象,後面一個接一個
var obj = { 0: 1, 1: 2, length: 2 } var arr1 = Array.prototype.slice.call(obj) // [1, 2] var arr2 = Array.prototype.slice.apply(obj) // [1, 2]
var arr = [1, 2, 3, 4] //取最大值 console.log(Math.max.apply(Math, arr)) // 4 console.log(Math.max.call(Math, ...arr)) // 4 //取最小值 console.log(Math.min.apply(Math, arr)) // 1 console.log(Math.min.call(Math, ...arr)) // 1
function isArray(obj) { return Object.prototype.toString.call(obj) === '[object Array]' } isArray([1]) // true isArray({}) // false
class MyCircle extends Component { constructor(props) { super(props) this.func = this.func.bind(this) } func() { ... } ... }
三者做用都是改變函數this的指向
三者第一個傳參都是要this要指向的對象
apply、call是當即執行函數,bind須要再次調用函數