浅谈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 相关文章推荐
菜单效果
Oct 14 Javascript
javascript-TreeView父子联动效果保持节点状态一致
Aug 12 Javascript
jquery实现带二级菜单的导航示例
Apr 28 Javascript
JS实现可直接显示网页代码运行效果的HTML代码预览功能实例
Aug 06 Javascript
纯JavaScript代码实现移动设备绘图解锁
Oct 16 Javascript
微信小程序实现留言板功能
Nov 02 Javascript
Koa日志中间件封装开发详解
Mar 09 Javascript
详解微信小程序开发(项目从零开始)
Jun 06 Javascript
react MPA 多页配置详解
Oct 18 Javascript
vue中英文切换实例代码
Jan 21 Javascript
Vue3新特性之在Composition API中使用CSS Modules
Jul 13 Javascript
解决vuex数据页面刷新后初始化操作
Jul 26 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中对数据库操作的封装
2006/10/09 PHP
php magic_quotes_gpc的一点认识与分析
2008/08/18 PHP
php实现猴子选大王问题算法实例
2015/04/20 PHP
PHP实现随机生成水印图片功能
2017/03/22 PHP
PHP使用PDO操作sqlite数据库应用案例
2019/03/07 PHP
PHP面向对象程序设计之对象克隆clone和魔术方法__clone()用法分析
2019/06/12 PHP
js计算两个时间之间天数差的实例代码
2013/11/19 Javascript
七个很有意思的PHP函数
2014/05/12 Javascript
编程语言JavaScript简介
2014/10/16 Javascript
jQuery事件绑定和委托实例
2014/11/25 Javascript
jquery实现无刷新验证码的简单实例
2016/05/19 Javascript
Javascript中作用域的详细介绍
2016/10/06 Javascript
jsTree使用记录实例
2016/12/01 Javascript
AngularJS ionic手势事件的使用总结
2017/08/09 Javascript
浅谈Vue SSR中的Bundle的具有使用
2019/11/21 Javascript
jQuery实现穿梭框效果
2021/01/19 jQuery
python实现的解析crontab配置文件代码
2014/06/30 Python
python getopt详解及简单实例
2016/12/30 Python
python装饰器-限制函数调用次数的方法(10s调用一次)
2018/04/21 Python
基于python绘制科赫雪花
2018/06/22 Python
Python中按值来获取指定的键
2019/03/04 Python
Python Django基础二之URL路由系统
2019/07/18 Python
Python接口开发实现步骤详解
2020/04/26 Python
柯基袜:Corgi Socks
2017/01/26 全球购物
印度在线内衣和时尚目的地:Zivame
2017/09/28 全球购物
联想法国官方网站:Lenovo法国
2018/10/18 全球购物
Huda Beauty官方商店:化妆和美容产品
2020/09/05 全球购物
总经理岗位职责范本
2014/02/02 职场文书
十八届三中全会学习方案
2014/02/16 职场文书
涉外离婚协议书怎么写
2014/11/20 职场文书
2015年大学生工作总结
2015/04/21 职场文书
让人感觉高大上的讲话稿怎么写?
2019/07/08 职场文书
话题作文之诚信
2019/11/28 职场文书
简述python四种分词工具,盘点哪个更好用?
2021/04/13 Python
解决Go gorm踩过的坑
2021/04/30 Golang
MySQL系列之十五 MySQL常用配置和性能压力测试
2021/07/02 MySQL