js中this指向问题

this是javascript的众多关键字之一,它自动定义于作用域内,很多初学者可能对this指向问题感到摸不着头脑。首先看下面的示例

var hero ={};
hero.name = "CJF";
//此处使用具体对象
hero.getName = function(){
    console.log(hero.name);//这个确定了我们访问的是hero这个对象的name属性
}
hero.getName();//输出 "CJF"
//在此处我们使用this
hero.getNameNew = function(){
    console.log(this.name);//这个则要根据具体的运行环境来判定this指向
}
hero.getNameNew()//也输出 "CJF"    此时的this对象指向的hero这个对象

当然我们也可以在浏览器控制台直接输入this看具体的结果
浏览器控制台this输出结果
从上图看一看出,此时this指向的window对象。

this的指向大概可以分为四种

1、普通函数调用
2、作为对象的方法调用
3、作为构造函数使用
4、call和apply调用

第一种 作为普通函数调用
//函数声明
function fn(){
   console.log(this);//windwo对象
}
//函数表达式
var f = function(){
  console.log(this);//windwo对象
};
fn();
f();
//不管此时是调用fn或者f函数,它们中的this指向的都是window对象

也就是当一个函数作为普通函数调用时,内部的this对象指向的全局对象,即浏览器的window对象。
当然在ECMAScript5的严格模式下,this已经被规定不在指向全局对象了,而是undefined

function fun(){
    "use strict"
    console.log(this);//输出undefined
}
fun();
第二种 作为对象的方法调用

就如前面的hero示例所示的

var hero = {
    name:"CJF",
    getName:function(){
        console.log(this.name);
    }
}
hero.getName();//输出  "CJF"

也就是说当函数作为对象的方法调用时,this指向的就是该对象。
不过大家要注意一点儿,如果像下面这样调用,this就不再指向该对象了

var hero = {
    name:"CJF",
    getName:function(){
         console.log(this.name);
    }
}
window.name = "123";
var getName = hero.getName;  //将hero.getName方法的引用赋值给另一个变量,再通过这个变量调用该方法,此时this是window对象,不再是hero对象
getName();//输出  "123"  相当于普通函数调用
第三种 作为构造函数使用

当我们是使用new关键字调用函数时,总是返回一个对象,构造器中的this就指向该对象

function FClass(name){
    this.name = name;
}
var obj = new FClass("CJF");
console.log(obj.name);//输出 "CJF"

如果构造函数显式的返回一个Object类型的对象,那么我们期待的this就不会被返回。
如果构造函数不显式的返回任何数据或者显式返回的不是对象类型数据,使用new调用函数,返回的还是我们期待的this。

//构造函数显式返回对象类型数据
function FClass(name){
    this.name = name;
    return {
        name:"CJF1",
        age:20
    };
}
var obj = new FClass("CJF");
console.log(obj.name);//输出 "CJF1"
console.log(obj.age);//输出 20

//构造函数显式返回非对象类型数据
function FClass(name){
    this.name = name;
    return "CJF1";
}
var obj = new FClass("CJF");
console.log(obj.name);//输出 "CJF"
console.log(obj.age);//输出 undefined
第四种 call和apply调用

call和apply调用跟普通函数调用相比,call和apply可以动态的改变传入函数的this对象指向。

var obj = {
    name:"CJF",
    getName:function(){
        console.log(this.name);
    }
}
var obj1 = {
    name:"CJF1"
}
console.log(obj.getName());//输出 "CJF"
console.log(obj.getName.call(obj1));//输出  "CJF1"
//或者
console.log(obj.getName.apply(obj1));//输出  "CJF1"

//如果call和apply不传任何参数或者传入null 则this指向window对象
window.name == "123";
console.log(obj.getName.call());//输出  "123"
console.log(obj.getName.apply());//输出  "123"
console.log(obj.getName.call(null));//输出  "123"
console.log(obj.getName.apply(null));//输出  "123"

call和apply具体使用请参考我的另一篇博客 apply、call的区别和使用

this总是指向一个对象,this对象具体指向的是哪个对象是在运行时基于函数的执行环境动态绑定的,不是函数声明时的环境。

在js中this的使用是非常普遍的,上面介绍的四种关于this指向的四种情况和规则,在实际写代码的过程中肯定比这要复杂的多(各种框架和js库),但是无论它们的代码多么复杂,它们的this运用基本都是混合应用上面的几个情况和规则而已。


如果有写的不对的,或者理解不到位地方,欢迎各位指正。

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值