JavaScript中call、apply、bind方法 改变函数中的this指向

2018-05-2112:54:13WEB前端开发JavaScript中call、apply、bind方法 改变函数中的this指向已关闭评论2,532 views字数 1997阅读模式

JavaScript中,call、apply和bind是Function对象自带的三个方法,这三个方法的主要作用是改变函数中的this指向。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

call、apply、bind方法的共同点和区别:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

1. 都是用来改变函数的this对象的指向的;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

2. 第一个参数都是this要指向的对象,也就是想指定的上下文;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

3. 都可以利用后续参数传参;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

call、apply、bind方法的不同点:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

一、call文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

call()文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

语法:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

call([thisObj[,arg1[, arg2[, [,.argN]]]]])文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

定义:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

调用一个对象的一个方法,以另一个对象替换当前对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

说明:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

call 方法可以用来代替另一个对象调用一个方法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

thisObj的取值有以下4种情况:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

(1) 不传,或者传null,undefined, 函数中的this指向window对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

(2) 传递另一个函数的函数名,函数中的this指向这个函数的引用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

(3) 传递字符串、数值或布尔类型等基础类型,函数中的this指向其对应的包装对象,如 String、Number、Boolean。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

(4) 传递一个对象,函数中的this指向这个对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

常用场景:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

原型的继承:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

Function Student(){文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

Person.call(this,arguments);文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

}文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

用Student对象代替Person对象,这时Student可以继承Person上面所有的方法和属性;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

二、apply()文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

语法:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

apply([thisObj[,argArray]])文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

定义:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

应用某一对象的一个方法,用另一个对象替换当前对象。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

说明:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将报错。 如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

call 和 apply的区别: 作用完全一样,只是call按顺序接收参数,apply把参数放在数组里面;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

Call和apply的使用场景区分:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

参数是明确知道数量时用 call ;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

而不确定的时候用 apply,然后把参数 push 进数组传递进去;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

三、bind文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

bind是在ES6中扩展的方法(IE6,7,8不支持)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

bind() 方法与 apply 和 call 很相似,也是可以改变函数体内 this 的指向。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

bind()方法会创建一个新函数,称为绑定函数,当调用这个绑定函数时,绑定函数会以创建它时传入 bind()方法的第一个参数作为 this,传入 bind() 方法,第二个以及以后的参数+绑定函数运行时本身的参数按照顺序作为原函数的参数来调用原函数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

注意:bind方法的返回值是函数文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

理解运用apply、call:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

1、当传入参数的个数是不确定的时候,打印出函数传入的所有参数?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

function log(){
console.log.apply(console,arguments);
}

log(1); 1
Log(1,2) 1,2

2、给每一个 log 消息添加一个"(app)"的前辍?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

Function log(){
var args=Array.prototype.slice.call(arguments);
Args.unshift(“app”);
Console.log.apply(console,args);
}

总结:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

1. apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

2. 三者第一个参数都是this要指向的对象,也就是想指定的上下文;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

3. 三者都可以利用后续参数传参;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

4. bind 是返回对应函数,便于稍后调用;apply 、call 则是立即调用 。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

附:IE6-8自定义bind方法(IE6-8不兼容bind)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

原理:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

通过对Function的prototype原型进行扩展,可以为IE6~8自定义bind方法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

代码如下:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

if (!function() {}.bind) {
   Function.prototype.bind = function(context) {
       var self = this
           , args = Array.prototype.slice.call(arguments);

       return function() {
           return self.apply(context, args.slice(1));    
       }
   };
}

1、用call为函数的参数绑定splice方法;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

2、给Function函数的this改变成bind传入的this对象;文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

3、把参数从第二个计算(第一个是传入的this对象);文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

作者:红蔷薇
链接:https://juejin.im/post/5ad55c036fb9a028c06b4ff0
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html

文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/3539.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/gcs/3539.html