文章转自个人博客 https://knightyun.github.io/2019/05/01/js-call,转载请申明。


概述

JavaScript函数中的三个方法.call(), .apply(), .bind(),总体来说主要功能就是改变函数中 this 关键字的指向,因为 this 默认指向 当前环境的对象

例如:

var obj = {name: 'Knight',getName: function() {// this 指向 obj 对象console.log(this.name);}
}
obj.getName(); // 'Knight'

call()

.call() 可以用于改变 this 值的指向,例如:

this.name = 'Knight'; // 此处 this 指向全局对象 window;
var obj = {name: 'Cloud'
}
function fn() {console.log(this.name);
}fn();         // 'Knight'
fn.call(obj); // 'Cloud'
// 此处指向了 obj 对象,所以 name 变了

也可以传递函数参数,平常调用函数的形式可能是这样:

function fn(a, b) {console.log(a + b);
}fn(2 + 3); // 5

现在也可以这样调用:

function fn(a, b) {console.log(a + n);
}fn.call(null, 2, 3); // 5
// 因为函数里没有用到 this,
// 所以可以设置为 null

apply()

.apply().call() 类似,第一个参数也是用于改变 this 指向,区别就是 apply() 接受的函数参数是一个数组,例如:

function fn(a, b) {console.log('Mu name is ' +this.name + (a + b) +' years old.');
}
var obj = {name: 'Knight'
}
var arr = [2, 3];fn.apply(obj, arr);
// My name is Knight, 5 years old.// 使用 call() 的情况:
fn.call(obj, 2, 3);
// My name is Knight, 5 years old.

bind()

.bind() 也与 .call() 类似,改变 this 指向,传递函数参数,区别在于 .bind() 方法结果是创建一个新的 绑定函数,而之前的 .call().apply() 结果都是 立即执行函数,举例来理解:

var obj = {name: 'Knight'
}
function fn(a, b) {console.log('My name is ' +this.name + (a + b) +' years old.');
}var fnn = fn.bind(obj, 2, 3);
// fn.bind() 是一个函数,不会立即执行
fnn();
// My name is Knight, 5 years old.fn.bind(obj, 2, 3)();
// 这种写法就是立即执行函数了,
// 结果与上面一样;

this 的困境

考虑以下情况:

function fn1() {function fn2() {console.log('fn2: ' +this);}fn2();console.log('fn1: ' + this);
}fn1.call('here'); // 'fn1: here'

结果不会输出 fn2: here,因为函数定义 fn2 里的 this 是一个新的指向,并且未定义,与外部函数 fn1 中的 this 不同;

所以我们通常会进行一下处理:

function fn1() {function fn2() {console.log('fn2: ' +this);}// 对 this 进行转存var that = this;fn2.call(that);console.log('fn1: ' +this);
}fn1.call('here');
/*
fn2: here
fn1: here
*/

当然,ES6中的箭头函数解决了上述问题:

function fn1() {var fn2 = () => {console.log('fn2: ' + this);}fn2();fn2.call('there');console.log('fn1: ' + this);
}fn1.call('here');
/*
fn2: here
fn2: here
fn1: here
*/

由于 .call() 方法对箭头函数不起作用,所以上面的第二行输出与第一行相同;


技术文章推送 手机、电脑实用软件分享

JavaScript之call,bind,apply方法及 this 的用法辨析相关推荐

  1. 炒鸡简单的javaScript的call和apply方法

    解释一 作者:杨志 链接:https://www.zhihu.com/question/20289071/answer/14644278 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商 ...

  2. JavaScript中call和apply方法

    1 /* 2 在js中 call和apply常用于绑定作用域 3 */ 4 //1 简单的绑定 5 function sum(a,b){ 6 return a+b; 7 } 8 //将sum的功能绑定 ...

  3. JavaScript replace之字符串的方法与indexOf的用法 详解

    目录 replace方法 1. 作用1:替换字符串 2. 替换多个字符 3. 穿插indexOf的用法 3.1. 一个参数的作用 3.2.两个参数时的作用 3.3. 替换所有字符 3.4. 打印字符出 ...

  4. JavaScript的call,apply和bind方法之间的区别

    by Rajat Saxena 通过拉贾特·萨克森纳(Rajat Saxena) JavaScript的call,apply和bind方法之间的区别 (The difference between J ...

  5. JavaScript 之 call和apply,bind 的模拟实现

    call 一句话介绍 call: call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法. 举个例子: var foo = {value: 1 };functi ...

  6. JavaScript中的call,apply,bind学习总结

    JavaScript 中的 call, apply, bind 这三个函数的作用和区别在各大论坛都被讨论了很多次了,但是我一直都还没来得及好好总结,这次正好看到了一个很不错的关于JavaScript ...

  7. js apply/call/caller/callee/bind使用方法与区别分析

    一.call 方法 调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容). Js代码 call([thisObj[,arg1[, arg2[, ...

  8. 不用call和apply方法模拟实现ES5的bind方法

    本文首发我的个人博客:前端小密圈,评论交流送1024邀请码,嘿嘿嘿?. 来自朋友去某信用卡管家的做的一道面试题,用原生JavaScript模拟ES5的bind方法,不准用call和bind方法. 至于 ...

  9. 可能遇到假的面试题:不用call和apply方法模拟实现ES5的bind方法

    本文首发我的个人博客:前端小密圈,评论交流送1024邀请码,嘿嘿嘿?. 来自朋友去某信用卡管家的做的一道面试题,用原生JavaScript模拟ES5的bind方法,不准用call和bind方法. 至于 ...

最新文章

  1. 智能&大数据时代,架构师思维的十个学习步骤(优化版)
  2. java8学习:用流收集数据
  3. Entity Framework 在MySQL中执行SQL语句,关于参数问题
  4. 运行时修改数据库连接字符串(ConnectionString)
  5. 智能指针引用计数器版
  6. 服务幂等以及常用实现方式
  7. java线程 打印_Java多线程实战之交叉打印的两种方法
  8. 初学者学习Python,掌握这些实用小技巧能快速入门!
  9. 阿里P8架构师谈:分布式架构设计12精讲
  10. html加入购物车的动画,vue实现加入购物车动画
  11. 追踪监听(TraceListener)
  12. 苹果试图将AirPods打造成健康产品 可监测体温和姿势
  13. java题角色信息管理,java题库专家信息管理系统
  14. 免费下载知网论文的重要链接
  15. 互联网30年,泡沫如梦,一个个泡沫和风口过后,会是什么样的结局
  16. 霹雳吧啦Wz语义分割学习笔记P10
  17. 可以测试电脑网络速度的软件,介绍4种有用的Internet Speed软件应用程序,用于测试网络速度软件...
  18. 《东周列国志》第十二回 卫宣公筑台纳媳 高渠弥乘间易君
  19. 顺丰速运——深圳大数据部一面(18分钟)
  20. c语言辗转相除法不同规模的情况,C语言讲义终极勘误版.doc

热门文章

  1. 如何优化网站服务器来提高吞吐量并减少延迟时间
  2. ES6 变量的6种方式
  3. Eclipse的使用总结
  4. maven隐式依赖引起的包冲突
  5. 敏捷开发日常跟进系列之四:跟进表
  6. 题目2 : 回文字符序列(区间DP)
  7. android时间戳字体,Android获取当前时间戳?
  8. javabean反射改字段内容_JSP第三篇「JavaBean的介绍、JSP的行为--JavaBean」(修订版)...
  9. 怎样呵护友谊_家长怎样与孩子有效的交流沟通
  10. React 折腾记 - (4) 侧边栏联动Tabs菜单-增强版(结合Mobx)