浅谈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 相关文章推荐
最近项目写了一些js,水平有待提高
Jan 31 Javascript
防止页面被iframe(兼容IE,Firefox火狐)
Jul 04 Javascript
怎样在JavaScript里写一个swing把数据插入数据库
Dec 10 Javascript
JavaScript中匿名、命名函数的性能测试
Sep 04 Javascript
js获取当前日期前七天的方法
Feb 28 Javascript
js实现带关闭按钮始终显示在网页最底部工具条的方法
Mar 02 Javascript
详解原生JavaScript实现jQuery中AJAX处理的方法
May 10 Javascript
angular2中router路由跳转navigate的使用与刷新页面问题详解
May 07 Javascript
浅谈react前后端同构渲染
Sep 20 Javascript
vue实现图片加载完成前的loading组件方法
Feb 05 Javascript
Vue.js 无限滚动列表性能优化方案
Dec 02 Javascript
2019最新21个MySQL高频面试题介绍
Feb 06 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
咖啡与牛奶
2021/03/03 冲泡冲煮
Ajax PHP 边学边练 之三 数据库
2009/11/26 PHP
thinkphp多表查询两表有重复相同字段的完美解决方法
2016/09/22 PHP
漂亮的仿flash菜单,来自蓝色经典
2006/06/26 Javascript
发两个小东西,ASP/PHP 学习工具。 用JavaScript写的
2007/04/12 Javascript
随鼠标上下滚动的jquery代码
2013/12/05 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 图片库
2015/01/09 Javascript
浅谈Javascript线程及定时机制
2015/07/02 Javascript
Bootstrap多级导航栏(级联导航)的实现代码
2016/03/08 Javascript
使用jQuery的ajax方法向服务器发出get和post请求的方法
2017/01/13 Javascript
移动端使用localResizeIMG4压缩图片
2017/04/22 Javascript
jQuery实现鼠标滑过预览图片大图效果的方法
2017/04/26 jQuery
微信小程序wx:for和wx:for-item的用法详解
2018/04/01 Javascript
select2 ajax 设置默认值,初始值的方法
2018/08/09 Javascript
基于js Canvas实现二次贝塞尔曲线
2018/12/25 Javascript
Vue组件为什么data必须是一个函数
2020/06/11 Javascript
Django admin美化插件suit使用示例
2017/12/12 Python
python kmeans聚类简单介绍和实现代码
2018/02/23 Python
python3 flask实现文件上传功能
2020/03/20 Python
Python多进程与服务器并发原理及用法实例分析
2018/08/21 Python
对Python3中bytes和HexStr之间的转换详解
2018/12/04 Python
Python实现的拉格朗日插值法示例
2019/01/08 Python
python爬虫基础教程:requests库(二)代码实例
2019/04/09 Python
简单的Python调度器Schedule详解
2019/08/30 Python
python实现飞船游戏的纵向移动
2020/04/24 Python
html5 Canvas画图教程(6)—canvas里画曲线之arcTo方法
2013/01/09 HTML / CSS
求职推荐信
2013/10/28 职场文书
工程建设实施方案
2014/03/14 职场文书
父母寄语大全
2014/04/12 职场文书
村党的群众路线教育实践活动总结材料
2014/10/31 职场文书
停水通知
2015/04/16 职场文书
2015小学新教师个人工作总结
2015/10/14 职场文书
详解Vue router路由
2021/11/20 Vue.js
MySQL sql模式设置引起的问题
2022/05/15 MySQL
字节飞书面试promise.all实现示例
2022/06/16 Javascript
MySQL新手入门进阶语句汇总
2022/09/23 MySQL