有關ECMAScript定義如何獲取this請移步ECMAScript中關於如何獲取this的定義
絕大多數情況下,函數的調用方式決定了this的取值
全局上下文
console.log(this === window); //true
函數上下文
直接調用
function fn(){
return this;
}
fn() === window; //true
//this的值不是由函數調用設定,默認爲全局對象
嚴格模式下增強了安全措施,this關鍵字禁止指向全局對象
function fn(){
"use strict";
return this;
}
fn() === undefined; //true
function f(){
"use strict";
this.a = 1;
}
f();// 報錯,this未定義
var fun = new f();
console.log(fun.a); //1
對象方法中的this
指向調用該函數的對象,並且是最靠近的引用
var o = {prop: 37};
function independent() {
return this.prop;
}
o.f = independent;
o.b = {
g: independent,
prop: 42
};
console.log(o.f()); //logs 37
console.log(o.b.g()); //logs 42
構造函數中的this
與即將被創建的新對象綁定,可手動設置返回對象
function C(){
this.a = 37;
}
var o = new C();
console.log(o.a); //logs 37
function C2(){
this.a = 37;
return {a:38};
}
o = new C2();
console.log(o.a); //logs 38
call和apply
this的值被綁定到一個指定的對象上
如果傳遞的this值不是一個對象,則會使用ToObject操作將其轉換爲對象
function bar() {
console.log(Object.prototype.toString.call(this));
}
bar.call(7); // [object Number]
//會通過new Number(7)轉換爲對象
//如果是字符串則會通過new String('foo')轉換爲對象
bind
Function.prototype.bind
會創建一個具有相同函數體和作用域的函數,但是新函數的this被永久綁定到bind的第一個參數上,無論這個函數如何被調用
function f(){
return this.a;
}
var g = f.bind({a:"azerty"});
console.log(g()); //azerty
var o = {a:37, f:f, g:g};
console.log(o.f(), o.g()); //37, azerty
DOM事件處理函數中的this
事件處理函數中的this指向觸發事件的函數
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<button id="btn">button</button>
<script>
function eventHandler() {
//this指向#btn
console.log(this); //<button id="btn">button</button>
}
var btn = document.querySelector('#btn');
btn.addEventListener('click', eventHandler, false);
</script>
</body>
</html>
內聯事件處理函數中的this
指向監聽器所在DOM元素
<!--
<button οnclick="console.log(this);">
Show this
</button>
-->
<button onclick="alert(this);">
Show this
</button>
<!--window對象,因爲沒有設置內部函數的this,非嚴格模式下默認指向全局對象-->
<button onclick="alert((function(){return this})());">
Show inner this
</button>