三者的作用都是改变函数执行时的上下文,也就是改变this指向
fun.apply(thisArg, [argsArray])
function.call(thisArg, arg1, arg2, …)
fun.bind(thisArg[, arg1[, arg2[, …]]])
call与apply的区别在于,传递参数的方式
bind与他们的区别是,bind是返回这个函数的copy,而call与apply是直接执行
一些应用:
求最大最小值
利用apply,call来做继承
调用匿名函数
一、call && apply
//一、最大最小
Math.min.apply(Math,[(3,5,6)]) == 6 //为什么
Math.min.apply(Math,{ 'length': 2, '0': '1', '1': '2' }) ==1
//二、将伪数组转化为数组
var arrayLike = { 'length': 2, '0': '1', '1': '2' };
//(必须以数字为属性,必须有length属性,length多了,就会多加undefined,length少了主动删减多余的)
var arr = Array.prototype.slice.call(arrayLike);
//arr为 ["1", "2"]
var arrayLike = { 'length': 3, '0': '1', '1': '2' };//arr为 ["1", "2",undefined]
var arrayLike = { 'length': 1, '0': '1', '1': '2' };//arr为 ["1"]
//三、数组追加
var arr1 = [1,2];
var arr2 = [3,4];
[].push(arr1,arr2);
//arr1 [1,2,3,4] ; arr2[3,4]
//四、判断变量类型
function isArray(obj){
return Object.prototype.toString.call(obj)
== '[object Array'];
}
isArray([]) //true
//五、调用匿名函数
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);
}
二、bind
//1、创建绑定函数
this.x = 9; // this refers to global "window" object here in the browser
var module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81
var retrieveX = module.getX;
retrieveX();
// returns 9
var boundGetX = retrieveX.bind(module);
boundGetX(); // 81
//2、预传递参数
function list() {
return Array.prototype.slice.call(arguments);
}
var list1 = list(1, 2, 3); // [1, 2, 3]
var leadingThirtysevenList = list.bind(null, 37);
var list2 = leadingThirtysevenList();
// [37]
var list3 = leadingThirtysevenList(1, 2, 3);
// [37, 1, 2, 3]
//3.有setTimeout时,this会自动指向window,用bind改变
function LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
};
LateBloomer.prototype.declare = function() {
console.log('I am a beautiful flower with ' +
this.petalCount + ' petals!');
};
var flower = new LateBloomer();
flower.bloom();
// after 1 second, triggers the 'declare' methodfunction LateBloomer() {
this.petalCount = Math.ceil(Math.random() * 12) + 1;
}
// Declare bloom after a delay of 1 second
LateBloomer.prototype.bloom = function() {
window.setTimeout(this.declare.bind(this), 1000);
};
//this均指向LateBloomer这个自定义对象,
//LateBloomer {petalCount: a number of [1,13]}
LateBloomer.prototype.declare = function() {
console.log('I am a beautiful flower with ' +
this.petalCount + ' petals!');
};
var flower = new LateBloomer();
flower.bloom();
// after 1 second, triggers the 'declare' method