前导: this是JavaScript中的一个关键字,在不同的场景中,this指向的对象也不同。在其他面向对象语言中(如C#),this就是指向当前对象。而在JavaScript 中this是在代码运行时绑定的,相对而言this指向比较混乱。在代码运行时this可以指向window对象,也可以指向当前调用对象,还可以指向其他对象。
Javascript调用函数有以下方式:普通函数、对象方法、定时器、构造函数、事件函数、call()/apply(),下面分别分析this在以上函数中的指向
1.this在普通函数中的指向
//1.在普通函数中this指向
var name = "张三";
function demo(){
var name = '李四';//在函数内部定义并声明的变量是局部变量
console.log(this.name); //张三
}
demo(); //其实这也可以看做是window.demo(),只不过我们在平常写代码的时候会自动忽略掉。
//所以window是函数的调用者,this指向window,this下name属性的值就是全局变量,所以输出的
//是全局变量 张三,而不是局部变量 李四
2.this在定时器中指向
setInterval(function(){
var a = 12;
alert(this.a);
},1000) //undefined ,归其本质setInterval方法也属于window,因为window对象下没有a属性,所以
//浏览器会每隔一秒弹出值为undefined的提示框
这个案例也很好玩
function Demo(){
this.a = 12;
setInterval(this.show,1000);
}
Demo.prototype.show = function(){
alert(this.a);
}
var demo = new Demo();
demo.show(); //第一次弹出12,之后每隔一秒弹出undefined
//原因在this.show代表了Demo.prototype.show的函数体,this指向Demo,所以第一次弹出12;
//之后延迟定时器开始工作,定时器时钟到达之后this指向window,window下没有a属性,所以每隔一秒弹出undefined
3. this在对象方法中的指向
name : '张三',
sayHi : function(){
alert(this.name);
}
}
var demo = obj.sayHi();
demo();//张三,如果一个对象中的方法有this,那么上一级调用这个方法时,this将指向上一级的对象
4.this在构造函数中的指向
//4.this在构造函数中的指向
function Person(name,age){
this.name = name;
this.age = age;
function sayHi(){
alert('hello');
}
return sayHi;
}
var per = new Person('张三',14);
console.log(per);//new关键字在内存中开辟了新的内存空间,并返回首地址的值,并将this指针指向了这块
//刚开辟的内存空间上,输出结果是person对象。但是如果取消return注释,输出值为sayHi函数体,原因如下:
//如果构造函数又返回的值的话,JS引擎会分析返回值的类型,如果返回值类型为Number()、字符串等基本类型,
//则不会替代new所创建的对象,如果返回值是引用类型,则将替换new创建出来的对象,因为new创建出来的对象
//也是引用类型,JS引擎无法分辨,将new替换。
5.this在事件函数中的指向
<body>
<button id="btn">点击</button>
</body>
<script>
var btn = document.querySelector('#btn');
btn.onclick = function(){
function fn(){
alert(this); //弹出window,如果事件函数中还有其他函数存在,那么this指向window
//如果想要修改this的指向,可以使用一下两种方法
}
fn();
}
</script>
解决方法:
<body>
<button id="btn">点击</button>
</body>
<script>
var btn = document.querySelector('#btn');
btn.onclick = function(){
var _this = this; //将this指针赋值给一个变量
function fn(){
alert(_this);//指向button对象
}
fn();
}
</script>
<body>
<button id="btn">点击</button>
</body>
<script>
var btn = document.querySelector('#btn');
btn.onclick = function(){
function fn(){
alert(this);//指向button对象
}
fn.call(this);//call()改变this的指向
//call()方法里面需要两大类参数,第一类参数是要修改指针指向的参数,只能有一个参数,并且只能放在第一个位置,第二类参数是函数中需要传参的参数。如果函数不需要传参,则只需要写第一类参数;//apply()同理,但是参数的存放形式不同,参数必须放在[ ]里面
}
</script>