JS this指向問題
阿新 • • 發佈:2022-03-08
首先, 明確一點, 沒有巢狀時, 函式中的this指向它的呼叫者.
巢狀函式, 內部的函式的this指向它的呼叫者=>window(不是外層函式)
var a = {
f: function (params) {
console.log(this);
function fn() {
console.log(this);
}
fn();
}
};
a.f();
{f: ƒ}
Window {window: Window, self: Window, document: document, name: '', location: Location, …}
其次, 函式既可以在當前執行環境中( this指向物件 ), 又可以在全域性環境中( this指向window )
var obj = {
foo: function () { console.log(this.bar) },
bar: 1
};
var foo = obj.foo;
var bar = 2;
obj.foo() // 1
foo() // 2
或者
var foo = function () { console.log(this.bar) };
var bar = 2;
var obj = {
foo: function () { console.log(this.bar) },
bar: 1
};
obj.foo() // 1
foo() // 2
原因: JavaScript 語言之所以有this的設計,跟記憶體裡面的資料結構有關係。
var obj = { foo: 5 };
JavaScript 引擎會先在記憶體裡面,生成一個物件{ foo: 5 },然後把這個物件的記憶體地址賦值給變數obj。
也就是說,變數obj是一個地址(reference)。後面如果要讀取obj.foo,引擎先從obj拿到記憶體地址,然後再從該地址讀出原始的物件,返回它的foo屬性。
原始的物件以字典結構儲存,每一個屬性名都對應一個屬性描述物件。舉例來說,上面例子的foo屬性,實際上是以下面的形式儲存的。
{ foo: { [[value]]: 5 [[writable]]: true [[enumerable]]: true [[configurable]]: true } }
當屬性的值是一個函式。var obj = { foo: function () {} };
這時,引擎會將函式單獨儲存在記憶體中,然後再將函式的地址賦值給foo屬性的value屬性。
{
foo: {
[[value]]: 函式的地址
...
}
}
由於函式是一個單獨的值,所以它可以在不同的環境(上下文)執行。???
var f = function () {};
var obj = { f: f };
// 單獨執行
f()
// obj 環境執行
obj.f()
1 函式形參及內部的this指向: 呼叫函式者
function a(){
var user = "追夢子";
console.log(this.user); //undefined
console.log(this); //Window
}
window.a();或a();//this指向window
var o = {
user:"追夢子",
fn:function(){
console.log(this.user); //追夢子
}
}
o.fn();//this指向o
var o = {
a:10,
b:{
a:12,
fn:function(){
console.log(this.a); //12
}
}
}
o.b.fn();////this指向b
2 箭頭函式的this=定義時外層物件的this,因為它根本沒有自己的this,導致內部的this就是外層程式碼塊的this
var obj = {
foo() {
console.log(this);
},
bar: () => {
console.log(this);
}
}
obj.foo() // {foo: ƒ, bar: ƒ}
obj.bar() // window
注意: 因為是箭頭函式,所以他的this是obj的this,即呼叫obj的=>window
3 建構函式this指向物件
function Fn(){
this.user = "追夢子";
}
var a = new Fn(); //this指向a
console.log(a.user); //追夢子
定時器中的this,指向的是window. =>巢狀函式
setTimeout(function() {
alert(this); // this -> window
},500)
元素繫結事件,執行函式中的this,指向的是當前元素
let $btn = document.getElementById('btn');
$btn.onclick = function(){
alert(this); // this -> $btn
}
物件(全域性)中的this
var age=18
var obj={
age1:this.age
}
console.log(obj.age1) //17
只有函式才形成區域性作用域,上面的obj的this實際上是全域性作用域window