首页 > 移动平台 > 详细

谈谈call、apply、bind

时间:2017-04-04 22:06:24      阅读:214      评论:0      收藏:0      [点我收藏+]

一、前言

是不是经常遇到这样的用法?

Array.prototype.slice.call ( arguments);

或者是:
[].prototype.slice.apply(argument);

或者是:

function   isArray(obj){ 
    return Object.prototype.toString.call(obj) === ‘[object Array]‘ ;

}

或者是:

function(){XXXXXXx}.bind (this);

jQuey中不也有bind方法么?

$(‘.XXX‘).bind(‘click‘,function(){});

这样看当然不能看出这三者有啥区别,也不太能看出都有啥作用?那么我们就挑出来看看呗。

 

二、先看看相似之处。

2.1、都是Function.prototype的方法。

2.2、都是用来改变函数的运行时的上下文对象(执行上下文),或者说是改变函数内部的this指向,或者可以说,利用这几个方法去借用别人的方法。

2.3、三个方法中的第一个参数都是this要指向的对象,我们来验证一下:

先来看看call(),MDN上的解释是"call()方法在使用一个指定的this值和若干个指定的参数值的前提下调用某个函数或方法."

function print(){
  console.log(this)
 }
 print(123);         //window
 print.call(123);    //Number
 print(123);         //window
 print.call(123);    //String
 print(new Object());  //window
 print.call(new Object());//Object
 print(null);          //window
 print.call(null);     //window
 print(undefined);     //window
 print.call(undefined);//window

说明:
非严格条件下,call和apply的第一个参数为null、undefined、空 ,函数内的this指向windown(浏览器 ) 或global。
严格模式下,null是null,undefined和空 为undefined

apply的结果同上。bind方法返回值是当前函数对象,且当前函数的this已经被改变了,这点也算是bind和call,apply的区别了。

举个简单的例子:

var animal = {
    words:‘......‘,
    speak:function(say){
        console.log(say + ‘ ‘ + this.words);
    }
}

var dog ={
  words: ‘wang‘  
}
//小狗没有say这个方法,但是可以通过call来调用aniaml的say方法。

animal.speak.call(dog, ‘speak‘); //dog就是call()这个方法的上下文,this指向了dog这个对象。

  , 

三、区别

3.1、call() vs apply();

call()方法接收的是一个参数列表,apply()接收的是一个包含多个参数的数组。

例如:

print.call(123,2,3,4);   
print.apply(123,[2,3,4]);     

当参数明确的时候,建议使用call,但传入的参数不明确的时候,或者是数组的时候,建议使用apply。

3.2、bind vs call、apply

bind返回的是对应的函数,不会立即调用,而call、apply都是立即调用的。

下面的只是一个简单的例子,用来说明bind的用处,特别注意的是,定时器中的this如果不在执行函数中bind(this),则里面的this就会指向window,而不是当前创建的对象中。可以这么理解,setTimeout是window的,那么在执行函数的this也会指向Windows,除非bind(this)前置把里面函数的执行上下文改成当前对象。

var slider={
	LWIDTH:0,
	DURATION: 1000,
	WAIT:3000, //自动轮播之间的等待时间
	timer:null,    //保存一次性定时器序号
	canAuto:true,
	LHeight:60,
	init:function(){
		this.updateView();
		$(".slider").hover(
			function(){this.canAuto=false;}.bind(this),
			function(){this.canAuto=true;}.bind(this)
		)
		this.autoMove();//判断之后,调用自动执行函数
	},
	autoMove:function(){
		this.timer=setTimeout(
			function(){
				if(this.canAuto){
					this.move(1);
				}else{
					this.autoMove();
				}
			}.bind(this),
		);
	}
}

  

四、应用场景

4.1利用apply传参数机制,在某些本来需要写成遍历数组变量的任务中使用内建的函数

Math.max/Math.min来找出一个数组中的最大/最小值。

var numbers = [2, 8, 4, 3, 1];
var max = Math.max.apply(null, numbers); //等价于:Math,max(2, 8, 4, 3, 1);
var min = Math.min.apply(null, numbers);  //同上

4.2方便实现继承

function Animal(words){
    this.words = words;
    this.speak = function(){
       console.log(this.words);
    }
}    

function Dog(words){
    Anaimal.call(this, words);//或者Anmal.apply(this,, arguments)
     
}

var dog  = new Dog(‘wang‘);//这样实例的dog对象就有了Animal的speak方法了。

dog.speak();

  

4.3文章开头写的几种用法也是我们可能经常使用的。

 

 

  

 

谈谈call、apply、bind

原文:http://www.cnblogs.com/leaf930814/p/6661854.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!