JavaScript中this的四种指向情况

392 阅读2分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路。

跟别的语言大相径庭的是,JavaScript的this总是指向一个对象,而具体指向哪个对象是在运行时基于函数的执行环境动态绑定的,而非函数被声明时的环境。 除去不常用的with和eval的情况,具体到实际应用中,this的指向大致可以分为以下四种

  • 作为对象的方法调用
  • 作为普通函数调用
  • 构造器调用
  • Function.prototype.call / Funtion.prototype.apply
  1. 作为对象的方法调用 当函数作为对象的方法被调用时,this指向该对象。
let obj = {
    a:1,
    getA:function(){
        alert(this === obj ); //输出:true
        alert(this.a) //输出:1   
    }
}
obj.getA();
  1. 作为普通函数调用 当函数不作为对象的属性被调用时,也就是我们常说的普通函数方式,此时的this总是指向全局对象。在浏览器的JavaScript里,这个全局对象是window对象。
window.name =  'globalName'
let getName =function(){
    return this.name;
}
console.log(getName());// 输出:globalName
let myObject = {
    name:'sven',
    getName:function(){
        return this.name;    
    }
}
var getName = myObject.getName;
console.log(getName())//输出:globalName
  1. 构造器调用 当用new运算符调用函数时,该函数总会返回一个对象,通常情况下,构造器里的this就指向返回的这个对象。
let MyClass = function(){
    this.name = 'shintaro'
}
let obj = new MyClass();
console.log(obj.name) // output:'shintaro'

如上obj复制了MyClass的原型也获得了其中的name属性,但当构造器函数显示的返回了一个object类型的对象时,那么使用new调用构造器后获得的this环境就是这个对象,如下:

let MyClass = function(){
    this.name = 'shintaro'
    return {
        name:'Faker'    
    }
}
let obj = new MyClass();
console.log(obj.name) //output:'Faker'

如果返回的是一个非object类型的值则不会造成这种情况

let MyClass = function(){
    this.name = 'shintaro'
    return 'Faker'    
}
let obj = new MyClass();
console.log(obj.name) //output:'shintaro'
  1. call/apply/bind call/apply/bind函数接受一个参数从而能够动态的改变传入函数运行时的this:
var obj1 = {
    name:'sven',
    getName:function(){
        return this.name;    
    }
}

	var obj2 = {
	    name:'anne'
	}
	console.log(obj1.getName()) // output:sven
	console.log(obj1.getName.call(obj2))// output:anne
  • call和apply都能接受第二个或是更多的参数作为运行指定函数时,所使用的参数并运行
  • bind函数同上,但是不会立即运行而是返回一个设置好this指针以及参数的函数 基本上通用的this情况就到此结束了,后续若有补充会继续更新。

创作不易,有帮助的朋友们麻烦点赞支持下