全局中的代碼無論是否處於嚴格模式下,它的this都執行Windowjavascript
console.log(this) // Window
複製代碼
() => {
console.log(this) // window 或 global,在全局定義指向全局
}
obj = {
fn: () => {
console.log(this) // obj 在obj對象中定義,可是指向全局(箭頭函數時,obj沒法確認環境)
}
}
複製代碼
直接調用函數(在全局或者其餘函數內)html
在非嚴格模式下,this默認指向全局變量(window或global)java
```js
// 在瀏覽器中,全局對象是window, 在NODE中是global
function test() {
console.log(this) // Window 或者 global
(function(){
console.log(this) // Window 或者 global
})
}
test()
```
複製代碼
function test() {
console.log(this) // undefined
(function(){
console.log(this) // undefined
})
}
test()
複製代碼
// setTimeout是window的方法,可使用window.setTimeout調用
// 調用函數時,對象訪問大體路線:window -> setTimeout -> 獲取參數中test的引用參數 -> 執行 test 函數
function test() {
console.log(this)
}
setTimeout(test, 100); // window 或 global
複製代碼
做爲對象方法調用則指向當前對象es6
var a = 'global'
function name() {
console.log('name', this.a) // 經過普通調用方法直接調用,在嚴格模式下this爲undefined,運行報錯,在非嚴格模式下global
}
var obj = {
fn: function () {
console.log('inner', this.a) // obj 經過對象obj調用,this指向該對象與模式沒有關係
name()
},
a: 'obj'
}
obj.fn()
var newFn = obj.fn()
newFn() // 嚴格模式爲undefined,非嚴格爲window或者global,按普通方法直接調用的規則處理
function test(fn){
fn()
}
test(obj.fn) // 至關於將fn=obj.fn, 嚴格模式爲undefined,非嚴格爲window或者global
newObj = {fn: 2}
test(newObj.fn=obj.fn) // 至關於 fn = newObj.fn = obj.fn, 嚴格模式爲undefined,非嚴格爲window或者global
複製代碼
執行new操做時,構造函數的this指向正在構造的新對象瀏覽器
function TEST(){
this.a = 'obj';
console.log(this) //new操做時 TEST { a: 'obj'} this指向正在構造的對象(返回的對象)
}
var o = new TEST();
console.log(o); // TEST { a: 'obj'} this指向剛剛構造的對象
複製代碼
class MyTest {
constructor (callback) {
this.callback = callback
callback() // 指向window
}
func () {
this.callback() // 指向MyTest
}
}
// let的值不會綁定到window上,沒法用window.name訪問
let name = 'global'
function Test () {
console.log(this, this.name)
}
new Test() // window 使用let輸出 '', 使用var輸出global
let c = new MyTest(Test) // window 使用let輸出 '', 使用var輸出global
c.func() // MyTest{} undefined
複製代碼
// 當函數直接調用的時候,在非嚴格模式下,this指向window;嚴格模式爲undefined
// 當函數做爲對象的屬性調用的時候,this指向這個對象;
// p1.constructor指向Person的構造函數(Person()函數自己),
// 在p1.constructor()時,Person是做爲p1的屬性調用的,因此this指向p1;
// 當調用p2 = p1.constructor;p2();時,其實就至關於直接調用Person();因此this指向window
var name = 'global'
function Person() {
this.name = 'person';
console.log(this);
}
var p1 = new Person();
p1.constructor(); // Person {name: "person"}
var p2 = p1.constructor;
p2(); // window
複製代碼
設置call/apply/bind後調用,則指向其第一個參數的this,若是爲空則在嚴格模式下指向undefined,在非嚴格模式下指向window或globalbash
// 語法
// 一、函數.apply(對象, [參數列表])
// 二、函數.call(對象, arg1,arg2,arg3…argn)
// 三、函數.bind(對象)
// 'use strict'
var a = 'global'
function name() {
console.log('name', this.a)
}
function name2() {
console.log('name2', this)
}
var obj = {
a: 'obj'
}
name.call(obj) // obj this指向經過call綁定的obj對象
// name2.call() // 嚴格模式爲undefined,非嚴格模式爲widow或global
複製代碼
做爲一個dom事件處理函數,它的this指向添加處理事件的元素(一些瀏覽器在使用非addEventListener的函數動態添加監聽函數時不遵照這個約定)閉包
// html
<div id="A">
<div id="B"></div>
</div>
// javascript
var a = document.getElementById('A');
var b = document.getElementById('B');
function logs (e) {
console.log(e.target, e.target===this); // 當e.target與e.currentTarget相等時爲true
console.log(e.currentTarget, e.currentTarget===this); // 老是true
}
a.addEventListener('click', logs, false);
// 點擊A時,
// 輸出 A節點信息,true \n A節點信息, true
// 點擊B時,
// 輸出 B節點信息,false \n A節點信息, true
// currentTarget表示實際綁定處理事件的元素
// target表示觸發事件的元素(如點擊B)
// 因此處理事件中的this指向實際添加處理事件的元素
複製代碼
做爲一個內聯事件處理函數,app
<button onclick="alert(this.tagName.toLowerCase());">Show this</button>
複製代碼
<button onclick="alert((function(){return this})());">Show inner this</button>
複製代碼
閉包的執行至關因而返回一個函數,而後將這個返回的函數執行,所以和普通函數的直接調用相同dom
var box={
user: 'zs',
getThis:function(){
return function(){
return this;
};
}
}
console.log(box.getThis()()); // 指向全局,非嚴格爲window,嚴格爲undefined
複製代碼