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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章