1 this绑定和函数声明的位置没有任何关系,只取决于函数的调用位置。
2 this和词法作用域的查找混合使用时,无法实现
function foo() { var a=2; this.bar(); } function bar() { console.log(this.a); } foo();//undefined
3 默认绑定
指向全局对象;函数直接使用不带任何修饰的函数引用进行调用的,只能使用默认绑定。
4 隐式绑定
- 当函数引用有上下文对象时,会把函数调用的this绑定到这个上下文对象。
-
对象属性引用链只有上一层或者说最后一层调用位置中起作用。
function foo() { console.log(this.a); } var obj2={ a:42, foo:foo } var obj1={ a:2, obj2:obj2 } obj1.obj2.foo(); //42
-
隐式丢失
function foo() { console.log(this.a); } var obj={ a:2, foo:foo } var bar=obj.foo; var a="1"; bar(); // 1
bar是obj.foo的一个引用,引用的是foo函数本身,因此此时的bar()其实是一个不带任何修饰符的函数调用,因此用了默认绑定。
回调函数
function foo() { console.log(this.a); } function doFoo(fn) { fn(); } var obj={ a:2, foo:foo } var a="1"; doFoo(obj.foo);// 1
参数传递其实就是一种隐式赋值,所以返回1
5 显式绑定 call()/apply()
硬绑定:
function foo() { console.log(this.a); } var obj={ a:2, } var bar=function() { foo.call(obj); } bar();// 2 bar.call(window); //2 硬绑定后不能再修改它的this
创建函数bar(),并在内部调用 foo.call(obj),因此强制把foo的this绑定到obj,之后调用bar,总会手动在obj上调用foo,这种绑定称为硬绑定。
function bind(fn,obj){ //简单实现bind return function(){ return fn.apply(obj,arguments); } }
由于硬绑定非常常用,ES5内置提供了方法Function.prototype.bind
bind()会返回一个硬编码的新函数,会把你指定的参数设置为this的上下文并调用原始函数。
6 new绑定
new来调用函数会自动执行下面的操作
- 创建一个新对象
- 这个新对象会执行[[Prototype]]连接
- 这个新对象会绑定到函数调用的this
- 如果函数没有返回其他对象,那么new表达式中的函数调用会自动返回这个新对象