详解 JavaScript的 call() 和 apply()
定义
ECMAScript规范为所有函数都包含两个方法(这两个方法非继承而来), call 和 apply 。这两个函数都是在特定的作用域中调用函数,能改变函数的作用域,实际上是改变函数体内 this 的值 。
call 和 apply
| 语法 | 定义 | 说明 |
|---|---|---|
| call(thisObj,Object) | 调用一个对象的一个方法,以另一个对象替换当前对象。 | call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象.如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj |
| apply(thisObj,[argArray]) | 应用某一对象的一个方法,用另一个对象替换当前对象。 | 如果 argArray 不是一个有效的数组或者不是 arguments 对象,那么将导致一个 TypeError。如果没有提供 argArray 和 thisObj 任何一个参数,那么 Global 对象将被用作 thisObj, 并且无法被传递任何参数 |
用法
调用函数,传递参数
//定义一个add 方法
function add(x, y) {
return x + y;
}
//用call 来调用 add 方法
function myAddCall(x, y) {
//调用 add 方法 的 call 方法
return add.call(this, x, y);
}
//apply 来调用 add 方法
function myAddApply(x, y) {
//调用 add 方法 的 applly 方法
return add.apply(this, [x, y]);
}
console.log(myAddCall(10, 20)); //输出结果30
console.log(myAddApply(20, 20)); //输出结果40
我们看到通过方法本身的call 和 apply 执行了该函数。
改变函数作用域
var name = '小白';
var obj = {name:'小红'};
function sayName() {
return this.name;
}
console.log(sayName.call(this)); //输出小白
console.log(sayName. call(obj)); //输入小红
我们改变了函数运行的作用域, 通过绑定不同的对象,函数内部 this 也不同。最终输入结果才会这样。
高级用法,实现 js 继承
//父类 Person
function Person() {
this.sayName = function() {
return this.name;
}
}
//子类 Chinese
function Chinese(name) {
//借助 call 实现继承
Person.call(this);
this.name = name;
this.ch = function() {
alert('我是中国人');
}
}
//子类 America
function America(name) {
//借助 call 实现继承
Person.call(this);
this.name = name;
this.am = function() {
alert('我是美国人');
}
}
//测试
var chinese = new Chinese('成龙');
//调用 父类方法
console.log(chinese.sayName()); //输出 成龙
var america = new America('America');
//调用 父类方法
console.log(america.sayName()); //输出 America
区别
- 参数不同, apply 传入的是一个参数数组,也就是将多个参数组合成一个参数数组, call 从第二个参数开始依次传入.
- apply 可以直接将当前函数的arguments对象作为apply的第二个参数传入
结束语
call 和 apply 最大的好处:方便我们解耦,对象不需要和方法有任何的耦合性,能使我们写出更好的面相对象程序。
大家如果看一些 js 框架底层的话会看到好多地方都有大量用到。
详解 JavaScript的 call() 和 apply()的更多相关文章
- 详解javascript中的call, apply
一些学js的同学一看到call, apply, 就蒙了, 感觉不好懂, 看的头大. 今天我们就一起来研究一下这2个东东.彻底弄清楚它们的用法. 定义: call, apply是函数的方法, 只有函数才 ...
- 详解Javascript的继承实现(二)
上文<详解Javascript的继承实现>介绍了一个通用的继承库,基于该库,可以快速构建带继承关系和静态成员的javascript类,好使用也好理解,额外的好处是,如果所有类都用这种库来构 ...
- 【转】详解JavaScript中的this
ref:http://blog.jobbole.com/39305/ 来源:foocoder 详解JavaScript中的this JavaScript中的this总是让人迷惑,应该是js众所周知的坑 ...
- js对象详解(JavaScript对象深度剖析,深度理解js对象)
js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...
- 详解javascript中的this对象
详解javascript中的this对象 前言 Javascript是一门基于对象的动态语言,也就是说,所有东西都是对象,一个很典型的例子就是函数也被视为普通的对象.Javascript可以通过一定的 ...
- 详解JavaScript调用栈、尾递归和手动优化
调用栈(Call Stack) 调用栈(Call Stack)是一个基本的计算机概念,这里引入一个概念:栈帧. 栈帧是指为一个函数调用单独分配的那部分栈空间. 当运行的程序从当前函数调用另外一个函数时 ...
- 详解javascript的类
前言 生活有度,人生添寿. 原文地址:详解javascript的类 博主博客地址:Damonare的个人博客 Javascript从当初的一个"弹窗语言",一步步发展成为现在前后端 ...
- 详解 javascript中offsetleft属性的用法(转)
详解 javascript中offsetleft属性的用法 转载 2015-11-11 投稿:mrr 我要评论 本章节通过代码实例介绍一下offsetleft属性的用法,需要的朋友可以做一 ...
- 详解JavaScript的任务、微任务、队列以及代码执行顺序
摘要: 理解JS的执行顺序. 作者:前端小智 原文:详解JavaScript的任务.微任务.队列以及代码执行顺序 思考下面 JavaScript 代码: console.log("scrip ...
随机推荐
- 盘点销售一体机 打印POS一体的设备。 打印,盘点,销售PDA(手持终端)+移动销售POS软件
一.产品介绍 本产品为一个PDA(手持终端)+移动销售POS管理软件组合.可以实现功能如下: 可以实现移动销售(销售退货).盘点.配送.移库.打印小票的功能. 销售时,可以选择客户.业务员.库房,并且 ...
- Python学习日志(二)
在网易云课堂看到小甲鱼的python视频,想起以前看就是看他的视频学C的虽然后来不了了之都怪我自己啦,于是决定跟着这个视频来学python啦! IDLE IDLE其实是一个python shell , ...
- 分布式平台Spark环境的搭建
1.安装Spark之前需要先安装Java,Scala及Python(个人喜欢用pyspark,当然你也可以用原生的Scala) 首先安装Java jdk: 我们可以在Oracle的官网下载Java S ...
- 求50-100内的素数(java)
实现代码: public class sushu { public static void main(String[] args) { for(int i=50 ; i<=100; i++){ ...
- Holographic Remoting
看到微软官方的 Holographic Remoting Player https://developer.microsoft.com/en-us/windows/holographic/hologr ...
- [JSOI2008]完美的对称 题解
题目大意: 首先我们给定一点A以及对称中心S,点A'是点A以S为对称中心形成的像点,即点S是线段AA'的对称中心. 点阵组(X)以S为中心的像点是由每个点的像点组成的点阵组.X是用来产生对称中心S的, ...
- Redis 主从配置
环境 Master/Slave 系统 IP Redis版本 Master CentOS6.7 10.10.3.211 redis-3.2.6 ...
- 【BFS】HDU 1495
直达–> HDU 1495 非常可乐 相似题联动–>POJ 3414 Pots 题意:中文题,不解释. 思路:三个杯子倒来倒去,最后能让其中两个平分即可.可能性六种.判定的时候注意第三个杯 ...
- 基础3.Jquery操作Dom
1 内部插入节点 <body> <ul id="city"> <li id="bj" name=&qu ...
- 简单C#、asp.net mvc验证码的实现
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Text;u ...