function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
}
obj.foo();// 2
var bar = obj.foo;
var a = "oops, global";
bar();// oops, global
function foo() {
console.log(this.a);
}
function doFoo() {
foo();
}
var obj = {
a: 2,
foo: foo
}
var a = "oops, global";
doFoo(obj.foo);// oops, global
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
}
var a = "oops, global";
obj.foo();// 2
setTimeout(obj.foo,100);// oops, global
// 等同于var bar = obj.foo;传递了bar给timeout其内调用bar()此时的调用者是window
setTimeout(function(){
obj.foo();// 2
},200);// oops, global
明确绑定(Explicit Binding)
call,apply,bind
function foo() {
console.log(this.a);
}
var obj = {
a: 2
}
var a = "oops, global";
foo();// oops, global
foo.call(obj)// 2
硬绑定(Hard Binding)
function foo() {
console.log(this.a);
}
var obj = {
a: 2
}
var bar = function(){
foo.call(obj);
}
bar();// 2
setTimeout(bar,100);// 2
// `bar`将`foo`的`this`硬绑定到`obj`
// 所以它不可以被再被覆盖
bar.call(window);// 2
bind由来
function foo(something) {
console.log(this.a,something);
return this.a + something;
}
var obj = {
a: 2
}
var bar = function(){
return foo.apply(obj,arguments);
}
var b = bar(3);// 2 3
console.log(b);// 5
function foo(something) {
console.log(this.a,something);
return this.a + something;
}
// 简单的`bind`帮助函数(提取封装)
function bind(fn,obj){
return function(){
return foo.apply(obj,arguments);
}
}
var obj = {
a: 2
}
var bar = bind(foo,obj);
var b = bar(3);// 2 3
console.log(b);// 5
/**
*由于 硬绑定 是一个如此常用的模式,它已作为ES5的内建工具提供:Function.prototype.bind,像这样使用
*/
function foo(something) {
console.log(this.a,something);
return this.a + something;
}
var obj = {
a: 2
}
var bar = foo.bind(obj);// 它已作为ES5的内建工具提供:Function.prototype.bind
var b = bar(3);// 2 3
console.log(b);// 5
new绑定(new Binding)
function foo(something) {
this.a = something;
}
var obj1 = {
foo: foo
}
var obj2 = {};
obj1.foo(2);
console.log(obj1.a);// 2
obj1.foo.call(obj2,3);
console.log(obj2.a);// 3
var bar = new obj1.foo(4);
console.log(obj1.a);// 2
console.log(bar.a);// 4 new绑定 的优先级要高于 隐含绑定
function foo(something) {
this.a = something;
}
var obj1 = {}
var bar = foo.bind(obj1);
bar(2);
console.log(obj1.a);// 2
var baz = new bar(3);
console.log(obj1.a);// 2
console.log(baz.a);// 3
/**
* bar是硬绑定到obj1的,但是new bar(3)没有想我们期待的那样将obj1.a变为3。
* 反而,硬绑定(到obj1)的bar(..)调用 可以 被new所覆盖。
* 因为new被实施,我们得到一个名为baz的新创建的对象,而且我们确实看到baz.a的值为3
*/
new可以覆盖 硬绑定
function foo(a,b){
console.log("a:"+a+",b:"+b);
}
// 将数组散开作为参数
foo.apply(null,[2,3]);// a:2, b:3
// 用`bind(..)`进化柯里化
var bar = foo.bind( null,2 );
bar( 3 );// a:2, b:3
间接引用
function foo(){
console.log(this.a);
}
var a=2;
var o={a:3,foo:foo};
var p = {a:4};
o.foo();// 3
(p.foo = o.foo)();// 2
/**
* 赋值表达式p.foo = o.foo的 结果值 是一个刚好指向底层函数对象的引用
*/
p.foo();// 4