Javascript this的簡單理解

首先寫這篇博客是爲了整理我自己有關於this關鍵字的一些基本理解,讓自己的關於this理解更深刻些,後面會把它整理的更加完善。
javascript中this一直困擾着我,一下es5中的this,一下es6中的this,有時候自己容易暈,近期自己特意去看有關this的博客和文章,進一步加深了我對this的理解。
JS中的this,

  • 在function內部創建。
  • 指向啓用該函數的對象。
  • this不可以被賦值,但是可以被call/apply/bind改變指向。

我先把主要的兩個重要的有關定義拋出來

1. this指向函數執行時啓用該函數的對象,如果該函數沒有被任何對象啓用(綁定),this就指向window。函數在執行時,this纔會進行綁定。
2.箭頭函數中,this是指向定義時所在的對象。

一、this和構造函數

我們常常用到構造函數,而構造函數中的this指向構造函數的實例。

function User (name,age) {
	this.name = name;
	this.age = age;
}
User.prototype.getName = function () {
	console.log(this.name);
};
var usr1 =  new User ('yang',23);
user.getName(); // yang

二、this和對象

this是在執行時纔開始綁定。因此this的指向是在執行的時候,看該函數有沒有綁定對象,如果沒有綁定對象,則是this指向window。

var obj = {
	name: 'zhangsan',
	getName: function () {
		console.log(this.name)
	}
}
obj.getName();// zhangsan

很顯然,上面的getName函數在執行時,是被obj對象調用的。因此this指向的是obj對象。

下面改變下代碼的形式:

var name = "Global";
var person = {
	name: "Person",
	details: {
		name: "Details",
		print: function () {
			return this.name;
		}
	},
	print: function () {
		return this.name;
	}
}
person.details.print(); //?
person.print();//?
var name1 = person.details;
var name2 = person.print;
name1.print(); //?
name2();//?

這個題很經典,我們可以逐步分析下,分析前始終要記住一句話
this指向函數執行時啓用該函數的對象,如果沒有任何對象啓用該函數,this就指向window。函數在執行時,this纔會進行綁定。
person.details.print(),很明顯是被person.detail調用,返回person.details.name,即"Details"。person.print()同理和print在被person調用,返回person.name,即"Person"。
name1 = person.details,person.details 賦值給了name1,person.details的引用賦值給了name1,name1.print()也是 name1.person調用的,因此返回的結果也是"Details"。
而name2是直接被person.print函數賦值的。name2()前面沒有任何東西調用它,因此name2指向的是window。

三、this和dom/事件

示例1:

<div id="nav" onclick="alert(this)"></div>
//this指向nav

示例2:

<div id="nav" onclick="alert(this)"></div>

<script>
var nav = document.getElementById('nav');
nav.onclick= function () {
	alert(this);
}
//同理this指向的是id爲nav的dom元素
</script>

示例3:

<div id="nav" onclick="getId()"></div>
<script>
function getId(){
	alert(this.id);
}
</script>

可能剛開始會以爲結果爲nav.其實不然,還是原來的那句話,this的指向,是看函數執行時而非定義時,是指向函數執行時啓用該函數的對象,只要函數沒被任何對象啓用(綁定),this都指向window

四、this和箭頭函數

箭頭函數中的this指向時在函數定義時的對象。
下面可以看一個

var obj = {
	data: [1,2,3],
	dataDouble: [1,2,3],
	double: function () {
		console.log("在doucle函數中");
		console.log(this); // @1  表示第一個this
		return this.data.map(function(item){
			console.log(this); // @2 表示第二個this
			return item*2;
		});
	},
	doubleArrow: function () {
		console.log("在doucleArrow函數中");
		console.log(this);//@3 表示第三個this
		return this.data.map((item) => {
			console.log(this); // @4 表示第四個this
			return item*2;
		})
	}
}
obj.double();
obj.doubleArrow();

obj.double(),是被obj啓用的,所以在 @1和 @3 顯然都是指向的obj對象。可以複製代碼執行看下結果就知道了。

return this.data.map(function(item){
			console.log(this); // @2 表示第二個this
			return item*2;
		});

this.data.map中的是匿名函數,沒用被任何對象啓用,因此@2指向的是window;


return this.data.map((item) => {
			console.log(this); // @4 表示第四個this
			return item*2;
		})

箭頭函數就不同了,箭頭函數中的this指向定義時所在的對象,因此@4指向的是obj對象。

參考文章
http://caibaojian.com/deep-in-javascript-this.html
https://www.cnblogs.com/snandy/p/4773184.html
https://www.cnblogs.com/libin-1/p/6069031.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章