用call或bind实现bind()
一、bind方法
让我们看一下MDN上对bind方法的解释
bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
也就是说,bind()方法会:
- 创建一个新的函数(这也是它和call、apply不同的点)
- 创建的函数接收bind的第二个及以后的参数作为自己的参数
那bind创建的这个新函数还有其他什么特性吗?
调用绑定函数时作为
this参数传递给目标函数的值。 如果使用new运算符构造绑定函数,则忽略该值。
举个下面的例子:由bind创建的新函数bindFoo作为构造函数时,其创建的实例newBindFoo并不指向bindFoo绑定的obj,而是指向bindFoo。
var obj={
name:"Melody"
}
var name="huyang"
function foo(tel){
console.log(this.name)
console.log(tel)
}
var bindFoo=foo.bind(obj,"110")
bindFoo()
//Melody
//
var newbindFoo=new bindFoo();
//undefinde
//
二、现在可以尝试用call实现bind啦
先实现前两个特性,用call模拟bind绑定this,并且对arguments进行分割处理实现其余参数传递
Function.prototype.bind2 = function (context) {
var self = this;
var args=Array.prototype.slice.call(arguments,1)//模拟bind时的传参
return function () {
var bindArgs=Array.prototype.slice(arguments)//模拟执行bind的返回函数时的传参
self.apply(context,args.concat(bindArgs));//修改返回函数的this指向为context,并将bind时和执行bind的返回函数传入的参数concat后绑定给返回函数。
}
}
修改返回函数的作用域链,使其指向绑定函数,这样返回函数生成的实例就可以继承绑定函数的原型啦。
Function.prototype.bind2 = function (context) {
var self = this;
var args=Array.prototype.slice.call(arguments,1)//模拟bind时的传参
var foo=function() {
var bindArgs=Array.prototype.slice(arguments)//模拟执行bind的返回函数时的传参
self.apply(this instanceof self ? this : context, args.concat(bindArgs));
// 由于下方修改返回函数的prototype为绑定函数的prototype,当返回函数作为构造函数使用时,实例this instanceof self必定为真(instanceof判断的底层原理实际上就是根据原型链判断的)
// 当作为普通函数时,this 指向 window,self 指向绑定函数,此时结果为 false,当结果为 false 的时候,this 指向绑定的 context
}
foo.prototype=this.prototype
return foo
}
需要注意的点:
arguments只是具有length属性且可以通过index读取的类数组对象,并没有slice等数组方法,要想对arguments使用数组方法必须得将arguments转换为真正的数组。故,使用Array.prototype.slice.call(arguments),对Array原型链中的slice方法调用call(或apply),传入arguments作为其上下文,然后返回arguments转换后的数组。
用call或bind实现bind()的更多相关文章
- 山寨一个std::bind\boost::bind
这里是最初始的版本,参考https://github.com/cplusplus-study/fork_stl/blob/master/include/bind.hpp 提供了最简洁的实现方式. 第一 ...
- 解决bind错误 bind: Address already in use
关于bind错误的处理: bind: Address already in use 原因: 操作系统没有立即释放端口 解决一: 等待一段时间运行网络程序即可 解决二:通过setsockopt进行设置, ...
- JS核心系列:浅谈 call apply 与 bind
在JavaScript 中,call.apply 和 bind 是 Function 对象自带的三个方法,这三个方法的主要作用是改变函数中的 this 指向,从而可以达到`接花移木`的效果.本文将对这 ...
- 【Win10】UAP/UWP/通用 开发之 x:Bind
[Some information relates to pre-released product which may be substantially modified before it's co ...
- jQuery 中bind(),live(),delegate(),on() 区别(转)
当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...
- 转 jQuery 中bind(),live(),delegate(),on() 区别
当我们试图绑定一些事件到DOM元素上的时候,我相信上面这4个方法是最常用的.而它们之间到底有什么不同呢?在什么场合下用什么方法是最有效的呢? 准备知识: 当我们在开始的时候,有些知识是必须具备的: D ...
- 深入浅出 妙用Javascript中apply、call、bind
apply.call 在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向. Jav ...
- 【优雅代码】深入浅出 妙用Javascript中apply、call、bind
这篇文章实在是很难下笔,因为网上相关文章不胜枚举. 巧合的是前些天看到阮老师的一篇文章的一句话: “对我来说,博客首先是一种知识管理工具,其次才是传播工具.我的技术文章,主要用来整理我还不懂的知识.我 ...
- 背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合
[源码下载] 背水一战 Windows 10 (22) - 绑定: 通过 Binding 绑定对象, 通过 x:Bind 绑定对象, 通过 Binding 绑定集合, 通过 x:Bind 绑定集合 作 ...
随机推荐
- Python|队列Queue
一 前言 本文算是一次队列的学习笔记,Queue 模块实现了三种类型的队列,它们的区别仅仅是队列中元素被取回的顺序.在 FIFO 队列中,先添加的任务先取回.在 LIFO 队列中,最近被添加的元素先取 ...
- Java虚拟机一看就懂01
Jvm内存结构 --- 线程隔离区域说明: 1.1.程序计数器 线程私有 是一块内存空间 唯一的一个在Java虚拟机规范中没有规定任何OOM情况的区域(不会OOM?) 1.2.Java虚拟机栈 线程私 ...
- 90002CAD相关操作
第一章 初识CAD 1.1 CAD能干什么 (1)绘制机械图/建筑图/装修图等二维复杂工程图的不二之选.二维设计软件的王者. (2)CAD可以绘制平面图.轴测图(二维线框表示三维图形).立体图(三 ...
- MSIL实用指南-生成内部类
生成内部类用TypeBuilder的DefineNestedType方法,得到另一个TypeBuilder.内部类的可访问性都是TypeAttributes的“Nested”开头一些成员.实例代码:y ...
- 从Linux服务器下载上传文件
首先要确定好哪两种的连接:Linux常用的有centors和unbantu两种版本,PC端Mac和Windows 如果在两个Linux之间传输,或Linux和Mac之间传输可以使用scp命令,类似于s ...
- HTML(四)图像,表格
HTML 图像 插入动图的语法和静态图的语法是一样的 HTML 图像- 图像标签( )和源属性(Src) 一个来自文件夹中的图像: 一个来自网站的图像: alt 属性用来为图像定义一串预备的可替换的文 ...
- Spring Cloud开发人员如何解决服务冲突和实例乱窜?(IP实现方案)
一.背景 在我上一篇文章<Spring Cloud开发人员如何解决服务冲突和实例乱窜?>中提到使用服务的元数据来实现隔离和路由,有朋友问到能不能直接通过IP来实现?本文就和大家一起来讨论一 ...
- 现代 JavaScript 教程到底是什么?
手册与规范 <现代 JavaScript 教程>是开源的现代 JavaScript 从入门到进阶的优质教程,它旨在帮助你逐渐掌握 JavaScript 这门语言.但是一旦你已经熟悉了这门语 ...
- c++拷贝构造函数引用传参
看一道C++面试题: 给出下述代码,分析编译运行的结果,并提供3个选项: A.编译错误 B.编译成功,运行时程序崩溃 C.编译运行正常,输出10 class A { private: int va ...
- python自学Day02(自学书籍python编程从入门到实践)
第三章 列表简介 3.1 列表是什么 按特定顺序排列的元素组成. 元素类型可以是任意数据类型. 元素之间没有任何的关系. 在python中用中括号 [] 括起来并用 ,号隔开 3.1.1 访问列表元素 ...