this指向的几种情况
1. 全局环境下
console.log(this); //在全局中打印this,就是指向 window
2. 普通函数中的 this 指向全局
function foo(){
console.log(this); //this指向 window
}
foo();
//即使是嵌套的函数, this 也是指向全局对象
function outer() {
function inner(){
console.log(this); // window
}
inner();
};
outer();
3. 通过对象调用, this 指向该对象(哪个对象调用它就指向对应的对象)
注意这个是普通函数哦~
let obj = {
name: "zhangsan",
talk(){
console.log(this); // this指向obj这个对象
}
}
obj.talk();
4. 事件监听器中的 this,指向事件源(注意它和event.target的区别。this只是指事件源,event.target不一定)
//这里忽略了html中的按钮哦~ 呐,就是这===><input type="button" value="click" id='btn>
btn.onclick = function(){
console.log(this); // <input type="button" value="click me">
}
5. 构造函数中的 this,指向 new 出来的实例对象
function Peopel(name) {
this.name = name;
console.log(this); // {name:"zhangsan"}
}
let obj = new Peopel("zhangsan");
6. 箭头函数的 this
飘忽不定箭头函数!!!!!
由于箭头函数没有自己的arguments和this指向。所以箭头函数的 this 指向取决于当前箭头函数声明的环境(执行上下文)
箭头函数需要获取函数定义时所在的环境的this,箭头函数定义在哪个作用域中,它的 this 就继承当前作用域 this 的指向。
① 定义在全局指向 window
let foo = () = >{console.log(this)} // window
//箭头函数没有自己的this指向,没有arguments。需要获取函数定义时所在的环境的this
② 对象中的箭头函数
var name = "小w";
let obj = {
name: "zhangsan",
talk: () => {
console.log(this.name); // 指向了 window,所以打印 小w
}
}
obj.talk();
/*
{} 不会生成作用域,即箭头函数声明在全局作用域中,this 指向全局
通过 var 声明的变量会被认作是 window 的属性 即 var a = 5; window.a == a
*/
理论说完了,那现在进入实战分析下吧!
//分析输出结果
let count = () => {
console.log(this);
console.log(this.number);
}
var number = 5;
let obj = {
say: count
};
obj.say();
最后的结果:window 5
我猜有小伙伴的答案是:window和报错,没注意到声明方式是很容易出现问题的哦。函数下面有个var声明的变量会存在变量提升的哦~提升变量不提升值。
分析:count是一个箭头函数,函数从上而下执行,obj是一个对象,对象里的say的值是上面声明的count(count是一个箭头函数),然后下面obj这对象调用say这个方法。箭头函数没有自己的this指向,所以要看箭头函数的声明环境。此题中声明的环境是全局,所以this的值就是window。通过 var 声明的变量会被认作是 window 的属性,所以var number==window number。
在全局环境下var,function声明的变量会自动成为全局对象的属性
易错点:箭头函数看声明环境,箭头函数在对象中{} 不会生成作用域。
继续继续!!!
//分析输出啦~
let number=5;
let obj={
number:10,
count:()=>{
console.log(this.number);
}
}
obj.count();
答案:undefined
我猜有小伙伴开始疑惑了,(・∀・*),为啥和前面的差不多输出咋就变undefined了?重点在于全局的变量声明。只有var在全局声明的变量是挂在window上的。let在全局作用域中声明的变量不会成为window对象的属性
继续继续!!!
//继续继续分析~
const zhangsan={
name:'zhangsan',
talk:function(){
console.log(this);
let lisi={
name:'lisi',
talk:()=>{
console.log(this);
}
}
lisi.talk()
}
};
zhangsan.talk();
答案:2个zhangsan这个对象
结构对象里面有方法(函数) 对象调用这个方法然后进入函数内部,talk这个函数是普通函数,通过对象调用的, this 指向该对象,所以这个function的this指向的就是zhangsang这个对象。然后继续进入李四对象,下面李四调用方法,进入李四里面的箭头函数。这个箭头函数声明在function这个普通函数中,所以箭头函数的this指向就是上面这个function的this指向
再来,再来!
let obj = {
a: 10,
fn: () => {
let bar = () => {
console.log(this);
}
bar();
}
}
obj.fn();
答案:window
分析:箭头函数没有指定this指向。看上图是属于全局变量。
总结!!!
分析注意var和执行顺序。细心细心再细心