详解js中的apply与call的用法


Posted in Javascript onJuly 30, 2016

前言

call 和 apply 都是为了改变某个函数运行时的 context 即上下文而存在的,换句话说,就是为了改变函数体内部 this 的指向
call 和 apply二者的作用完全一样,只是接受参数的方式不太一样。

方法定义
apply
Function.apply(obj,args)方法能接收两个参数:

obj:这个对象将代替Function类里this对象

args:这个是数组或类数组,apply方法把这个集合中的元素作为参数传递给被调用的函数。

call

call方法apply方法的第一个参数是一样的,只不过第二个参数是一个参数列表

在非严格模式下当我们第一个参数传递为null或undefined时,函数体内的this会指向默认的宿主对象,在浏览器中则是window

var test = function(){
  console.log(this===window);
}
test.apply(null);//true
test.call(undefined);//true

用法

"劫持"别人的方法

此时foo中的logName方法将被bar引用 ,this指向了bar

var foo = {
  name:"mingming",
  logName:function(){
    console.log(this.name);
  }
}
var bar={
  name:"xiaowang"
};
foo.logName.call(bar);//xiaowang

实现继承

function Animal(name){   
  this.name = name;   
  this.showName = function(){   
    console.log(this.name);   
  }   
}   

function Cat(name){  
  Animal.call(this, name);  
}   

var cat = new Cat("Black Cat");   
cat.showName(); //Black Cat

在实际开发中,经常会遇到this指向被不经意改变的场景。
有一个局部的fun方法,fun被作为普通函数调用时,fun内部的this指向了window,但我们往往是想让它指向该#test节点,见如下代码:

window.id="window";
document.querySelector('#test').onclick = function(){
  console.log(this.id);//test
  var fun = function(){
    console.log(this.id);
  }
  fun();//window
}

使用call,apply我们就可以轻松的解决这种问题了

window.id="window";
document.querySelector('#test').onclick = function(){
  console.log(this.id);//test
  var fun = function(){
    console.log(this.id);
  }
  fun.call(this);//test
}

当然你也可以这样做,不过在ECMAScript 5strict模式下,这种情况下的this已经被规定为不会指向全局对象,而是undefined:

window.id="window";
document.querySelector('#test').onclick = function(){
  var that = this;
  console.log(this.id);//test
  var fun = function(){
    console.log(that.id);
  }
  fun();//test
}
function func(){
  "use strict"
  alert ( this );  // 输出:undefined
}
func();

其他用法

类数组

这里把符合以下条件的对象称为类数组

1.具有length属性

2.按索引方式存储数据

3.不具有数组的push,pop等方法

常见类数组有 arguments,NodeList!

(function(){
  Array.prototype.push.call(arguments,4);
  console.log(arguments);//[1, 2, 3, 4]
})(1,2,3)

这样就往arguments中push一个4进去了

Array.prototype.push 页可以实现两个数组合并

同样push方法没有提供push一个数组,但是它提供了push(param1,param,…paramN) 所以同样也可以通过apply来装换一下这个数组,即:

var arr1=new Array("1","2","3"); 
var arr2=new Array("4","5","6"); 
Array.prototype.push.apply(arr1,arr2); 
console.log(arr1);//["1", "2", "3", "4", "5", "6"]

也可以这样理解,arr1调用了push方法,参数是通过apply将数组装换为参数列表的集合.

再比如我想求类数组中的最大值

(function(){
  var maxNum = Math.max.apply(null,arguments);
  console.log(maxNum);//56
})(34,2,56);

判断类型

console.log(Object.prototype.toString.call(123)) //[object Number]
console.log(Object.prototype.toString.call('123')) //[object String]
console.log(Object.prototype.toString.call(undefined)) //[object Undefined]
console.log(Object.prototype.toString.call(true)) //[object Boolean]
console.log(Object.prototype.toString.call({})) //[object Object]
console.log(Object.prototype.toString.call([])) //[object Array]
console.log(Object.prototype.toString.call(function(){})) //[object Function]

以上就是apply与call的用法总结的全部内容,欢迎大家积极留言参加讨论,也希望本文对大家学习javascript有所帮助。

Javascript 相关文章推荐
Jquery在指定DIV加载HTML示例代码
Feb 17 Javascript
使用ajaxfileupload.js实现ajax上传文件php版
Jun 26 Javascript
node.js中的fs.renameSync方法使用说明
Dec 16 Javascript
JavaScript焦点事件、鼠标事件和滚轮事件使用详解
Jan 15 Javascript
微信QQ的二维码登录原理js代码解析
Jun 23 Javascript
微信开发 消息推送实现代码
Oct 21 Javascript
基于javascript实现按圆形排列DIV元素(一)
Dec 02 Javascript
javascript 正则表达式去空行方法
Jan 24 Javascript
详解Angular-Cli中引用第三方库
May 21 Javascript
微信小程序调用摄像头隐藏式拍照功能
Aug 22 Javascript
微信小程序实现批量倒计时功能
Nov 01 Javascript
VUE Elemen-ui之穿梭框使用方法详解
Jan 19 Javascript
javascript回到顶部特效
Jul 30 #Javascript
javascript鼠标滑过显示二级菜单特效
Nov 18 #Javascript
避免jQuery名字冲突 noConflict()方法
Jul 30 #Javascript
分享jQuery封装好的一些常用操作
Jul 28 #Javascript
一个仿微博登陆邮箱提示框js开发案例
Jul 28 #Javascript
利用JS实现数字增长
Jul 28 #Javascript
灵活使用数组制作图片切换js实现
Jul 28 #Javascript
You might like
windows 2008r2+php5.6.28环境搭建详细过程
2019/06/18 PHP
Javascript SHA-1:Secure Hash Algorithm
2006/12/20 Javascript
风吟的小型JavaScirpt库 (FY.JS).
2010/03/09 Javascript
JQuery浮动DIV提示信息并自动隐藏的代码
2010/08/29 Javascript
js使用ajax读博客rss示例
2014/05/06 Javascript
js和jquery中循环的退出和继续下一个循环
2014/09/03 Javascript
jQuery实现带动画效果的二级下拉导航方法
2015/03/11 Javascript
javascript页面倒计时实例
2015/07/25 Javascript
asp.net+jquery.form实现图片异步上传的方法(附jquery.form.js下载)
2016/05/05 Javascript
易被忽视的js事件问题总结
2016/05/14 Javascript
jqueryMobile 动态添加元素,展示刷新视图的实现方法
2016/05/28 Javascript
使用jQuery.Pin垂直滚动时固定导航
2017/05/24 jQuery
JS倒计时实例_天时分秒
2017/08/22 Javascript
微信小程序实现的贪吃蛇游戏【附源码下载】
2018/01/03 Javascript
解决Webpack 热部署检测不到文件变化的问题
2018/02/22 Javascript
ES6 中可以提升幸福度的小功能
2018/08/06 Javascript
React中使用UMEditor的方法示例
2019/12/27 Javascript
vue 使用 canvas 实现手写电子签名
2020/03/06 Javascript
Python中使用PIL库实现图片高斯模糊实例
2015/02/08 Python
python获取指定目录下所有文件名列表的方法
2015/05/20 Python
对python创建及引用动态变量名的示例讲解
2018/11/10 Python
Python正则匹配判断手机号是否合法的方法
2020/12/09 Python
Python中按值来获取指定的键
2019/03/04 Python
解析python的局部变量和全局变量
2019/08/15 Python
Python实现实时数据采集新型冠状病毒数据实例
2020/02/04 Python
夏威夷咖啡公司:Hawaii Coffee Company
2019/09/19 全球购物
俄罗斯GamePark游戏商店网站:购买游戏、游戏机和配件
2020/03/13 全球购物
Pandora西班牙官方商店:PandoraShop.es
2020/10/05 全球购物
机械设计毕业生自荐信
2014/02/02 职场文书
学校感恩节活动策划方案
2014/10/06 职场文书
党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
单位接收证明格式
2015/06/18 职场文书
python绘制箱型图
2021/04/27 Python
JavaScript事件的委托(代理)的用法示例详解
2022/02/18 Javascript
Python中 range | np.arange | np.linspace三者的区别
2022/03/22 Python
Python使用BeautifulSoup4修改网页内容
2022/05/20 Python