这是三个常用的操作函数的方法,在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 是闭包的变量。

最新文章

  1. win2008R2 下解决关于mysql odbc无法正常工作问题
  2. DevExpress ASPxSplitter ClientSideEvents-PaneExpanded 时间用法
  3. css整理-03 文本
  4. Head First 设计模式 --8 模板方法模式 别找我,我会找你
  5. @SuppressWarnings
  6. centos6 下安装xfce+vnc
  7. UVALive 6525
  8. JRE下的rt.jar、tools.jar
  9. MyBatis(3.2.3) - Cache
  10. C# 日期转换函数
  11. Oracler读取各种格式的相关日期格式
  12. getline(cin,s) bug workaround
  13. 小猪猪C++笔记基础篇(四)数组、指针、vector、迭代器
  14. Navigation Controller 创建方法
  15. 1.1 PCI总线的组成结构
  16. bzoj1926[Sdoi2010]粟粟的书架 二分 主席树
  17. RNA-seq标准化
  18. netty解码器详解(小白也能看懂!)
  19. PostgreSQL 问题总结
  20. C++_调用约束

热门文章

  1. 【转】SQL数据库日志文件收缩
  2. PHP设置凌晨时间戳
  3. CentOS7系统上的GPSTK示例代码调试 & 运行结果 & 心得
  4. MySQL—增删改查,分组,连表,limit,union,alter,排序,去重
  5. C#如何在生成文件夹或者文件时候自动重命名
  6. [BZOJ1596]电话网络
  7. ios打包unity应用以及配置签名
  8. Miller Robbin测试模板(无讲解)
  9. bash配色
  10. 第十节 集合类Collection和Map