浅谈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 相关文章推荐
基于jquery自定义的漂亮单选按钮RadioButton
Nov 19 Javascript
js的回调函数详解
Jan 05 Javascript
js生成随机数的过程解析
Nov 24 Javascript
jQuery表格插件datatables用法详解
Nov 23 Javascript
js实现适配不同的屏幕大小
Apr 10 Javascript
BootStrap表单控件之文本域textarea
May 23 Javascript
浅谈struts1 & jquery form 文件异步上传
May 25 jQuery
ionic2屏幕适配实现适配手机、平板等设备的示例代码
Aug 11 Javascript
微信小程序使用字体图标的方法
May 23 Javascript
ES6 proxy和reflect的使用方法与应用实例分析
Feb 15 Javascript
jQuery实现移动端图片上传预览组件的方法分析
May 01 jQuery
Ant design vue中的联动选择取消操作
Oct 31 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
PHP的开发框架的现状和展望
2007/03/16 PHP
浅析php变量作用域的一些问题
2013/08/08 PHP
php绘图中显示不出图片的原因及解决
2014/03/05 PHP
PHP在线书签系统分享
2016/01/04 PHP
yii2使用ajax返回json的实现方法
2016/05/14 PHP
用php和jQuery来实现“顶”和“踩”的投票功能
2016/10/13 PHP
PHP中单例模式与工厂模式详解
2017/02/17 PHP
采用CSS和JS,刚好我最近有个站点要用到下拉菜单!
2006/06/26 Javascript
javascript学习笔记(十) js对象 继承
2012/06/19 Javascript
jquery如何把参数列严格转换成数组实现思路
2013/04/01 Javascript
Jquery实现弹出层分享微博插件具备动画效果
2013/04/03 Javascript
关于页面嵌入swf覆盖div层的问题的解决方法
2014/02/11 Javascript
自定义jquery模态窗口插件无法在顶层窗口显示问题
2014/05/29 Javascript
JavaScript中创建字典对象(dictionary)实例
2015/03/31 Javascript
jQuery EasyUI tree 使用拖拽时遇到的错误小结
2016/10/10 Javascript
JS触摸与手势事件详解
2017/05/09 Javascript
详解Angular的8个主要构造块
2017/06/20 Javascript
基于node下的http小爬虫的示例代码
2018/01/11 Javascript
微信小程序--特定区域滚动到顶部时固定的方法
2019/04/28 Javascript
基于vue.js实现购物车
2020/01/15 Javascript
[04:03]DOTA2英雄梦之声_第02期_风暴之灵
2014/06/30 DOTA
在Python中使用SQLite的简单教程
2015/04/29 Python
python连接数据库的方法
2017/10/19 Python
DES加密解密算法之python实现版(图文并茂)
2018/12/06 Python
python绘制漏斗图步骤详解
2019/03/04 Python
美国新兴城市生活方式零售商:VILLA
2017/12/06 全球购物
初二物理教学反思
2014/01/29 职场文书
2014迎新年晚会策划方案
2014/02/23 职场文书
班长竞选演讲稿
2014/04/24 职场文书
500字小学生检讨书
2015/02/19 职场文书
结婚十年感言
2015/07/31 职场文书
2015新员工工作总结范文
2015/10/15 职场文书
优胜劣汰,强者为王——读《鲁滨逊漂流记》有感
2019/08/15 职场文书
Java集成swagger文档组件
2021/06/28 Java/Android
不负正版帝国之名 《重返帝国》引领SLG手游制作新的标杆
2022/04/07 其他游戏
Mybatis-plus配置分页插件返回统一结果集
2022/06/21 Java/Android