浅谈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 hasFocus使用实例
Jun 29 Javascript
jquery中dom操作和事件的实例学习 仿yahoo邮箱登录框的提示效果
Nov 30 Javascript
js substring从右边获取指定长度字符串(示例代码)
Dec 23 Javascript
AngularJS基础知识笔记之表格
May 10 Javascript
jquery+html5时钟特效代码分享(可设置闹钟并且语音提醒)
Mar 30 Javascript
JS中对Cookie的操作详解
Aug 05 Javascript
Bootstrap CSS组件之导航条(navbar)
Dec 17 Javascript
vue2项目使用sass的示例代码
Jun 28 Javascript
使用 Node.js 开发资讯爬虫流程
Jan 07 Javascript
详解webpack4之splitchunksPlugin代码包分拆
Dec 04 Javascript
js中apply和call的理解与使用方法
Nov 27 Javascript
JavaScript canvas实现流星特效
May 20 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
239军机修复记
2021/03/02 无线电
Php 构造函数construct的前下划线是双的_
2009/12/08 PHP
第三章 php操作符与控制结构代码
2011/12/30 PHP
PHP用星号隐藏部份用户名、身份证、IP、手机号等实例
2014/04/08 PHP
Yii2.0实现的批量更新及批量插入功能示例
2019/01/29 PHP
在JS中解析HTML字符串示例代码
2014/04/16 Javascript
javascript实现左右控制无缝滚动
2014/12/31 Javascript
使用jQuery+EasyUI实现CheckBoxTree的级联选中特效
2015/12/06 Javascript
JS 对象(Object)和字符串(String)互转方法
2016/05/20 Javascript
Three.js学习之几何形状
2016/08/01 Javascript
jQuery中fadein与fadeout方法用法示例
2016/09/16 Javascript
BootStrop前端框架入门教程详解
2016/12/25 Javascript
详解vue + vuex + directives实现权限按钮的思路
2017/10/24 Javascript
在 Typescript 中使用可被复用的 Vue Mixin功能
2018/04/17 Javascript
KOA+egg.js集成kafka消息队列的示例
2018/11/09 Javascript
JS数组方法concat()用法实例分析
2020/01/18 Javascript
node.js制作一个简单的登录拦截器
2020/02/10 Javascript
详解vue父子组件状态同步的最佳方式
2020/09/10 Javascript
jquery实现抽奖功能
2020/10/22 jQuery
elementui实现预览图片组件二次封装
2020/12/29 Javascript
[04:16]完美世界DOTA2联赛PWL S2 集锦第一期
2020/11/23 DOTA
wxPython窗口的继承机制实例分析
2014/09/28 Python
python模拟事件触发机制详解
2018/01/19 Python
python实现Decorator模式实例代码
2018/02/09 Python
Python学习笔记之抓取某只基金历史净值数据实战案例
2019/06/03 Python
Python2比较当前图片跟图库哪个图片相似的方法示例
2019/09/28 Python
浅谈PyTorch中in-place operation的含义
2020/06/27 Python
虚拟环境及venv和virtualenv的区别说明
2021/02/05 Python
HTML5+CSS3应用详解
2014/02/24 HTML / CSS
瑞典香水、须后水和美容产品购物网站:Parfym-Klick.se
2019/12/29 全球购物
大学生个人求职信例文
2014/07/07 职场文书
小学生勤俭节约演讲稿
2014/08/28 职场文书
人与自然的观后感
2015/06/18 职场文书
男方家长婚礼致辞
2015/07/27 职场文书
公司酒会致辞
2015/07/30 职场文书
Go语言使用select{}阻塞main函数介绍
2021/04/25 Golang