浅谈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 相关文章推荐
关于 byval 与 byref 的区别分析总结
Oct 08 Javascript
风吟的小型JavaScirpt库 (FY.JS).
Mar 09 Javascript
Javascript中call的两种用法实例
Dec 13 Javascript
javascript圆盘抽奖程序实现原理和完整代码例子
Jun 03 Javascript
在HTML中插入JavaScript代码的示例
Jun 03 Javascript
jQuery 获取select选中值及清除选中状态
Dec 13 Javascript
node前端开发模板引擎Jade的入门
May 11 Javascript
解决koa2 ctx.render is not a function报错问题
Aug 07 Javascript
通过javascript实现扫雷游戏代码实例
Feb 09 Javascript
JavaScript 异步时序问题
Nov 20 Javascript
JavaScript实现通讯录功能
Dec 27 Javascript
javascript中Set、Map、WeakSet、WeakMap区别
Dec 24 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
2020最新CPU的性能排名
2020/04/02 数码科技
smarty中改进truncate使其支持中文的方法
2016/05/30 PHP
PhpStorm terminal无法输入命令的解决方法
2016/10/09 PHP
利用laravel搭建一个迷你博客实战教程
2017/08/13 PHP
JQuery,Extjs,YUI,Prototype,Dojo 等JS框架的区别和应用场景简述
2010/04/15 Javascript
javascript贪吃蛇完整版(源码)
2013/12/09 Javascript
分享20个提升网站界面体验的jQuery插件
2014/12/15 Javascript
JS将滑动门改为选项卡(需鼠标点击)的实现方法
2015/09/27 Javascript
JSONP原理及简单实现
2016/06/08 Javascript
微信小程序 教程之引用
2016/10/18 Javascript
JS中with的替代方法与String中的正则方法详解
2016/12/23 Javascript
Angular.js ng-file-upload结合springMVC的使用教程
2017/07/10 Javascript
AngularJs 终极购物车(实例讲解)
2017/11/08 Javascript
Vue中JS动画与Velocity.js的结合使用
2019/02/13 Javascript
python中map、any、all函数用法分析
2015/04/21 Python
用Python进行行为驱动开发的入门教程
2015/04/23 Python
python杀死一个线程的方法
2015/09/06 Python
python面向对象_详谈类的继承与方法的重载
2017/06/07 Python
python三方库之requests的快速上手
2019/03/04 Python
Python考拉兹猜想输出序列代码实践
2019/07/05 Python
Python多个装饰器的调用顺序实例解析
2020/05/22 Python
Python unittest单元测试openpyxl实现过程解析
2020/05/27 Python
thinkphp5 路由分发原理
2021/03/18 PHP
Merrell迈乐澳大利亚网站:购买户外登山鞋
2017/05/28 全球购物
Carolina Lemke Berlin澳大利亚官网:时尚太阳镜品牌
2019/09/17 全球购物
违反校纪校规检讨书
2014/02/15 职场文书
幼儿园教师获奖感言
2014/03/11 职场文书
诚信考试倡议书
2014/04/15 职场文书
霸气队列口号
2014/06/18 职场文书
地球物理学专业推荐信
2014/09/08 职场文书
2015年村党支部工作总结
2015/04/30 职场文书
金榜题名主持词
2015/07/02 职场文书
公安干警正风肃纪心得体会
2016/01/15 职场文书
2016年学校十一国庆节活动总结
2016/04/01 职场文书
TensorFlow的自动求导原理分析
2021/05/26 Python
Java 泛型详解(超详细的java泛型方法解析)
2021/07/02 Java/Android