if(!Function.prototype.bind){

  Function.prototype.bind = function(oThis){

    if(typeof this !=="function"){ //如果不函数抛出异常

      throw new TyperError("")

    }

    var aArgs = Array.prototype.slice.call(arguments,1),   //此处的aArgs是除函数外的参数

      fToBind = this,                  //要绑定的对象

      fNOP = function(){},

      fBound = function(){

        return fToBind.apply(

          this instanceof fNOP ? this:oThis||this,aArgs.concat(Array.prototype.slice.call(arguments)));

          )

      };

    fNOP.prototype = this.prototype;

    fBound.prototype = new fNOP();

    return  fBound;

  }

}

明白 bind 的用法就必须要知道 apply 的用法,MDN 指出,apply 是直接修改了函数内部的指向到第一个参数,并将第二个参数数组传参进函数并运行这个函数。也就是说

var obj = {test: function() { console.log(this, arguments) }},
func = obj.test; obj.test("Hello", ",", "world", "!");
func.apply(obj, ["Hello", ",", "world", "!"]);

这两种运行方式是一样的。那么回到 Polyfill 中发现参数的写法是 args.concat(slice.call(arguments))args 是将 bind时候定义的除第一个参数外的其它参数,而此时的 arguments 是指函数调用时候的参数,通过数组的操作将这两个参数合并成一个数组传入函数内部。看个例子你可能更容易明白:

/** 代码接上 **/
var newFunc = func.bind(obj, "Hello", ",");
newFunc("world", "!");

那么再来回答问题一,这个是典型的属性继承的方法,本来使用

bound.prototype = self.prototype

就可以将原属性集成过来了,但是这样两个对象属性都指向同一个地方,修改 bound.prototype 将会造成 self.prototype也发生改变,这样并不是我们的本意。所以通过一个空函数 nop 做中转,能有效的防止这种情况的发生。

bind返回的是函数

if (!Function.prototype.bind) {
Function.prototype.bind = function(obj) {
var _self = this
,args = arguments;
return function() {
_self.apply(obj, Array.prototype.slice.call(args, 1));
}
}
}

手写Function.bind函数的更多相关文章

  1. 依据ECMA规范,手写一个bind函数

    Function.prototype.bind 函数,参见ECMA规范地址 如题,这次来实现一个boundFunction函数,不挂载在Function.prototype上,而是一个单独声明的函数. ...

  2. 手写简化版printf函数

    2019.02.01更新:经同学提醒,myprintf函数应有返回值为输出的字符数. 期末的大作业,手写一个myprintf函数,支持如下一些操作. 也就是  % -(负号控制左右对齐) 数(控制字段 ...

  3. 手写事件代理函数 (Delegated function)

    ‘手写 ’ 这个词 ,面试是不是听过无数遍呢 ! 今天我们来手写一个这样的事件委托函数 => function( parent, selector, type ,  handle)  {} 你需 ...

  4. 前端面试手写代码——JS函数柯里化

    目录 1 什么是函数柯里化 2 柯里化的作用和特点 2.1 参数复用 2.2 提前返回 2.3 延迟执行 3 封装通用柯里化工具函数 4 总结和补充 1 什么是函数柯里化 在计算机科学中,柯里化(Cu ...

  5. 【OpenCV学习笔记】之六 手写图像旋转函数---万丈高楼平地起

    话说,平凡之处显真格,这一点也没错!  比如,对旋转图像进行双线性插值,很简单吧?  可,对我,折腾了大半天,也没有达到预期效果!  尤其是三个误区让我抓瞎好久: 1,坐标旋转公式.   这东西,要用 ...

  6. cs224d 作业 problem set2 (一) 用tensorflow纯手写实现sofmax 函数,线性判别分析,命名实体识别

    Hi Dear Today we will use tensorflow to implement the softmax regression and linear classifier algor ...

  7. 手写map, filter函数

    function map(arr, fn) { let newArr = []; for (let i = 0; i < arr.length; i++) { newArr[i] = fn(ar ...

  8. 手写一个bind

    1 Function.prototype.bind1 = function(){ 2 // 将类数组转化成数组 3 let arr = Array.prototype.slice.call(argum ...

  9. 前端面试手写代码——call、apply、bind

    1 call.apply.bind 用法及对比 1.1 Function.prototype 三者都是Function原型上的方法,所有函数都能调用它们 Function.prototype.call ...

随机推荐

  1. 如何利用开源思想开发一个SEO友好型网

    如果你有一个网站需要去做SEO优化的时候,不要期望你的努力能立即得到回报.耐心等待并更正内容营销策略,最终会发现你的网站很受用户欢迎.下面就教你如何利用开源思维开发一个SEO友好型网站! 首先,你应该 ...

  2. java中 ++a 与 a++ 的区别

    public static void main(String[] args) { int a = 5; a ++; System.out.println(a); int b = 5; ++ b; Sy ...

  3. ElasticJob-分布式作业调度神器,你们还在用Quartz吗?!

    简介 Elastic-Job是一个分布式调度解决方案,由两个相互独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成. Elastic-Job-Lite定位为轻量级无中 ...

  4. 19.SimLogin_case04

    # 利用cookies登录马蜂窝 import requests from lxml import etree session = requests.Session() phone_number = ...

  5. Mysql之DQL------基础查询

    #笔记内容来自于B站尚硅谷教学视频(av49181542)use myemployees; 查询表中的单个字段 SELECT last_name FROM employees; 查询表中的多个字段 # ...

  6. 12-5-上下文this

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. Django static静态配置文件

    对于Django来说静态文件一般交由Web服务器处理,Django本身不处理静态文件.为了使Django开发环境能够处理静态文件,Django有和生产环境不同的静态文件配置方式. Django 版本: ...

  8. mysql 表查询结果 总行数计算

    一般的查询语句是这样的 SELECT  id,name FROM SystemEvents WHERE  1=1 limit 9,10 SELECT  * FROM SystemEvents WHER ...

  9. leetcode-95-不同的二叉搜索树(卡特兰数)

    题目描述: 方法一:动态规划 O(n^2) O(n) class Solution: def numTrees(self, n: int) -> int: dp = [0]*(n+1) dp[0 ...

  10. phpstorm中完成一键快速注释函数头

    先保存函数,再在函数头写/**+enter就行了 /** * @param $num1 * @param $num2 * @param $opt * @return float|int */ func ...