浅谈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删除option选项的多种方法总结
Nov 22 Javascript
原生JavaScript编写俄罗斯方块
Mar 30 Javascript
JS实现弹出浮动窗口(支持鼠标拖动和关闭)实例详解
Aug 06 Javascript
浅谈JS中逗号运算符的用法
Jun 12 Javascript
jQuery 中msgTips 顶部弹窗效果实现代码
Aug 14 jQuery
Vue+SpringBoot开发V部落博客管理平台
Dec 27 Javascript
微信小程序http连接访问解决方案的示例
Nov 05 Javascript
10个最受欢迎的 JavaScript框架(推荐)
Apr 24 Javascript
解决vuex刷新状态初始化的方法实现
Aug 15 Javascript
基于vue写一个全局Message组件的实现
Aug 15 Javascript
微信小程序实现同时上传多张图片
Feb 03 Javascript
Vue数组响应式操作及高阶函数使用代码详解
Aug 01 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网页游戏学习之Xnova(ogame)源码解读(十)
2014/06/24 PHP
smarty模板引擎使用内建函数foreach循环取出所有数组值的方法
2015/01/22 PHP
前端开发必须知道的JS之原型和继承
2010/07/06 Javascript
JQuery优缺点分析说明
2011/04/10 Javascript
jQuery中读取json文件示例代码
2013/05/10 Javascript
JSON无限折叠菜单编写实例
2013/12/16 Javascript
jquery解析XML字符串和XML文件的方法说明
2014/02/21 Javascript
浏览器窗口大小变化时使用resize事件对框架不起作用的解决方法
2014/05/11 Javascript
javascript禁止超链接跳转的方法
2016/02/02 Javascript
jQuery 更改checkbox的状态,无效的解决方法
2016/07/22 Javascript
JSONP和批量操作功能的实现方法
2016/08/21 Javascript
javascript比较语义化版本号的实现代码
2016/09/09 Javascript
详解node如何让一个端口同时支持https与http
2017/07/04 Javascript
jsTree事件和交互以及插件plugins详解
2017/08/29 Javascript
mongoose更新对象的两种方法示例比较
2017/12/19 Javascript
vue-cli 组件的导入与使用教程详解
2018/04/11 Javascript
JS实现显示当前日期的实例代码
2018/07/03 Javascript
Vue-cli3生成的Vue项目加载Mxgraph方法示例
2020/05/31 Javascript
Vue3新特性之在Composition API中使用CSS Modules
2020/07/13 Javascript
H5 js点击按钮复制文本到粘贴板
2020/11/19 Javascript
[53:52]EG vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
[01:13:51]TNC vs Serenity 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
使用rpclib进行Python网络编程时的注释问题
2015/05/06 Python
pandas 快速处理 date_time 日期格式方法
2018/11/12 Python
Python二叉树的遍历操作示例【前序遍历,中序遍历,后序遍历,层序遍历】
2018/12/24 Python
Python实现图片转字符画的代码实例
2019/02/22 Python
python如何实现异步调用函数执行
2019/07/08 Python
使用python socket分发大文件的实现方法
2019/07/08 Python
Pytorch mask_select 函数的用法详解
2020/02/18 Python
The Hut美国/加拿大:英国领先的豪华在线百货商店
2019/03/26 全球购物
戴森英国官网:Dyson英国
2019/05/07 全球购物
军训心得体会
2013/12/31 职场文书
新春寄语大全
2014/04/09 职场文书
家长通知书家长评语
2014/04/17 职场文书
高等教育学专业自荐书
2014/06/17 职场文书
python实现批量提取指定文件夹下同类型文件
2021/04/05 Python