JavaScript之call,bind,apply方法及 this 的用法辨析
文章转自个人博客 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 的用法辨析相关推荐
- 炒鸡简单的javaScript的call和apply方法
解释一 作者:杨志 链接:https://www.zhihu.com/question/20289071/answer/14644278 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商 ...
- JavaScript中call和apply方法
1 /* 2 在js中 call和apply常用于绑定作用域 3 */ 4 //1 简单的绑定 5 function sum(a,b){ 6 return a+b; 7 } 8 //将sum的功能绑定 ...
- JavaScript replace之字符串的方法与indexOf的用法 详解
目录 replace方法 1. 作用1:替换字符串 2. 替换多个字符 3. 穿插indexOf的用法 3.1. 一个参数的作用 3.2.两个参数时的作用 3.3. 替换所有字符 3.4. 打印字符出 ...
- JavaScript的call,apply和bind方法之间的区别
by Rajat Saxena 通过拉贾特·萨克森纳(Rajat Saxena) JavaScript的call,apply和bind方法之间的区别 (The difference between J ...
- JavaScript 之 call和apply,bind 的模拟实现
call 一句话介绍 call: call() 方法在使用一个指定的 this 值和若干个指定的参数值的前提下调用某个函数或方法. 举个例子: var foo = {value: 1 };functi ...
- JavaScript中的call,apply,bind学习总结
JavaScript 中的 call, apply, bind 这三个函数的作用和区别在各大论坛都被讨论了很多次了,但是我一直都还没来得及好好总结,这次正好看到了一个很不错的关于JavaScript ...
- js apply/call/caller/callee/bind使用方法与区别分析
一.call 方法 调用一个对象的一个方法,以另一个对象替换当前对象(其实就是更改对象的内部指针,即改变对象的this指向的内容). Js代码 call([thisObj[,arg1[, arg2[, ...
- 不用call和apply方法模拟实现ES5的bind方法
本文首发我的个人博客:前端小密圈,评论交流送1024邀请码,嘿嘿嘿?. 来自朋友去某信用卡管家的做的一道面试题,用原生JavaScript模拟ES5的bind方法,不准用call和bind方法. 至于 ...
- 可能遇到假的面试题:不用call和apply方法模拟实现ES5的bind方法
本文首发我的个人博客:前端小密圈,评论交流送1024邀请码,嘿嘿嘿?. 来自朋友去某信用卡管家的做的一道面试题,用原生JavaScript模拟ES5的bind方法,不准用call和bind方法. 至于 ...
最新文章
- 智能&大数据时代,架构师思维的十个学习步骤(优化版)
- java8学习:用流收集数据
- Entity Framework 在MySQL中执行SQL语句,关于参数问题
- 运行时修改数据库连接字符串(ConnectionString)
- 智能指针引用计数器版
- 服务幂等以及常用实现方式
- java线程 打印_Java多线程实战之交叉打印的两种方法
- 初学者学习Python,掌握这些实用小技巧能快速入门!
- 阿里P8架构师谈:分布式架构设计12精讲
- html加入购物车的动画,vue实现加入购物车动画
- 追踪监听(TraceListener)
- 苹果试图将AirPods打造成健康产品 可监测体温和姿势
- java题角色信息管理,java题库专家信息管理系统
- 免费下载知网论文的重要链接
- 互联网30年,泡沫如梦,一个个泡沫和风口过后,会是什么样的结局
- 霹雳吧啦Wz语义分割学习笔记P10
- 可以测试电脑网络速度的软件,介绍4种有用的Internet Speed软件应用程序,用于测试网络速度软件...
- 《东周列国志》第十二回 卫宣公筑台纳媳 高渠弥乘间易君
- 顺丰速运——深圳大数据部一面(18分钟)
- c语言辗转相除法不同规模的情况,C语言讲义终极勘误版.doc
热门文章
- 如何优化网站服务器来提高吞吐量并减少延迟时间
- ES6 变量的6种方式
- Eclipse的使用总结
- maven隐式依赖引起的包冲突
- 敏捷开发日常跟进系列之四:跟进表
- 题目2 : 回文字符序列(区间DP)
- android时间戳字体,Android获取当前时间戳?
- javabean反射改字段内容_JSP第三篇「JavaBean的介绍、JSP的行为--JavaBean」(修订版)...
- 怎样呵护友谊_家长怎样与孩子有效的交流沟通
- React 折腾记 - (4) 侧边栏联动Tabs菜单-增强版(结合Mobx)