浅谈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 EasyUI API 中文文档 DateTimeBox日期时间框
Oct 16 Javascript
扒一扒JavaScript 预解释
Jan 28 Javascript
深入理解JavaScript系列(41):设计模式之模板方法详解
Mar 04 Javascript
React.js入门学习第一篇
Mar 30 Javascript
jQuery轻松实现表格的隔行变色和点击行变色的实例代码
May 09 Javascript
Vue 过渡实现轮播图效果
Mar 27 Javascript
jQuery extend()详解及简单实例
May 06 jQuery
jQuery 防止相同的事件快速重复触发方法
Feb 08 jQuery
AngularJs中$cookies简单用法分析
May 30 Javascript
通过seajs实现JavaScript的模块开发及按模块加载
Jun 06 Javascript
解决Vue在Tomcat8下部署页面不加载的问题
Nov 12 Javascript
JS数组扁平化、去重、排序操作实例详解
Feb 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
PHP+MYSQL开发工具及资源收藏
2007/01/02 PHP
PHP冒泡算法详解(递归实现)
2014/11/10 PHP
php简单实现多字节字符串翻转的方法
2015/03/31 PHP
PHP读取大文件末尾N行的高效方法推荐
2016/06/03 PHP
PHP token验证生成原理实例分析
2019/06/05 PHP
懒就要懒到底——鼠标自动点击(含时间判断)
2007/02/20 Javascript
Google 静态地图API实现代码
2010/11/19 Javascript
dojo学习第一天 Tab选项卡 实现
2011/08/28 Javascript
js相册效果代码(点击创建即可)
2013/04/16 Javascript
jQuery事件绑定on()、bind()与delegate() 方法详解
2015/06/03 Javascript
JS中dom0级事件和dom2级事件的区别介绍
2016/05/05 Javascript
jquery点击切换背景色的简单实例
2016/08/25 Javascript
基于JS设计12306登录页面
2016/12/28 Javascript
Vue条件循环判断+计算属性+绑定样式v-bind的实例
2018/09/18 Javascript
vue项目引入ts步骤(小结)
2019/10/31 Javascript
[01:04:20]完美世界DOTA2联赛PWL S2 LBZS vs Forest 第一场 11.29
2020/12/02 DOTA
实例讲解Python设计模式编程之工厂方法模式的使用
2016/03/02 Python
详解python 注释、变量、类型
2018/08/10 Python
Python_查看sqlite3表结构,查询语句的示例代码
2019/07/17 Python
python读取配置文件方式(ini、yaml、xml)
2020/04/09 Python
Pycharm添加虚拟解释器报错问题解决方案
2020/10/13 Python
Jupyter Notebook安装及使用方法解析
2020/11/12 Python
Python 转移文件至云对象存储的方法
2021/02/07 Python
英国可持续奢侈品包包品牌:Elvis & Kresse
2018/08/05 全球购物
方正Java笔试题
2014/07/03 面试题
经管应届生求职信
2013/11/17 职场文书
致长跑运动员广播稿
2014/01/31 职场文书
酒店七夕情人节活动策划方案
2014/08/24 职场文书
英文辞职信范文
2015/05/13 职场文书
王亚平太空授课观后感
2015/06/12 职场文书
何时使用Map来代替普通的JS对象
2021/04/29 Javascript
详解NodeJS模块化
2021/06/15 NodeJs
使用Python+OpenCV进行卡类型及16位卡号数字的OCR功能
2021/08/30 Python
Python卷积神经网络图片分类框架详解分析
2021/11/07 Python
浅谈css实现背景颜色半透明的两种方法
2021/12/06 HTML / CSS
Spring Data JPA框架的核心概念和Repository接口
2022/04/28 Java/Android