bind的原理深度剖析

bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
**语法:**function.bind(thisArg[,arg1[,arg2[, …]]])
返回一个原函数的拷贝,并拥有指定的this值和初始参数。
bind 方法与 call / apply 最大的不同就是前者返回一个绑定上下文的函数,而后两者是直接执行了函数。

var value = 2;

var foo = {
    value: 1
};

function bound (name: string, age: number) {
    return {
        value: this.value,
        name: name,
        age: age
    }
};

bound.call(foo, "Jack", 20); // 直接执行了函数,并修改了this指向
// {value: 1, name: "Jack", age: 20}

var bindFoo1 = bound.bind(foo, "Jack", 20); // 返回一个函数
bindFoo1();
// {value: 1, name: "Jack", age: 20}

var bindFoo2 = bound.bind(foo, "Jack"); // 返回一个函数
bindFoo2(20);
// {value: 1, name: "Jack", age: 20}`在这里插入代码片`

bind特性:
1.返回一个新函数
2.可以指定this
3.可以传入参数
4.柯礼化
使用场景

**var nickname = "Kitty";
function Person(name){
    this.nickname = name;
    this.distractedGreeting = function() {

        setTimeout(function(){
            console.log("Hello, my name is " + this.nickname);
        }.bind(this), 500);
    }
}
 
var person = new Person('jawil');
person.distractedGreeting();
// Hello, my name is jawil**

柯里化(curry)
只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
可以一次性地调用柯里化函数,也可以每次只传一个参数分多次调用。

var add = function(x) {
  return function(y) {
    return x + y;
  };
};

var add = function(x) {
	return function(y) {
		return x+y
	}
}
var increment = add(1);
var addTen = add(10)

var increment = add(1);
var addTen = add(10);

increment(2);
// 3

addTen(2);
// 12

add(1)(2);
// 3`

模拟实现
bind() 函数在 ES5 才被加入,所以并不是所有浏览器都支持,IE8及以下的版本中不被支持,如果需要兼容可以使用 Polyfill 来实现。
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
// 第一版

Function.prototype.bind2 = function(context) {
	var self = this;
	return funciton() {
		return self.apply(context)
	}
}
Funciton.prototype.bind2 = function(context) {
    var self= this;
    var args = Array.prototype.slice.call(arguments, 1);
    return function() {
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(context, args.concat(bindArgs))
    }
}

一个绑定函数也能使用new操作符创建对象:

这种行为就像把原函数当成构造器,提供的 this 值被忽略,
同时调用时的参数被提供给模拟函数。

var value = 2;
var foo = {
    value: 1
}
function bar(name, age) {
    this.habit = 'shopping';
    conosle.log(this.value);
    console.log(name);
    console.log(age);
}
bar.prototype.friend = 'kevin';
var bindFoo = bar.bind(foo, 'jack');
var obj = new bindFoo(20);
//undefine jack 20
Function.prototype.bind2 = function(context) {
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);
    var fBound = function() {
        var bindArgs = Array.proottype.slice.call(arguments);
        return self.apply(
            this instanceof fBound ? this : context,
            args.concat(bindArgs)
        )
    };
    fBound.prototype = this.prototype;
    return fBound;
}
Function.prototype.bind2 = function(context) {
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1)
    var fBound = function() {
        var bindArgs = Array.prototype.slice.call(argumnents),
        return self.apply(
            this instanceof fBound ? this : context,
            args.concat(bindArgs)
        )
    }
    fBound.prototype = this.protoyep;
    return fBound;
}
Function.prototype.bind2 = function(context) {
    if (typeof this !== "funciton") {
        threw new Error("Function.prototype.bind-what istryinf to be found is not callable");
    }
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1)
    var fNOP = function() {};
    var fBound = function() {
        var bindArgs = Array.prototype.slice.call(argumnents);
        return self.apply(
            this instanceof fNOP ? this : context,
            args.concat(bindArgs)
        )
    }
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    (fBound.prototype = object.create(this.prototype))
    return fBound;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值