普通函数:谁调用就指向谁,如果没有调用者,就指向全局对象window。
箭头函数:箭头函数的this指向于外层函数作用域下的this指向。它的this
永远是外层函数的this。
一、在全局作用域下,this始终指向全局对象window,无论是否是严格模式!
//在全局作用域下,this始终指向全局对象window,无论是否是严格模式!
console.log(this); //window
//完整的写法是window.console.log(),window可以省略, 所以指向window
二、普通函数内的this分为两种情况,严格模式下和非严格模式下。
// 普通模式下
function test() {
console.log(this);
}
test() //window,没有调用者,就指向全局对象window。
// 严格模式下,必须指定调用者
function test() {
'use strict';
console.log(this);
}
test() //严格模式下,没有指定调用者,输出为undefined
window.test() // 指定调用者,输出window
三、对象中的this,对象内部方法的this指向调用这些方法的对象,也就是谁调用就指向谁。
一层对象。
let obj = {
name: 'zjh',
sing: function () {
var name = 'lxf'; // 他是函数内的变量,不是obj对象上的
console.log(this.name); //this指向obj,输出zjh
}
}
obj.sing(); //// 谁调用指向谁,指向obj,
二层对象,多层嵌套的对象,内部方法的this指向离被调用函数最近的对象。
let obj = {
name: 'zjh',
obj2: {
name: 'zzz',
dance: function () {
console.log(this.name); //this指向obj2,输出zzz
}
}
}
obj.obj2.dance(); //zzz,
let obj = {
a: 1,
say() {
console.log(this); //obj { a:1, say:function }
let fn = function () {
console.log(this); //window
}
fn() //没有调用者,就指向window
}
}
obj.say();
四、箭头函数下的this
箭头函数是一个ES6的主要特性之一,他存在的真正意义并不是为了更加简洁的语法,而是因为他独特的this指向。箭头函数的this
跟常规函数的规则完全不同。无论用什么方式、在哪里调用箭头函数,里面的this
永远是外层函数作用域的this
。也就是箭头函数没有自己的this指向。如果没找到函数作用域,找到最外层的全局作用域,那this指向window。如果父级作用域还是箭头函数,就再往上找,一层一层的直到找到this的指向。
虽然log和newlog都是同一个方法,但是他们的this指向确不同,因此,普通函数this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,而箭头函数的this指向在被定义的时候就确定了,之后永远都不会改变。即使使用call()
、apply()
、bind()
等方法改变this指向也不可以。
let counter = {
count: 0,
log() {
console.log(this)
}
}
let newLog = counter.log;
couter.log(); // couter { count:0, log: fn}
newlog() // window
let fn = () => {
console.log(this); //外层作用域是全局作用域,则this指向window
}
fn() //window
let obj = {
a: 1,
say: () => {
console.log(this); //window
}
}
obj.say();
//obj是全局声明的变量,处于全局作用域
// 没有找到外层函数作用域,那就处于全局作用域,即指向window
let obj1 = {
a: 1,
fn(items) {
console.log(this) //obj1
let dance = () => {
console.log(this); //外层函数作用域是fn,fn的this指向obj1
};
dance()
}
}
obj1.fn()
let printThis = () => {
console.log(this)
}
function logThis() {
console.log(this)
}
btn1.addEventListener('click', printThis) // Window
btn2.addEventListener('click', logThis) // <button class="btn1">1</button>
五、构造函数中的this
构造函数中的this指向构造函数下创建的实例对象。
function Star(a) {
this.a = a;
console.log(this); // 指向实例对象 { a: 11 } { a: 22 }
}
let zjh = new Star(11); // { a: 11 };
let ldh = new Star(22); // { a: 22 };
六、不在函数里的场景
- 在 <script /> 标签里,this 指向 Window。
- 在 Node.js 的模块文件里,this 指向 Module 的默认导出对象,也就是 module.exports