一.普通函数this指向
//单独使用 指向全局对象 window
console.log(this);//window
1.方法调用形式
当函数被保存为一个对象的属性时,它就可称为这个对象的方法。当一个方法被调用时,this被绑定到这个对象上。如果调用表达式包含一个提取属性的动作(. 或 []),那么它被称为方法调用。
let person={
name:'liming',
eat:function(){
console.log(this.name);//liming 指向自身对象
},
}
person.eat();
此时person是对象,eat函数称为person的方法,所以this指向当前的对象person
对象的this指向window
var name='wangli';
let stu={
name:this.name,
wash:function(){
console.log(this.name);//wangli
}
}
stu.wash();
此对象为stu,对象的name属性,this.name指向window的name属性
2.函数调用形式
当一个函数并非一个对象的属性时,那么它就是被当做函数来调用的。在此种模式下,this被绑定为全局对象,在浏览器环境下是window对象
非严格模式下,函数中的this指向window
//在函数中 this指向 全局对象 window
var name='zhangliang';
function Method(){
console.log(this); //指向window
console.log(this.name);//zhangliang
}
Method();
Method函数没有对象,所以是一个函数进行调用的,所以指向的是全局对象window
严格模式下,函数中的this指向undefined,但是全局中的this还是指向window
'use strict';
var a = 1;
function strict(){
console.log(this); //undefined
console.log(this === window); //false
console.log(this.a); //报错
}
//全局中的this还是指向window
console.log(this); //window
console.log(window); //window
console.log(this.a); //1
console.log(window.a); //1
strict();
3.构造函数
如果在一个函数前面加上new关键字来调用,那么就会创建一个连接到该函数的prototype成员的新对象,同时,this会被绑定到这个新对象上。这种情况下,这个函数就可以成为此对象的构造函数
function obj(){
this.name = 'wangsan';
}
var ob = new obj();
conosle.log(ob.name);//wangsan
构造了ob对象 new来调用obj函数 所以this被绑定到了这个ob对象上
4.apply调用模式
在JS中,函数也是对象,所有函数对象都有两个方法:apply和call,这两个方法可以让我们构建一个参数数组传递给调用函数,也允许我们改变this的值
var name = "xiaoxiao";
var obj = {
name : "lili"
};
function getName(){
console.log(this.name);
}
getName.apply(); //"xiaoxiao"
getName.apply(obj); //"lili"
将obj对象递给getName调用函数,this值将会改变为obj的对象
二.事件的this指向
事件的this指针指向元素本身
<body>
<button class="btn">按钮</button>
<button class="btn">按钮</button>
<button class="btn">按钮</button>
<script>
Btn=document.getElementsByClassName("btn");
for(let i=0;i<Btn.length;i++){
Btn[i].οnclick=function(){
console.log(this); // this指向button 指向事件的元素
}
}
</script>
</body>
三.ES6箭头函数指向
箭头函数中的this始终指向箭头函数定义时的离this最近的一个函数,如果没有最近的函数就指向window,箭头函数的this是在定义函数时绑定的,不是在执行过程中绑定的。简单的说,函数在定义时,this就继承了定义函数的对象。
var h=10;
let fun=()=>{
let h=3;
console.log(this.h);//window 10
}
fun();
此箭头函数没有外部函数,指向window
var h=10;
let stu={
h:5,
eat:()=>{
console.log(this); //没有外部函数 指向window 10
}
}
stu.eat();
箭头函数就算是有对象,没有外部函数,还是指向的是window
let person={
h:6,
write:function(){
//外层函数的对象 此时为h=6
var get=()=>{
console.log(this.h);
}
get();
},
write1:()=>{
var get1=()=>{
console.log(this.h); //输出10 window 所以第一层是箭头函数也要指向window
}
get1();
}
}
person.write();
person.write1();
在第一个有外部函数write所以箭头函数get指向外部函数的对象即时person对象
write1为箭头函数,所以里面的get1箭头函数this还是指向的是window