前言: 一直都搞不清javascript中this的指向,<你不知道的javascript(上卷)>
這本書中有3章都是在講解this,去年第一次看完還是覺得似懂非懂的,一深入的問還是不清楚,現(xiàn)在在看一遍,真心覺得這本書里將的是真好,想深入了解一下的,這本書是一個(gè)不錯(cuò)的選擇.
下面我就簡(jiǎn)單的說一下我的理解,用兩句話記住了javascrpt中this的指向:
this的指向
普通函數(shù)指向函數(shù)的調(diào)用者:有個(gè)簡(jiǎn)便的方法就是看函數(shù)前面有沒有點(diǎn),如果有點(diǎn),那么就指向點(diǎn)前面的那個(gè)值;
箭頭函數(shù)指向函數(shù)所在的所用域: 注意理解作用域,只有函數(shù)的{}
構(gòu)成作用域,對(duì)象的{}
以及 if(){}
都不構(gòu)成作用域;
const obj = {
name: 'objName',
say() {
console.log(this.name);
},
read: () => {
console.log(this.name);
}
}
obj.say(); // objName
obj.read(); // undefined
- 普通函數(shù),調(diào)用者是obj,所以結(jié)果是 objname;也是理解
say()
是普通函數(shù),前面有點(diǎn),所以this
指向obj
; - 箭頭函數(shù),this指向函數(shù)所在的作用域,當(dāng)前的作用域?yàn)槿汁h(huán)境,所以
this.name
為undefined
, - 舉下面的例子更清楚的了解一下箭頭函數(shù)this的指向,箭頭函數(shù)所在的作用域是普通函數(shù)
say
,say()
的調(diào)用者是obj
const obj = {
say: function () {
setTimeout(() => {
console.log(this)
});
}
}
obj.say(); // obj,此時(shí)this指的是定義他的obj
補(bǔ)充知識(shí)點(diǎn)
- 瀏覽器默認(rèn)的this為window
function test() {
console.log(this);
}
test(); //window
- node.js中全局環(huán)境默認(rèn)
this為{}
,普通函數(shù)中默認(rèn)this為global
console.log(this); // {}
function test() {
console.log(this);
}
test(); //global
來兩道題檢查你是否掌握了
example1
const length = 10;
function fn() {
console.log(this.length);
}
const obj = {
length: 5,
method: function(fn) {
fn();
arguments[0]();
}
};
obj.method(fn, 1);
輸出 10, 2
剛開始看到這道題我也是蒙蒙的,現(xiàn)在也終于理解了,
method這個(gè)函數(shù)傳入了兩個(gè)參數(shù),一個(gè)參數(shù)為fn(),fn()為普通函數(shù),this指向函數(shù)的調(diào)用者,此時(shí)指向全局(也可以看這個(gè)函數(shù)前面沒有點(diǎn)
),所以運(yùn)行結(jié)果為10,arguments是函數(shù)的所有參數(shù),是一個(gè)類數(shù)組的對(duì)象,arguments0,可以看成是arguments.0(),調(diào)用這個(gè)函數(shù)的是arguments,此時(shí)this就是指arguments
,this.length就是angument.length,就是傳入的參數(shù)的總個(gè)數(shù)2
注: 上面例子在node環(huán)境中的運(yùn)行結(jié)果為 undefined 2, const length = 10
改成global.length = 10;
是因?yàn)閚ode環(huán)境下定義在全局的變量不會(huì)綁定到global,瀏覽器也會(huì)自動(dòng)綁定到全局環(huán)境window
改成下面這樣結(jié)果又是什么呢?
const length = 10;
function fn() {
console.log(this.length);
}
const obj = {
length: 5,
method: function(fn) {
fn();
const fun = arguments[0];
fun()篇梭;
}
};
obj.method(fn, 1);
10, 10
example 2
window.val = 1;
var obj = {
val: 2,
dbl: function() {
this.val *= 2;
val *= 2;
console.log(val);
console.log(this.val);
}
}
obj.dbl(); // 2 4
var func = obj.dbl;
func(); // 8 8
這個(gè)就是有點(diǎn)繞了,不過一步步來分析就很容易理解了:
obj.dbl()
;執(zhí)行這行代碼時(shí)刺覆,this指的是obj
,所以this.val === obj.val*=2
,最后結(jié)果為4
,val*=2 === window.val *= 2
,最后結(jié)果是2
func()
哎媚,執(zhí)行這行代碼時(shí),func()
沒有任何前綴,this
指的是window.func()
;所以此時(shí)this值得是window
,this.val === window.val *= 2
,此時(shí)window.val
為4
垛玻,val*=2 === window.val *2
,最后結(jié)果為8
,最后console.log(this.val)
,與console.log(val)
,指的都是window.val
奶躯,最后結(jié)果都是8
上述是我自己的理解,如果有什么問題,歡迎指正~