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.