JS的this(普通函数谁调用就指向谁)
普通函数:
.this(上下文对象)
- 我们每次调用函数时,解析器都会将一个上下文对象作为隐含的参数传递进函数。
使用this来引用上下文对象,根据函数的调用形式不同,this的值也不同。就是谁调用,this就是谁。
- this的不同的情况:
1.以函数的形式调用时,this是window
2.以方法的形式调用时,this就是调用方法的对象
3.以构造函数的形式调用时,this就是新创建的对象
var name = "window:我好帅" function fun1(){ console.log(this.name); } var obj = { name:"obj:我好帅", say:fun1 } window.fun1(); fun1(); obj.say();
//以工厂方式或者构造函数的形式调用时,this就是新创建的对象
function create_obj(age,name){
运行结果:
总结:哪个对象调用this,this就指向谁。
所有全局变量,全局函数都是window这个对象的属性。
箭头函数的this指向:
this与它本身所在的位置有关,它在哪里就指向哪里。
*************************************************************************************************************
例子1:对象里面定义函数
var obj1 = { fun () { console.log(this); } }; var obj2 = { fun: function () { console.log(this); } } var obj3 = { fun: () => { console.log(this) } } obj1.fun(); //obj1 obj2.fun(); //obj2 obj3.fun(); //window
讲解
fun () {}
这是对象里面函数的简写跟,跟fun: function(){}
一样,两者的this指向都是最原始的,谁调用指向谁-
() => {}
箭头函数的this指向为 是他定义时的上一级作用域的this指向,也就是说箭头函数是在哪个作用域下定义的,他的this指向就是那个作用域的this指向,其中上一层作用域必须为函数作用域或者是全局作用域。如果找不到函数作用域,那么this默认指向window。
例子如下
var obj = { pro: { getPro: ()=>{ console.log(this); } } } obj.pro.getPro() //window
箭头函数是在getPRo这里定义的,他上一级是一个pro对象,这不是函数作用域,所以默认指向window。
例子2:对象里面定义普通函数,普通函数里面再嵌套箭头函数
var obj = { say: function() { var f1 = ()=>{ console.log("1111",this); } f1(); } } var o = obj.say; o();//输出window,o调用,所以this指向o所在的作用域,即全局作用域 console.log("***************") obj.say()//输出say,say调用,this指向say当前作用域
运行结果:
例子2对照组:对象里面定义箭头函数,箭头函数再嵌套箭头函数:
var obj = { say:()=>{ var f1 = ()=>{ console.log("1111",this); } f1(); } } var o = obj.say; o();//window console.log("***************") obj.say()//window
运行结果:
总结:
1.普通函数谁调用,this就指向谁;
2.箭头函数this,与箭头函数本身所在的位置有关,this指向的是上一级的非箭头函数所在的作用域,此作用域不是函数作用域就是全局作用域。
------------------------------------------------------------------------------------------
其实高级程序设计一书中提到,this的指向是与上下文对象有关的,上下文与作用域概念是不一样的,但是如果根据上面这些来决定this的指向,那么其实是没问题的,但是更严谨的写法,应该是this的指向是根据上下文对象决定的;
上下文与作用域的区别:
1.作用域是js代码定义时,就已经确定好的;
2.上下文是执行到哪里,上下文就创建到哪里,是动态生成的;而且上下文以我目前的知识水平,我觉得只有两个上下文,一个属于全局执行上下文,一个是函数执行上下文;
所有函数执行都是在执行上下文中执行的,当这个上下文中调用的是普通函数时,这个普通函数this指向的是这个上下文对象;当这个上下文调用的是箭头函数,那么箭头函数的this指向的是当时定义这个函数所在的那个上下文对象;
还是拿上面那个例子:getPro箭头函数定义在pro对象中,但是他不是上下文,obj也不是上下文,obj所在的上下文是window,所以实际上getPro是定义在全局上下文中的,此时this也是指向window;
var obj = { pro: { getPro: ()=>{ console.log(this); } } } obj.pro.getPro() //window