浅谈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代码运行不出来执行错误的可能情况整理
Oct 18 Javascript
js调用打印机打印网页字体总是缩小一号的解决方法
Jan 24 Javascript
js限制文本框只能输入整数或者带小数点的数字
Apr 27 Javascript
《JavaScript高级编程》学习笔记之object和array引用类型
Nov 01 Javascript
JS实现用户注册时获取短信验证码和倒计时功能
Oct 27 Javascript
Node.js  REPL (交互式解释器)实例详解
Aug 06 Javascript
gulp教程_从入门到项目中快速上手使用方法
Sep 14 Javascript
谈谈JS中的!!
Dec 07 Javascript
mongoose更新对象的两种方法示例比较
Dec 19 Javascript
vue微信分享到朋友圈 vue微信发送给好友
Nov 28 Javascript
uni-app 支持多端第三方地图定位的方法
Jan 03 Javascript
JavaScript ES 模块的使用
Nov 12 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
Discuz 5.0 中读取纯真IP数据库函数分析
2007/03/16 PHP
php表单转换textarea换行符的方法
2010/09/10 PHP
微信公众平台接口开发入门示例
2014/12/24 PHP
PHP内核探索:哈希表碰撞攻击原理
2015/07/31 PHP
Laravel框架处理用户的请求操作详解
2019/12/20 PHP
服务器安全设置的几个注册表设置
2007/07/28 Javascript
js弹出模式对话框,并接收回传值的方法
2013/03/12 Javascript
JS上传图片前实现图片预览效果的方法
2015/03/02 Javascript
JavaScript获取表单内所有元素值的方法
2015/04/02 Javascript
javascript正则表达式基础知识入门
2015/04/20 Javascript
JavaScript高级程序设计(第三版)学习笔记6、7章
2016/03/11 Javascript
JS DOMReady事件的六种实现方法总结
2016/11/23 Javascript
js事件源window.event.srcElement兼容性写法(详解)
2016/11/25 Javascript
JS简单获取日期相差天数的方法
2017/04/24 Javascript
详解vue-router 2.0 常用基础知识点之导航钩子
2017/05/10 Javascript
ng-repeat指令在迭代对象时的去重方法
2018/10/02 Javascript
详解Vue的mixin策略
2020/11/19 Vue.js
python使用生成器实现可迭代对象
2018/03/20 Python
Python根据已知邻接矩阵绘制无向图操作示例
2018/06/23 Python
Python爬虫爬取新浪微博内容示例【基于代理IP】
2018/08/03 Python
解决Tensorboard可视化错误:不显示数据 No scalar data was found
2020/02/15 Python
Python实现加密接口测试方法步骤详解
2020/06/05 Python
python 如何引入协程和原理分析
2020/11/30 Python
css3的图形3d翻转效果应用示例
2014/04/08 HTML / CSS
浅析HTML5 meta viewport参数
2020/10/28 HTML / CSS
StubHub巴西:购买和出售您的门票
2016/07/22 全球购物
运动会通讯稿400字
2014/01/28 职场文书
优秀毕业生推荐信范文
2014/03/07 职场文书
总经理秘书岗位职责
2014/03/17 职场文书
推荐信格式范文
2014/05/09 职场文书
本科毕业生求职信
2014/06/15 职场文书
合作意向书
2014/07/30 职场文书
2015年社区统计工作总结
2015/04/21 职场文书
如何写一份具有法律效力的借款协议书?
2019/07/02 职场文书
CSS中em的正确打开方式详解
2021/04/08 HTML / CSS
SpringBoot+Vue+JWT的前后端分离登录认证详细步骤
2021/09/25 Java/Android