相信学习前端的朋友肯定会遇到this,对this的理解程度往往决定了代码的高度。这里猫哥将结合各个具体实例,帮助朋友们彻底搞懂this。
什么是this?
this是Javascript语言的一个关键字。它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用,随着函数使用场合的不同,this的值会发生变化,指向是不确定的,也就是说可以动态改变的。但是有一个总的原则,那就是this指的是,调用函数的那个对象。
说白了猫哥总结就两点:
1、this只出现在函数里;
2、谁调用了该函数,this就指向谁
是不是感觉一下子明朗很多,接下来,直接上例子,深入理解。
function f(){
console.log(this)
};
//直接调用
f(); // this指的是window
//内置函数
setTimeout(f,1000); // this指的是window
//回调函数 —— 一个函数被作为参数传递给另一个函数 this ==== window
function test(v){
console.log(v)
};
//console.log(test); // 结果:打印的是整个函数
//console.log(test('hello')); // 结果:打印的是调用后的结果 “hello”
function f2(callback,v){
callback(v)
};
f2(test,'hello');
//另一种写法
f2(function(v){console.log(v)},'hello'); //匿名函数
//f2(function(v){console.log(this)},'hello'); // this指的是window
//数组
function f3(){
console.log(this);
};
var arr = [f3,4,5,6];
arr[0](); // this 指的是 arr
var f = arr[0]; // 数组赋值处理后 this指向发生了变化
f(); // this 指的是 Window
//对象
function f3(){
console.log(this);
};
var obj = {};
obj.id = 123;
obj.init = function(){
console.log(this)
};
obj.init() // 调用者是obj,所以jthis指向的是obj
obj.action = f3; //对象中添加了一个方法 方法赋值f3()
obj.action(); // 调用者是obj,所以jthis指向的是obj
//字面量
var obj2 = {
id:1,
abc:f3
};
obj2.abc(); // 调用者是obj2,所以jthis指向的是obj2
//构造函数
function Fun(name,age) {
this.name = name;
this.age = age;
this.action = function(){
console.log(this)
}
};
var fun2 = new Fun('abc',18);
fun2.action(); // this 指向的是新创建的对象, 而不是构造函数本身,即fun2
理解了this指向什么,那么有什么方法可以改变this的指向? 方法:apply() call() bind()
案例:
var a = 10;
function f5(x1,x2){
return this.a + " " +x1 +" "+ x2
};
var obj5 = {
a:100,
action:f5
};
var obj6 ={
a:9999
}
obj5.action(1,2); //结果 100 1 2
//call()
console.log(obj5.action.call(this,1,2)) //结果:10 1 2 改变作用域
//apply()
console.log(obj5.action.apply(window,[1,2])) // obj5.action对象的成员放到window对象上,这样f5的指向就是window
console.log(obj5.action.apply(obj6,[1,2]))
//bind() -------绑定this 也是改变作用域 绑定后不能改变this指向,(要想改变只能重新bind)
var a = 10;
function f5(x1,x2){
return this.a + " " +x1 +" "+ x2
};
var obj5 = {
a:100,
action:f5
};
var obj6 ={
a:9999
}
var a8 = f5.bind(obj5,1,2);
console.log(a8()); // 结果 100 1 2
console.log(a8.call(obj6,1,2)) // 由于使用了bind将obj5与f5绑定,所以此处通过call方法并不能将obj6绑给f5,故结果还是 100 1 2
最后,看了上面的例子,相信已经对this有了更深层次的理解,下面是一道经典测试题,最终的结果是什么?欢迎留言讨论。
var number = 1;
var obj = {
number:2,
showNumber:function(){
this.number = 3;
(function(){
console.log(this.number);
})();
console.log(this.number);
}
};
obj,showNumber();