浅谈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 相关文章推荐
JavaScript 关键字屏蔽实现函数
Aug 02 Javascript
JavaScript 学习初步 入门教程
Mar 25 Javascript
myEvent.js javascript跨浏览器事件框架
Oct 24 Javascript
jQuery插件pagewalkthrough实现引导页效果
Jul 05 Javascript
jquery实现图片上传前本地预览功能
May 10 Javascript
使用smartupload组件实现jsp+jdbc上传下载文件实例解析
Jan 05 Javascript
jQuery弹出层插件popShow(改进版)用法示例
Jan 23 Javascript
详解Angular-cli生成组件修改css成less或sass的实例
Jul 27 Javascript
基于Bootstrap table组件实现多层表头的实例代码
Sep 07 Javascript
Node.js学习教程之HTTP/2服务器推送【译】
Oct 31 Javascript
vue实现多个元素或多个组件之间动画效果
Sep 25 Javascript
vue实现可拖拽的dialog弹框
May 13 Vue.js
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图片上传程序
2008/03/27 PHP
php导出word文档与excel电子表格的简单示例代码
2014/03/08 PHP
thinkphp3.2中Lite文件替换框架入口文件或应用入口文件的方法
2015/05/21 PHP
Yii2.0多文件上传实例说明
2017/07/24 PHP
详解如何实现Laravel的服务容器的方法示例
2019/04/15 PHP
12个非常有创意的JavaScript小游戏
2010/03/18 Javascript
JavaScript中常见陷阱小结
2010/04/27 Javascript
图片onload事件触发问题解决方法
2011/07/31 Javascript
js+数组实现网页上显示时间/星期几的实用方法
2013/01/18 Javascript
js调用css属性写法
2013/09/21 Javascript
node.js中的fs.fsync方法使用说明
2014/12/15 Javascript
jQuery实现Div拖动+键盘控制综合效果的方法
2015/03/10 Javascript
js实现简单的左右两边固定广告效果实例
2015/04/10 Javascript
举例讲解AngularJS中的模块
2015/06/17 Javascript
JS实现的N多简单无缝滚动代码(包含图文效果)
2015/11/06 Javascript
JavaScript知识点总结(六)之JavaScript判断变量数据类型
2016/05/31 Javascript
每日十条JavaScript经验技巧(二)
2016/06/23 Javascript
Bootstrap Scrollspy源码学习
2017/03/02 Javascript
AngularJS全局警告框实现方法示例
2017/05/18 Javascript
vue中路由验证和相应拦截的使用详解
2017/12/13 Javascript
Nodejs环境实现socket通信过程解析
2020/07/03 NodeJs
Vue实现简单购物车功能
2020/12/13 Vue.js
[10:21]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster 选手采访
2021/03/11 DOTA
python抓取京东商城手机列表url实例代码
2013/12/18 Python
Python脚本判断 Linux 是否运行在虚拟机上
2015/04/25 Python
Python 26进制计算实现方法
2015/05/28 Python
Python操作Excel之xlsx文件
2017/03/24 Python
详解Python中字符串前“b”,“r”,“u”,“f”的作用
2019/12/18 Python
基于OpenCV的路面质量检测的实现
2020/11/04 Python
奥地利顶级内衣丝袜品牌英国站:Wolford英国
2016/08/29 全球购物
华为慧通面试题
2012/09/11 面试题
幼师岗位求职简历的自荐信格式
2013/09/21 职场文书
秦兵马俑教学反思
2014/02/07 职场文书
纠纷协议书
2014/04/16 职场文书
纪检监察建议书
2014/05/19 职场文书
2014年工商所工作总结
2014/12/09 职场文书