浅谈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 Ajax学习实例6 向WebService发出请求,返回DataSet(XML) 异步调用
Mar 18 Javascript
jqgrid 简单学习笔记
May 03 Javascript
随窗体滑动的小插件sticky源码
Jun 21 Javascript
JS实现时间格式化的方式汇总
Oct 16 Javascript
a标签的href与onclick事件的区别详解
Nov 12 Javascript
jQuery EasyUI提交表单验证
Jul 19 Javascript
jq实现左滑显示删除按钮,点击删除实现删除数据功能(推荐)
Aug 23 Javascript
jQuery中$.grep() 过滤函数 数组过滤
Nov 22 Javascript
详解js中==与===的区别
Jan 08 Javascript
Vue filter介绍及详细使用
Apr 04 Javascript
全站最详细的Vuex教程
Apr 13 Javascript
vue 解决computed修改data数据的问题
Nov 06 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项目开发中最常用的自定义函数整理
2010/12/02 PHP
php中数字0和空值的区别分析
2014/06/05 PHP
yum命令安装php7和相关扩展
2016/07/04 PHP
Zend Framework校验器Zend_Validate用法详解
2016/12/09 PHP
JavaScript 继承详解(三)
2009/07/13 Javascript
jQuery EasyUI API 中文文档 - PropertyGrid属性表格
2011/11/18 Javascript
正则表达式中特殊符号及正则表达式的几种方法总结(replace,test,search)
2013/11/26 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 图片库
2015/01/09 Javascript
基于jQuery实现二级下拉菜单效果
2016/02/01 Javascript
判断数组是否包含某个元素的js函数实现方法
2016/05/19 Javascript
jQuery操作动态生成的内容的方法
2016/05/28 Javascript
百度地图API之百度地图退拽标记点获取经纬度的实现代码
2017/01/12 Javascript
angular4实现tab栏切换的方法示例
2017/10/21 Javascript
Vue响应式原理深入解析及注意事项
2017/12/11 Javascript
vue利用v-for嵌套输出多层对象,分别输出到个表的方法
2018/09/07 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
2018/11/29 Javascript
vue将文件/图片批量打包下载zip的教程
2020/10/21 Javascript
python判断端口是否打开的实现代码
2013/02/10 Python
tensorflow获取变量维度信息
2018/03/10 Python
Python二进制串转换为通用字符串的方法
2018/07/23 Python
Django 限制用户访问频率的中间件的实现
2018/08/23 Python
pycharm中成功运行图片的配置教程
2018/10/28 Python
python pickle存储、读取大数据量列表、字典数据的方法
2019/07/07 Python
python自动结束mysql慢查询会话的实例代码
2019/10/27 Python
python开根号实例讲解
2020/08/30 Python
科颜氏英国官网:Kiehl’s英国
2019/11/20 全球购物
英语专业毕业个人求职自荐信
2013/09/21 职场文书
竞职演讲稿范文
2014/01/11 职场文书
企业消防安全制度
2014/02/02 职场文书
元旦活动感言
2014/03/08 职场文书
销售经理岗位职责
2014/03/16 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
工作检讨书500字
2014/10/19 职场文书
运动会广播稿200字
2015/08/19 职场文书
python可视化大屏库big_screen示例详解
2021/11/23 Python
Python软件包安装的三种常见方法
2022/07/07 Python