function foo() { // 當前調用棧 => foo // 當前調用位置 => global全局做用域 console.log('foo') bar() // bar調用位置 } function bar() { // 當前調用棧 => foo -> bar // 當前調用位置 foo console.log('bar') }
默認 => 獨立函數調用app
隱式 => 是否存在上下文 / 被某個對象擁有或包含函數
function foo() { return this.a } const obj = { a: 'hello', foo, // 函數引用,當前上下文是obj } obj.foo()
顯式綁定 => call, apply, bindthis
function foo() { return this.a } const obj = { a: 'hello } const bar = function() { foo.call(obj) // 顯式的強制綁定 } setTimeout(bar, 300) bar.call(window) // 2 => 硬綁定以後this沒法再修改
new綁定 => 構造函數調用,實際上並不存在「構造函數」,是對函數的「構造調用」code
隱式綁定會丟失綁定對象,從而應用默認綁定,分別有如下兩種狀況。對象
函數別名 => 引用函數自己,so默認綁定作用域
function foo() { return this.a } const obj = { a: 'hello', foo, // 函數引用,當前上下文是obj } const a = 'on no, this is global' const bar = obj.foo // 函數別名 bar() // 'on no, this is global'
參數傳遞 => 隱式賦值,同上io
function foo() { return this.a } function doFoo(fn) { fn() // fn => foo } const obj = { a: 'hello', foo, // 函數引用,當前上下文是obj } const a = 'on no, this is global' doFoo(obj.foo) // 'on no, this is global'
new能夠修改顯式的thisconsole
function foo(some) { this.a = some } const obj = {} const bar = foo.bind(obj) bar(2) console.log(obj.a) // 2 const baz = new bar(3) console.log(obj.a) // 2 console.log(baz.a) // 3 => new 修改了this綁定
new中使用硬綁定 => 函數柯理化function
function foo(a, b) { this.value = a + b } const bar = foo.bind(null, 'hello ') //這裏 this不指定,new時會修改 const baz = new bar('world') baz.value // 'hello world'