默认绑定
function foo () {
console.log(this.a)
}
var a = 2
foo() // 2
function foo () {
"use strict";
console.log(this.a)
}
var a = 2
foo() // TypeError: this is undefined
隐式绑定
function foo() {
console.log(this.a)
}
var obj = {
a: 2,
foo,
}
obj.foo() // 2
var obj1 = {
a: 2,
obj2,
}
var obj2 = {
a: 42,
foo
}
obj1.obj2.foo() // 42
var bar = obj.foo
var a = "oops, global"
bar() // "oops, global"
setTimeout(obj.foo, 100) //"oops, global"
显示绑定
function foo(something) {
console.log(this.a, something);
return this.a + something;
}
// 简单辅助函数
function bind(fn, obj) {
return function() {
return fn.apply(obj, arguments)
}
}
var obj = {
a: 2;
}
var bar = bind( foo, obj );
var b = bar(3); // 2 3
console.log(b) // 5
new绑定
- 创建一个全新对象
- 新对象执行原型连接
- 新对象绑定到函数调用的this
- 如果函数没有返回其他对象,那么表达式中的函数调用返回这个新对象
function foo(a) {
this.a = a;
}
var bar = new foo(2)
console.log(bar.a) // 2
忽略this
foo.bind(null, 2)通过null来忽略this绑定可能产生副作用。(比如修改全局变量)
一种更安全方法时绑定一个DMZ(demilitarized zone 非军事区)一个空的非委托对象
function foo(a, b) {
console.log("a: " + a + ", b: " + b);
}
// DMZ对象
var Q = Object.create(null)
foo.apply(Q, [2, 3]) // a: 2, b: 3
var bar = foo.bind(Q, 2)
bar(3) // a: 2, b: 3
软绑定
首先检查调用的this,如果this绑定到全局对象或者undefined,那就把指定的默认对象obj绑定到this,否则不会修改this
if(!Function.prototype.softBind) {
Function.prototype.softBind = function(obj) {
var fn = this;
var crried = [].slice.call(arguments, 1)
var bound = function () {
return fn.apply(
(!this || this === (window || global)) ?
obj : this
curried.concat.aplly(curried, arguments)
);
};
bound.prototype = Object.create(fn.prototype);
return bound;
}
}
function foo() {
console.log("name" + this.name)
}
var obj = {name: "obj"},
obj2 = {name: "obj2"},
obj3 = {name: "obj3"};
var fooOBJ = foo.softBind(obj)
fooOBj() // name: obj
obj2.foo = foo.softBind(obj);
obj2.foo(); // name: obj2
fooOBJ.call(obj3)
setTimeout(obj2.foo, 10);// name: obj软绑定
箭头函数
箭头函数回继承外层函数调用的this绑定(无论this绑定到什么)这个以下相同
function foo() {
var self = this;
setTimeout(function() {
console.log(self.a)
}, 100)
}
var obj = {
a: 2
}
foo.call(obj); // 2