JavaScript 中 apply 、call 的详解
apply 和 call 的区别
ECMAScript 规范给所有函数都定义了 call 与 apply 两个方法,它们的应用非常广泛,它们的作用也是一模一样,只是传参的形式有区别而已。
原文作者:林鑫,作者博客:https://github.com/lin-xin/blog
apply( )
apply 方法传入两个参数:一个是作为函数上下文的对象,另外一个是作为函数参数所组成的数组。
var obj = {name : 'linxin'
}function func(firstName, lastName){console.log(firstName + ' ' + this.name + ' ' + lastName);
}func.apply(obj, ['A', 'B']); // A linxin B
可以看到,obj 是作为函数上下文的对象,函数 func 中 this 指向了 obj 这个对象。参数 A 和 B 是放在数组中传入 func 函数,分别对应 func 参数的列表元素。
call( )
call 方法第一个参数也是作为函数上下文的对象,但是后面传入的是一个参数列表,而不是单个数组。
var obj = {name: 'linxin'
}function func(firstName, lastName) {console.log(firstName + ' ' + this.name + ' ' + lastName);
}func.call(obj, 'C', 'D'); // C linxin D
对比 apply 我们可以看到区别,C 和 D 是作为单独的参数传给 func 函数,而不是放到数组中。
对于什么时候该用什么方法,其实不用纠结。如果你的参数本来就存在一个数组中,那自然就用 apply,如果参数比较散乱相互之间没什么关联,就用 call。
apply 和 call 的用法
1.改变 this 指向
var obj = {name: 'linxin'
}function func() {console.log(this.name);
}func.call(obj); // linxin
我们知道,call 方法的第一个参数是作为函数上下文的对象,这里把 obj 作为参数传给了 func,此时函数里的 this 便指向了 obj 对象。此处 func 函数里其实相当于
function func() {console.log(obj.name);
}
2.借用别的对象的方法
先看例子
var Person1 = function () {this.name = 'linxin';
}
var Person2 = function () {this.getname = function () {console.log(this.name);}Person1.call(this);
}
var person = new Person2();
person.getname(); // linxin
从上面我们看到,Person2 实例化出来的对象 person 通过 getname 方法拿到了 Person1 中的 name。因为在 Person2 中,Person1.call(this) 的作用就是使用 Person1 对象代替 this 对象,那么 Person2 就有了 Person1 中的所有属性和方法了,相当于 Person2 继承了 Person1 的属性和方法。
3.调用函数
apply、call 方法都会使函数立即执行,因此它们也可以用来调用函数。
function func() {console.log('linxin');
}
func.call(); // linxin
call 和 bind 的区别
在 EcmaScript5 中扩展了叫 bind 的方法,在低版本的 IE 中不兼容。它和 call 很相似,接受的参数有两部分,第一个参数是是作为函数上下文的对象,第二部分参数是个列表,可以接受多个参数。
它们之间的区别有以下两点。
1.bind 发返回值是函数
var obj = {name: 'linxin'
}function func() {console.log(this.name);
}var func1 = func.bind(obj);
func1(); // linxin
bind 方法不会立即执行,而是返回一个改变了上下文 this 后的函数。而原函数 func 中的 this 并没有被改变,依旧指向全局对象 window。
2.参数的使用
function func(a, b, c) {console.log(a, b, c);
}
var func1 = func.bind(null,'linxin');func('A', 'B', 'C'); // A B C
func1('A', 'B', 'C'); // linxin A B
func1('B', 'C'); // linxin B C
func.call(null, 'linxin'); // linxin undefined undefined
call 是把第二个及以后的参数作为 func 方法的实参传进去,而 func1 方法的实参实则是在 bind 中参数的基础上再往后排。
在低版本浏览器没有 bind 方法,我们也可以自己实现一个。
if (!Function.prototype.bind) {Function.prototype.bind = function () {var self = this, // 保存原函数context = [].shift.call(arguments), // 保存需要绑定的this上下文args = [].slice.call(arguments); // 剩余的参数转为数组return function () { // 返回一个新函数self.apply(context,[].concat.call(args, [].slice.call(arguments)));}}
}
下一篇介绍闭包:JavaScript 中 闭包 的详解。
更多文章:lin-xin/blog
转载于:https://www.cnblogs.com/linxin/p/6592664.html
JavaScript 中 apply 、call 的详解相关推荐
- JavaScript中DOM对象的详解
*** JavaScript中DOM对象的详解*** DOM对象:Document Object Model,文档对象模型.也称为document(文档对象),是HTML页面当前窗体的内容,是连接JS ...
- php 实现setinterval,JavaScript中setInterval的使用详解
相信很多大伙都知道JavaScript中setInterval的作用是在播放动画的时,每隔一定时间就调用函数,方法或对象,也有很多小伙伴对此也只是知道setInterval的定义.也是一知半解,今天我 ...
- Javascript中的Document对象详解
Document对象详解 document 文挡对象 - JavaScript脚本语言描述 -------------------------------------------- ...
- javascript中的闭包closure详解
文章目录 简介 函数中的函数 Closure闭包 使用闭包实现private方法 闭包的Scope Chain 闭包常见的问题 闭包性能的问题 总结 简介 闭包closure是javascript中一 ...
- JavaScript 中常见排序算法详解
十大经典算法 一张图概括: 名词解释: n:数据规模 k:"桶"的个数 In-place:占用常数内存,不占用额外内存 Out-place:占用额外内存 稳定性:排序后2个相等键值 ...
- javascript 中match函数使用详解
javascript中的match函数是使用正则表达式对字符串进行查找,并将查找的结果作为数组返回,在实际开发中非常的有用,使用方法如下: stringObj.match(rgExp) 其中strin ...
- JavaScript中的valueOf方法详解
Object.prototype.valueOf() valueOf() 方法返回指定对象的原始值. 语法 object.valueOf() 返回值 返回值为该对象的原始值. 描述 JavaScrip ...
- JavaScript中的window对象详解
1.window对象简介 (1)在JavaScript中,一个浏览器窗口就是一个window对象. (2)一个窗口就是一个window对象,这个窗口里面的HTML文档就是一个document对象,do ...
- 理解JavaScript中this的指向详解
this的定义和理解: this是JavaScript语言的一个关键字,它是函数运行时,在函数体内部自动生成的一个对象,只能在函数体内使用. 1.this和执行环境对象有关,和函数的声明无关. var ...
- PHP和javascript中url编码解码详解
在实际开发中,我们可能会遇到路径编码解码的问题,下面总结了一下: PHP中: 1.urlencode(编码),urldecode(解码) $a = urlencode('http://www.baid ...
最新文章
- Linux下硬盘安装linux
- 介绍一下 information_schema 库
- facade-pattern外观模式
- Day 02 第二天课时总结
- 向量空间 Vector Space -- 推荐系统
- 华大基因:新型冠状病毒检测试剂盒日均产能已达8万人份
- 北斗形变监测系统_一款基于北斗卫星定位边坡表面位移监测系统
- 计算机网络---DHCP/NAT(简单介绍)
- 信号之sleep函数
- BlackBerry HTML5 WebWorks 平台下,让BB10应用连接上BBM
- 精准验码,昂视助力锂电生产管理追溯
- android webview浏览器下载文件,Android 浏览器 —— 使用 WebView 实现文件下载
- java 静态方法中调用非静态方法
- 地球经纬度转换为unity球面坐标
- pyton 内置模块
- 如何对计算机进行磁盘整理,如何对Windows 7进行磁盘碎片整理?
- PHP民俗文化管理系统,中国民俗文化
- Netty ChannelGroup自动移除InActive的Channel实现
- 与chatGPT的第一次亲密接触
- opencv2/3播放视频实现进度条显示拖动、快进、快退、逐帧播放、显示当前帧于图像
热门文章
- sqlplus可以连接plsql连接不上_Gee引擎配置微端不更新,连接不上,尝试重新连接的解决方法...
- java中的关键字transient说明
- Window setTimeout() 方法
- JS将Date加八小时
- Java系统中如何拆分同步和异步
- AIoT催使AI深度场景化,“AI赋能,智联万物——开发者沙龙·南京站”圆满落幕...
- chrome fiddler 重定向 https 请求
- Django通过pycharm创建后,如何登录admin后台?
- AI 是中性的技术,如何用它更好地为人类服务
- 将Java项目从maven迁移到gradle