浅谈JavaScript中的apply/call/bind和this的使用


Posted in Javascript onFebruary 26, 2017

fun.apply(context,[argsArray])

立即调用fun,同时将fun函数原来的this指向传入的新context对象,实现同一个方法在不同对象上重复使用。

context:传入的对象,替代fun函数原来的this;

argsArray:一个数组或者类数组对象,其中的数组参数会被展开作为单独的实参传给 fun 函数,需要注意参数的顺序。

fun.call(context,[arg1],[arg2],[…])

同apply,只是参数列表不同,call的参数需要分开一个一个传入。如果不知道参数个数,则使用apply。

使用:

Math.max()    //只接收单独的参数,通过下面的方法可以在数组上面使用max方法:
Math.max.apply(null, array);    //会将array数组参数展开成单独的参数再传入
Array.prototype.push.apply(arr1,arr2);    //将一个数组拆开push到另一个数组中;不用apply则会将后续数组参数当成一个元素push进去。
Array.prototype.slice.call(arguments);    //在类素组对象上使用slice方法

function isArray(obj){
  return Object.prototype.toString.call(obj) === '[object Array]' ;
}  //验证是否是数组

fun.bind(context,[arg1],[arg2],[…])

使fun方法执行的context永不变。

arg1:要传递到新函数的参数列表

返回一个函数供后续调用,其函数体和原函数fun一样,但新函数的this指向新传入的context对象。新函数会具有bind方法指定的初始参数arg1/arg2...,后续调用新函数时的实参要往已有参数的后面排。

//原来的函数有4个参数
var displayArgs = function (val1, val2, val3, val4) {
  console.log(val1 + " " + val2 + " " + val3 + " " + val4);
}
var emptyObject = {};
// 生成新函数时bind方法指定了2个参数,则新函数会带着这个两个实参
var displayArgs2 = displayArgs.bind(emptyObject, 12, "a");
// 调用时传入另2个参数,要在bind方法传入的2个实参后面
displayArgs2("b", "c");
// Output: 12 a b c

事件处理函数中使用bind:

var obj = {
  arg1 : 1,
  attach: function(){
    //var self = this; 普通传入this 的方法
    $('xxx').on('click',function (event) {
      console.log(this.arg1);//若不绑定this,回调函数中的this常指目标元素
     }.bind(this));  //使用bind方法绑定this
  }
}

使用bind()方法改写slice()方法:

var _Slice = Array.prototype.slice;
var slice = Function.prototype.call.bind(_Slice);
slice(…);

bind()兼容Ie5~ie8处理

if (!Function.prototype.bind) {
  Function.prototype.bind = function(context) {
    var self = this, // 调用bind方法的目标函数
    args = arguments;
    return function() {
      self.apply(context, Array.prototype.slice.call(args, 1));//参数个数不确定时用apply
    }
  }
}

一般情况下setTimeout()的this指向window或global对象。当使用类的方法时需要this指向类实例,就可以使用bind()将this绑定到调用对象,而不用传入self方式传入this。

this

this对象是在函数运行时基于函数的执行环境绑定的:在全局函数中,this等于window,而当函数被当作某个对象的方法调用时,this等于那个对象。

判断方法:this和定义在哪儿无关,函数运行时,如果有. 运算符,this指.前的对象;如果没有,this指window。若new关键字调用时,指代新对象。有apply/call/bind时,指代第一个参数。

/*例1*/
function foo() {
  console.log( this.a );
} 
var obj2 = {
  a: 42,
  foo: foo
};
var obj1 = {
  a: 2,
  obj2: obj2
};
obj1.obj2.foo(); // 42;当foo函数被调用时,其本身是归obj2所拥有
/*例2*/
function foo() {
  console.log( this.a );
} 
var obj = {
  a: 2,
  foo: foo
};
var bar = obj.foo;   // bar引用foo函数本身
var a = "global";   // 全局对象的属性
bar();        // "global" ;

在一个HTML DOM事件处理程序里面,this始终指向这个处理程序被所绑定到的DOM节点。

Javascript 相关文章推荐
对table和ul实现js分页示例分享
Feb 24 Javascript
jQuery实现的导航条切换可显示隐藏
Oct 22 Javascript
浅谈Node.js中的定时器
Jun 18 Javascript
javascript比较两个日期相差天数的方法
Jul 24 Javascript
JS实现可拖曳、可关闭的弹窗效果
Sep 26 Javascript
利用AJAX实现WordPress中的文章列表及评论的分页功能
May 17 Javascript
原生js实现选项卡功能
Mar 08 Javascript
jquery 禁止鼠标右键并监听右键事件
Apr 27 jQuery
使用Vuex解决Vue中的身份验证问题
Sep 28 Javascript
layDate日期控件使用方法详解
Nov 15 Javascript
vue使用axios上传文件(FormData)的方法
Apr 14 Javascript
javascript如何使用函数random来实现课堂随机点名方法详解
Jul 28 Javascript
JavaScript中Promise的使用详解
Feb 26 #Javascript
setTimeout函数的神奇使用
Feb 26 #Javascript
node.js入门学习之url模块
Feb 25 #Javascript
从零学习node.js之利用express搭建简易论坛(七)
Feb 25 #Javascript
从零学习node.js之express入门(六)
Feb 25 #Javascript
Node.JS中事件轮询(Event Loop)的解析
Feb 25 #Javascript
走进javascript——不起眼的基础,值和分号
Feb 24 #Javascript
You might like
通过文字传递创建的图形按钮
2006/10/09 PHP
《PHP边学边教》(02.Apache+PHP环境配置――上篇)
2006/12/13 PHP
php 上传文件类型判断函数(避免上传漏洞 )
2010/06/08 PHP
用javascript获取地址栏参数
2006/12/22 Javascript
非html5实现js版弹球游戏示例代码
2013/09/22 Javascript
JavaScript中使用ActiveXObject操作本地文件夹的方法
2014/03/28 Javascript
基于jQuery实现仿搜狐辩论投票动画代码(附源码下载)
2016/02/18 Javascript
bootstrap布局中input输入框右侧图标点击功能
2016/05/16 Javascript
BootStrap 超链接变按钮的实现方法
2016/09/25 Javascript
Jq通过td获取同行其它列td的方法
2016/10/05 Javascript
深入浅析Vue组件开发
2016/11/25 Javascript
JS实现的简易拖放效果示例
2016/12/29 Javascript
原生JS实现ajax与ajax的跨域请求实例
2017/12/01 Javascript
JavaScript 有用的代码片段和 trick
2018/02/22 Javascript
Angular2之二级路由详解
2018/08/31 Javascript
vue中的适配px2rem示例代码
2018/11/19 Javascript
原生javascript如何实现共享onload事件
2020/07/03 Javascript
在Mac OS上使用mod_wsgi连接Python与Apache服务器
2015/12/24 Python
12步教你理解Python装饰器
2016/02/25 Python
python中pandas.DataFrame的简单操作方法(创建、索引、增添与删除)
2017/03/12 Python
python用BeautifulSoup库简单爬虫实例分析
2018/07/30 Python
Python 窗体(tkinter)按钮 位置实例
2019/06/13 Python
django框架forms组件用法实例详解
2019/12/10 Python
Pytorch maxpool的ceil_mode用法
2020/02/18 Python
基于Python爬取爱奇艺资源过程解析
2020/03/02 Python
html5 利用重力感应实现摇一摇换颜色可用来做抽奖等等
2014/05/07 HTML / CSS
使用HTML5 Canvas API绘制弧线的教程
2016/03/22 HTML / CSS
Abbacino官网:包、钱包和女士配饰
2019/04/15 全球购物
Zalando Lounge瑞士:时尚与生活方式购物俱乐部
2020/03/12 全球购物
旅游管理专业生自荐信范文
2014/01/02 职场文书
民主生活会整改措施(党员)
2014/09/18 职场文书
2015年办公室文秘工作总结
2015/04/30 职场文书
党员进社区活动总结
2015/05/07 职场文书
公司财务管理制度
2015/08/04 职场文书
fastdfs+nginx集群搭建的实现
2021/03/31 Servers
python 闭包函数详细介绍
2022/04/19 Python