this的指向與面向對象是JS一個繞不開的話題,在面試的過程中也經理被問到,我們通過不同的場景來分析this的指向問題,讓我們來更好的瞭解JS中的this.
this在不同調用環境的指向
全局環境
- 瀏覽器 -> window
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>this Demo</title>
</head>
<body>
<script>
console.log(this);
</script>
</body>
</html>
這段代碼this輸出的是window對象。
- node環境 -> module.exports
//this.js
console.log(this);
console.log(this === module.exports);
在node環境下執行 node this.js 輸出 {}, node環境下this 爲module.exports。
函數內部
- this最終指向調用它的對象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>this Demo</title>
<style>
.box ,.box2{
width: 80px;
height: 80px;
background-color: aquamarine;
position: relative;
left: 0;
transition: 1s;
}
</style>
</head>
<body>
<div class="box"></div>
<div style="margin-top: 10px;" class="box2"></div>
<script>
function move() {
this.style.left = '120px';
}
let box = document.querySelector('.box');
box.onclick = move;
let box2 = document.querySelector('.box2')
box2.onclick = move;
</script>
</body>
</html>
box點擊指向box,box2點擊就指向box2.
-
默認情況下,沒有直接調用者,this指向window
這個和全局下的是一樣的指向window. -
函數被多層對象包含,this指向上一級的對象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>this Demo</title>
<style>
.box ,.box2{
width: 80px;
height: 80px;
background-color: aquamarine;
position: relative;
left: 0;
transition: 1s;
}
</style>
</head>
<body>
<script>
let obj = {
a: 1,
fn: function () {
console.log(this);
}
}
obj.fn();
//var myFunc = obj.fn;
//myFunc();
//window.myFunc();
</script>
</body>
</html>
這裏的this指向了 obj這個對象。
- 嚴格模式下(設置了’use strict’),this爲undefined
- 構造函數的指向
構造函數中如果有return, return返回的值是對象,this指向返回的對象,如果返回的不是對象,指向的是創建的實例對象
null比較特殊,
let person = new Person(30); 通過new創建的實例對象經過的幾個步驟- 調用函數
- 自動創建一個對象
- 把創建出來的實例和this進行綁定
- 如果構造函數沒有返回值,默認返回this對象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
function Person() {
this.age = 18;
// return {
// age : 88
// }
}
Person.age = 28;
Person.prototype.age = 38;
Person.prototype.getAge = function () {
console.log(this.age);
}
let prototype = Person.prototype;
let getAge = prototype.getAge;
new Person().getAge();
prototype.getAge();
getAge();
</script>
</body>
</html>
大家可以嘗試做一下這道題,看下會輸出怎麼樣的結果?
如果把構造函數註釋代碼放開呢?結果會不會一樣
公佈結果: 18 38 undefined
如果把註釋代碼放開的結果是:88 38 undefined
箭頭函數中 this的
- 箭頭函數中本身是沒有this和argument的
- 默認指向定義它時,所處上下文的對象的this指向。即ES6箭頭函數裏this的指向就是上下文裏對象this指向,偶爾沒有上下文對象,this就指向window
- 即使是call,apply,bind等方法也不能改變箭頭函數this的指向
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script>
let obj = {
a: 1,
fn: ()=>{
console.log(this);
}
}
obj.fn.call(obj);
</script>
</body>
</html>
如果正常的話,這個this指向的是obj,但是this指向的是window.這段代碼可以證明結論2.