call,apply,bind 方法的学习
这是三个常用的操作函数的方法,在js中函数就是一等公民,所以说掌握这三个方法还是有必要的
call 和 apply,都会绑定函数的上下文(context)并立即执行调用该方法函数,两者区别在于,接受的参数格式不一样。
call 接收的参数形式是: (context,arg1,arg2,ar3....) // argn 是一个个具体的参数
apply 接收的参数形式是: (context,argArr) // argArr 可以是一个有参数组成的数组或者arguments
bind 会返回绑定调用该方法的函数上下文的新的函数。
1.call的示例
var a = {
name: 'aa',
getName: function(age) {
return this.name + ',' + age;
}
};
var b = {
name: 'bbb'
};
a.getName.call(b,23) // bbb,23
1.用call实现apply
现在的我能想到的办法就是通过eval对参数进行拼接,因为函数底层操作参数的方法没有暴露(可能不知道吧)
代码示例
这里先看下一个eval作用域的事情,经过测试eval方法获取变量也是在划分作用域的,并不是从全局获取,示例:
(function () {
var me = {name: '33'};
console.log(eval('me')); // 33
})();
这样我们就能拿到函数原来的上下文
用call实现apply
// 用个low的办法实现apply
Function.prototype.fakeApply = function (context,arguments) {
// 拼接参数
var arg;
// 如果有参数将参数转换成数组
if(arguments){
arg = [].slice.call(arguments,0);
// 将数组拼接成字符串格式 -> arg1,arg2,arg3,...
arg = arg.join(',');
}
var excuteStr = 'this.call(context' + (arg ?',' + arg : '' ) + ')'; // this.call(context,2,3,4)
console.log(eval('this.call(context' + (arguments ?',' + [].slice.call(arguments,0).join(',') : '' ) + ')'));
// { name: 44 }
// { '0': 2, '1': 3, '2': 4 }
// ok
};
var a = {
name: 'aa',
getName: function() {
console.log(this);
console.log(arguments);
return 'ok';
}
};
a.getName.fakeApply({name:44},[2,3,4]);
为了加深bind理解,下面是用apply实现bind的示例
Function.prototype.fakeBind = function () {
// bind 有可能会传入绑定的参数
var prevFun = this;
var context = arguments[0];
var prevArg = arguments.length > 1 ? [].slice.call(arguments,1) : [] ;
return function () {
var curArg = [].concat.apply(prevArg,arguments);
return prevFun.apply(context,curArg);
};
};
var fun1 = function () {
console.log(this);
console.log(arguments);
};
var fun2 = fun1.fakeBind({name: 'aaa'},2,3);
fun2(4,5);
// { name: 'aaa' }
// { '0': 2, '1': 3, '2': 4, '3': 5 }
返回了一个新的函数,函数中的prevFun和preArg 是闭包的变量。
call,apply,bind 方法的学习的更多相关文章
- JavaScript内置一些方法的实现原理--new关键字,call/apply/bind方法--前戏
new关键字,call/apply/bind方法都和this的绑定有关,在学习之前,首先要理解this. 一起来学习一下this吧 首先.this是一个对象. 对象很好理解,引用类型值,可以实现如th ...
- JS 的 call apply bind 方法
js的call apply bind 方法都很常见,目的都是为了改变某个方法的执行环境(context) call call([thisObj[,arg1[, arg2[, [,.argN]]]] ...
- JavaScript中call,apply,bind方法的区别
call,apply,bind方法一般用来指定this的环境. var a = { user:"hahaha", fn:function(){ console.log(this.u ...
- javascript中的call(),apply(),bind()方法的区别
之前一直迷惑,记不住call(),apply(),bind()的区别.不知道如何使用,一直处于懵懂的状态.直到有一天面试被问到了这三个方法的区别,所以觉得很有必要总结一下. 如果有不全面的地方,后续再 ...
- JavaScript内置一些方法的实现原理--new关键字,call/apply/bind方法--实现
先学习下new操作符吧 new关键字调用函数的心路历程: 1.创建一个新对象 2.将函数的作用域赋给新对象(this就指向这个对象) 3.执行函数中的代码 4.返回这个对象 根据这个的思路,来实现一个 ...
- JavaScript中call,apply,bind方法的总结。
why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...
- call,apply,bind方法的总结
why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之前,通常会有这些问题. var a = { user:"追梦子", fn:f ...
- JavaScript中call,apply,bind方法的总结
原文链接:http://www.cnblogs.com/pssp/p/5215621.html why?call,apply,bind干什么的?为什么要学这个? 一般用来指定this的环境,在没有学之 ...
- call, apply,bind 方法解析
call(), apply(),bind() 三者皆为Function的方法 call(),apply()的作用是调用方法,并改变函数运行时的context(作用上下文) bind() 的作用是引用方 ...
随机推荐
- 新建项目找不到android studio:appcompat v7:27.+包。
1.我们在build.gradle(project)中添加maven中的google库: allprojects { repositories { jcenter() maven { url &quo ...
- I2C 上拉电阻选择计算公式
I2C接口上拉电阻的选择 - I2C接口上拉电阻的选择 1.I2C接口的输出端是漏极开路或集电极开路,所以必须在接口外接上拉. 2.上拉电阻的范围很宽,但也需要跟据功耗.信号上升时间等具体确定. 和速 ...
- 19_04_19校内训练[Game]
题意 给出n,等概率地生成一个1~n的数列.现在有n个人从左到右站成一排,每个人拿有当前数列位置上的数字,并且一开始都不知道数字是多少(但知道n是多少).从左到右让每个人进行如下选择: 1.选择保留自 ...
- HFun.快速开发平台(三)=》通用系统用户选择
系统中用户的选择使用特别多,将该功能统一实现可提升系统效率. 用户的选择实现相对简单,系统中基本都会提供,HFun.快速开发平台中的实现特点主要有: 1.用户的选择分为单用户选择和多用户选择. 2.用 ...
- 辗转相除法(GCD)求左旋转字符串
本文写于2017-01-18,从老账号迁移到本账号,原文地址:https://www.cnblogs.com/huangweiyang/p/6297874.html 今天在牛客网上做了一道题,题意就是 ...
- Ubuntu16.04 ionic(jdk,sdk,gradle)环境搭建完全攻略
在Ubuntu16.04当中搭建一个ionic环境还是按照官方教程的来,主要问题是首先要把JDK,SDK搭好,环境变量配好.本文中给的包的下载请不要直接用浏览器下载,很慢,尽量用wget 下载,重要的 ...
- maven的依赖特性
若排版紊乱可查看我的个人博客原文地址 maven的依赖特性很多很杂,这里大概总结一下,maven的依赖特性主要是依赖范围和传递依赖,前者会影响后者,这篇文章会介绍传递依赖的传递原则,出现冲突传递依赖默 ...
- 第一章04:JDK与JRE 区别
JDK = 开发工具 JRE = 运行程序 跨平台性 java程序 = 可以在任何系统中运行(不分系统) JVM = java虚拟机(不同系统下载不一样的JDK版本)(安装的时候包含在jre里面)
- mybatis(二)
一级缓存和二级缓存 mybatis一二级缓存测试实例: package com.atguigu.mybatis.test; import java.io.IOException; import jav ...
- Java String 常量池理解
String:字符串常量池 作为最基础的引用数据类型,Java 设计者为 String 提供了字符串常量池以提高其性能,那么字符串常量池的具体原理是什么,我们带着以下三个问题,去理解字符串常量池: 字 ...