this指向问题

导语

首先,如果搜索:js中this的指向问题

必然会得到这个结论:this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定,this最终指向调用它的对象。

但是发现有时候只依靠这句话还是会在判断this指向的时候出现问题。今天通过几个例子彻底搞懂this指向问题。

例子1

function flora(){
    var Animal = "?";
    console.log(this.Animal); //undefined
    console.log(this); //Window
}
flora();
复制代码

实际上,这里调用flora();是由window对象调用的,把flora();改成window.flora();控制台打印的同样是Window。

例子2

var flora = {
    Animal:"?",
    say:function(){
        console.log(this.Animal);  //?
    }
}
flora.say();
复制代码

this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定,这里flora调用了say,所以this指向对象flora

例子3-1

var flora = {
    Animal:"?",
    say:function(){
        console.log(this.Animal);  //?
    }
}
window.flora.say();
复制代码

例子3-2

var flora = {
    Animal:"?",
    mars:{
        Animal:"?",
        say:function(){ 
            console.log(this.Animal);  //?
    	}
    }
}
flora.mars.say();
复制代码

例子3-1的this竟然没有指向window,例子3-2的this竟然没有指向flora,不是说this最终指向调用他的对象吗?!! 结论竟然失效了,其实也不是,对于这种多层调用的情况

一个含有this的函数不管被多少花里胡哨的对象调用,this也只是指向它上一级的对象

例子4

var flora = {
    Animal:"?",
    mars:{
        Animal:"?",
        say:function(){ 
            console.log(this);   //window
            console.log(this.Animal);  //undefined
    	}
    }
}
var pink = flora.mars.say;
pink();
复制代码

…fá生了什么,this怎么指向了window? 别急,想想我们的理论:this最终指向调用它的对象;

什么时候调用了它?是不是pink()的时候,这个跟上面的?不一样,上面的例子直接执行了say;

没有哪一句话可以让我们直接判断this指向,分析的时候小心一点就可以啦(⁎⁍̴̛ᴗ⁍̴̛⁎)

例子5-1

function flora(){
    this.animal = "?";
}
var blue = new flora();
console.log(blue.animal); //?
复制代码

这里blue对象之所以可以打印出函数flora里面的animal是因为new可以改变this的指向

其实可以这么理解,我们在var blue = new flora();的时候,复制了一个florablue里面

注意⚠️这个时候并没有执行,而调用的时候是blue对象,所以this指向的就是blue

为什么blueanimal属性,因为flora已经复制到了blue对象中。

如果构造函数有返回值呢?⬇️

例子5-2

function flora(){
    this.animal = "?";   
    return {}
}
var blue = new flora();
console.log(blue.animal); //undefined

function flora(){
    this.animal = "?";   
    return function(){};
}
var blue = new flora();
console.log(blue.animal); //undefined
复制代码

返回的是一个对象,this指向的就是那个返回的对象;

例子5-3

function flora(){
    this.animal = "?";   
    return 1;
}
var blue = new flora();
console.log(blue.animal); //?

function flora(){
    this.animal = "?";   
    return undefined;
}
var blue = new flora();
console.log(blue.animal); //?
复制代码

如果返回的不是对象,this还是指向这个函数的实例

例子5-4

function flora(){
    this.animal = "?";   
    return null
}
var blue = new flora();
console.log(blue.animal); //?
复制代码

比较特别的是:虽然null属于对象,但是返回null依然指向函数实例

Null类型只有一个值的数据类型,这个特殊值是null。从逻辑角度来看,null值表示一个空对象指针,这也是使用typeof操作符检测null值时会返回"object"的原因

补充

  1. 箭头函数:箭头函数本身是没有this,但我们用到this的时候,他会找定义函数时所处环境的this.
  2. 在严格模式下,默认的this不是window,是undefined。(使用了"user strict"启用严格模式)
  3. new之所以可以改变this的指向,跟apply有关,还有其他方法可以改变this指向,后续文章会提到

给大家做两道测试题吧!?

测试题

测试题1

 var animal = '?';
 function flora() {
    var animal = '?';
    console.log(this.animal);
 }
 window.flora(); 
 
 var obj = {
    animal: '?',
    say: function() {
        console.log(this.animal);
    }
 }
 obj.say(); 
 
 var mrz = obj.say;
 window. mrz();
复制代码

答案:? ? ?

测试题2

 var animal = '?';
 (function() {
    var animal = '?';
    console.log(this.animal);
 })()
 
 function flora() {
    var animal = '?';
    function mrz() {
        console.log(this.animal);
    }
    mrz(); 
 }
 flora();
复制代码

答案:? ?

  1. 因为匿名函数没有名字,所以就挂给window
  2. 谁调用mrz那么就指向谁,它不是window调用的,也不是flora调用的,没有人管它,那么它就指向window,无主函数

转载于:https://juejin.im/post/5cf395bbe51d455a2f220216

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值