call和apply用途与使用方法
当你看代码时,经常会看到以下情形:(在这个博客里面,参数context是执行上下文的意思,params是参数的意思)
Object.prototype.toString.call(context, params);
fn.call(context, params);
Array.prototype.slice.call(context, params);
等等。
不要惊奇,不要慌张,看完这篇文章下次你就不怕了,甚至自己也会经常这么写了。
先说以下call,apply先不提了,等你把call学会了,到文章末尾也就把apply学会了。
用途:改变this指向
Object.prototype.toString.call(context, params);
这句话就相当于执行toString函数,如:toString(params); 但是为什么不直接这样写呢?
先看一段代码的执行结果:
var str = "stringstr";
var num = 12;
var arr = [1, 2];
var obj = {name: "solid"}; console.log(str.toString()); // stringstr
console.log(num.toString()); //
console.log(arr.toString()); // 1,2
console.log(obj.toString()); // [object Object] console.log(Object.prototype.toString.call(str)); // [object String]
console.log(Object.prototype.toString.call(num)); // [object Number]
console.log(Object.prototype.toString.call(arr)); // [object Array]
console.log(Object.prototype.toString.call(obj)); // [object Object]
如果你调用Object.prototype.toString()函数是不是可以查看变量的类型啊,进而进行别的逻辑。
在js中,基本上所有的变量都是从Object继承来的,但是他们又都改写了toString方法,所以调用自身的toString方法会得到重写后的函数的结果。有的并没有什么实际的用处,如字符串的toString方法。
下面看点实用的引用吧:
// A程序员写了一个函数
function Person(name, age, sex){
this.name = name;
this.age = age;
this.sex = sex;
}
// 现在一个对象里,你的需求里也需要这三个参数
var zhangsan = {};
// 你就可以这样借用他的函数为你效力
Person.call(zhangsan, "张三", 18, "男");
console.log(zhangsan); // {name: "张三", age: 18, sex: "男"}
// 你可能还需要其他的信息,再写就可以了
function say(){
this.say = function (){
console.log(this.name + "具有说话的能力");
}
}
say.call(zhangsan);
zhangsan.say(); // 张三具有说话的能力
在上面这个例子中,zhangsan这个对象借用了其他的函数实现了自己的功能。这样调用函数,是不是相当于把Person函数中的this指向了zhangsan,把say函数中的this指向了zhangsan?结果实现了调用其他构造函数的方法,为自己实现了功能。
开始学习的时候,我看call也不顺眼,就直接看成前面那个方法的执行。
当不需要改变this时,可以这样调
fn.call(null, params);
不过这个好像没有什么意义,还不如直接写fn(params);即调用函数。
使用方法:fn.call(context, params);
还有其他的如:
Object.prototype.toString.call(context, params);
Array.prototype.slice.call(context, params);
在这里相当于: toString.call(context, params); slice.call(context, params);
只是toString方法和slice不是全局的,而是Object和Array原型上的一个方法,所以需要这样来写。
看到这里对你的理解有没有一点帮助呢?有没有感觉使用起来也很简单呢。
下面说说apply。
apply的用途和call一模一样,只是参数有区别。call的参数是用逗号隔开的,apply的参数是一个数组。例子具体见下面的代码
Person.call(zhangsan, "张三", 18, "男");
Person.apply(zhangsan, ["张三", 18, "男"]);
// 这两句是等价的
apply什么时候用呢?看下面的例子把
// 已知一个数组,求数组中的最大值
var numArr = [12, 21, 9, 18, 100, 0];
var max = Math.max.apply(null, numArr);
console.log(max); // 100 // 下面这个求最大值的函数你可以直接收藏使用了。
function max(){
return Math.max.apply(null, arguments);
}
console.log(max(12, 21, 9, 18, 100, 0)); // 100
call和apply用途与使用方法的更多相关文章
- apply()和call()的方法
apply()和call()的方法的区别 参考文档https://www.cnblogs.com/lengyuehuahun/p/5643625.html 一直都没太明白apply()与call()的 ...
- JavaScript中的apply()方法和call()方法使用介绍
1.每个函数都包含两个非继承而来的方法:apply()和call(). 2.他们的用途相同,都是在特定的作用域中调用函数. 3.接收参数方面不同,apply()接收两个参数,一个是函数运行的作用域(t ...
- JavaScript的apply()方法和call()方法
1 <script type="text/javascript"> 2 /*定义一个人类*/ 3 function Person(name,age) 4 { 5 thi ...
- 利用apply和arguments复用方法
首先,有个单例对象,它上面挂了很多静态工具方法.其中有一个是each,用来遍历数组或对象. var nativeForEach = [].forEach var nativeMap = [].map ...
- 彻底理解了call()方法,apply()方法和bind()方法
javascript中的每一个作用域中都有一个this对象,它代表的是调用函数的对象.在全局作用域中,this代表的是全局对象(在web浏览器中指的是window).如果包含this的函数是一个对象的 ...
- apply方法和call方法。函数属性与方法。
每个函数都有length属性哥prototype属性. length属性表示的是函数接入参数的个数 在es引用类型语言中,prototype是保存它们所有实例方法的真正所在.换句话来说,类似于toSt ...
- AngularJs $scope 里面的$apply 方法和$watch方法
Angular $scope 里面的$apply 方法 Scope提供$apply方法传播Model变化 <!DOCTYPE html> <html> <head> ...
- 【JavaScript】call和apply区别及使用方法
一.方法的定义call方法: 语法:fun.call(thisArg[, arg1[, arg2[, ...]]])定义:调用一个对象的一个方法,以另一个对象替换当前对象.说明:call 方法可以用来 ...
- apply方法和call方法的详解2
1.apply和call的区别在哪里 2.什么情况下用apply,什么情况下用call 3.apply的其他巧妙用法(一般在什么情况下可以使用apply) 我首先从网上查到关于apply和call的定 ...
随机推荐
- UOJ#422. 【集训队作业2018】小Z的礼物
#422. [集训队作业2018]小Z的礼物 min-max容斥 转化为每个集合最早被染色的期望时间 如果有x个选择可以染色,那么期望时间就是((n-1)*m+(m-1)*n))/x 但是x会变,中途 ...
- Wireless Network POJ - 2236 (并查集)
#include<iostream> #include<vector> #include<string> #include<cmath> #includ ...
- NOIP2017到都不签签记
day 0: 校内开运动会,但是还是在机房学习了一天. 感觉上并没有多大用处,主要只是活跃一下思维而已. 然后就晚上上车出发去酒店. 下了个游戏王. 晚上叫了波宅急送,然后硬是腐了一个晚上. day ...
- IntelliJ IDEA包层级结构显示方式
在开发的过程中,程序结构增多,通过树状结构看包结构目录,更加舒适. Idea默认情况下是不分层级展示包结构的 点击设置标志按钮,如下图所示 去掉Hide Empty Middle Packages的勾 ...
- Vue--过滤器(私有和公有)
一.过滤器的基本使用 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- R语言分类算法之随机森林
R语言分类算法之随机森林 1.原理分析: 随机森林是通过自助法(boot-strap)重采样技术,从原始训练样本集N中有放回地重复随机抽取k个样本生成新的训练集样本集合,然后根据自助样本集生成k个决策 ...
- 阿里云MVP北京闭门会圆满落幕 多把“利剑”助力开发者破阵蜕变
摘要: 从传统制造业到新零售,从人工智能到新金融,阿里云MVP正在成为中国乃至全球各行各业数字化转型的中坚力量.当这群技术先锋者与阿里核心技术力量汇聚在一起,一场无与伦比的思想碰撞就此展开. 3月21 ...
- 数据库lib7第2, 3题(创建索引和触发器)
2. 分别为上述建立的表格建立适当的索引,请描述建立索引的过程(可以截图或者写SQL).其中,要求对SPJ标中的SNo, PNo字段各建立一个索引,为(PNo, JNo)的组合建立一个索引.请问,SN ...
- C++:static类
static自我理解 static使得数据成员或者函数生命周期为整个文件所在程序的生命周期, 在C中还可以用它避免被其它文件使用为外部成员 static类 明确:类的静态数据成员它被所有类对象共享,但 ...
- Directx11教程(47) alpha blend(4)-雾的实现
原文:Directx11教程(47) alpha blend(4)-雾的实现 除了用来实现透明效果之外,我们还可以用alpha blend来实现雾(fog)的效果.通过逐渐清晰的雾气效果,可 ...