默认绑定的概念
当函数以独立函数调用(而不是作为对象方法、使用 call/apply/bind 或作为构造函数调用)时,this 会使用默认绑定:
- 在非严格模式下,
this会绑定到全局对象(浏览器中是window,Node.js 中是global) - 在严格模式下,
this会绑定到undefined
function foo1() {
console.log(this) // 输出当前调用上下文中的this
}
function foo2() {
console.log(this) // 输出当前调用上下文中的this
foo1() // 调用foo1(独立函数调用)
}
function foo3() {
console.log(this) // 输出当前调用上下文中的this
foo2() // 调用foo2(独立函数调用)
}
foo3
在调用的时候是独立的,所以打印出来的结果都是window
var obj = {
name: "why",
foo: function() {
console.log(this) // 输出当前this指向
}
}
var bar = obj.foo // 将obj.foo函数赋值给bar变量
bar() // 直接调用bar函数
-
bar()调用时的输出- 在浏览器非严格模式下输出:
window全局对象 - 在严格模式下输出:
undefined
- 在浏览器非严格模式下输出:
-
原因解析:
-
虽然
foo最初定义在obj对象中,但当通过var bar = obj.foo赋值后:bar只是一个独立的函数引用,与obj完全解耦- 直接调用
bar()属于默认绑定规则,this不再指向obj
-
function foo() {
console.log(this)
}
var obj = {
name: "why"
foo: foo
}
var bar = obj.foo
bar() //window
-
函数引用赋值:
var bar = obj.foo只是获取了函数的引用,并没有保留obj的上下文关系
-
调用方式决定this:
bar()是直接函数调用(不是作为对象方法调用)- 在非严格模式下,普通函数调用的
this默认指向全局对象(浏览器中是window) - 严格模式下会输出
undefined
-
与方法调用的区别:
-
对比
obj.foo()会输出obj对象,因为:- 当作为方法调用时(
obj.foo()),JavaScript会自动将this绑定到点前面的对象
- 当作为方法调用时(
-
function foo() {
function bar() {
console.log(this); // 输出当前this指向
}
return bar; // 返回内部函数bar
}
var fn = foo(); // 获取bar函数
fn(); // 调用bar函数
-
fn()调用时的输出:- 在浏览器非严格模式下输出:
window全局对象 - 在严格模式下输出:
undefined
- 在浏览器非严格模式下输出:
-
原因解析:
- 虽然
bar是在foo函数内部定义的,但它被作为普通函数调用(fn()) - 按照 JavaScript 的 默认绑定规则,独立函数调用的
this指向全局对象(非严格模式)或undefined(严格模式) - 闭包特性不会影响
this的绑定规则
- 虽然