一道涉及构造函数、变量提升、非严格模式的笔试题,讲讲自己学到的

        今天在做面试题的时候碰到一道题,感觉涉及的知识点还挺多的,想着谈一谈自己学到的东西,也算是学以致用吧。

        目前本人还在学习中,如果讲错了或者需要补充的欢迎请大家指正,谢谢!

        面试题出自:牛客最新前端JS笔试百题 - 掘金中的程序题,如有侵权,请及时联系,第一次写blog,请见谅。

        话不多说,上题:

        下列程序的输出结果是多少?你能理清楚test函数的this指向吗?


var a = 5;
 function test() { 
    a = 0; 
    alert(a); 
    alert(this.a); 
    var a;
    alert(a); 
}
new test();

解题过程:        

        初看这道题的时候,有一点困惑,为什么构造函数的函数名首字母没有大写?在网上搜了一下,原来还真有别人问过JS里构造函数首字母不大写有什么影响-前端-CSDN问答,觉得挺有道理的,如果有更好的答案,请分享一下,互相进步,上述链接得出的结论如下:     

        JS里构造函数首字母不大写有什么影响没任何影响,只不过一般大写,这是一个规范,普通函数首字母是小写,为了区别构造函数首字母大写。

        接着看题,

        先看new test(),因为new关键字会创建一个对象实例,而里面的this指向这个实例对象。

var a = 5;
 function test() {

        console.log(this);    // test{}    this指向了一个空对象实例
         a = 0;         //非严格模式下,a可以先赋值,再声明,a存在变量提升的情况
         alert(a);     // 0
        alert(this.a);     // undefinded 
        var a;
        alert(a);     // 0
}
new test();

console.log(a);    // 5  从这里也可以证明a不是全局变量,因为如果函数中的a=0位全局变量的话,那么这个打印输出的结果就应该为0才对

        学过构造函数的都知道,要想给构造函数添加属性或方法,需要用到this.xxx=ccc或者this.xxx=function(){}格式来赋值操作,如果未赋值就使用了,就会得出undefined结论,所以可以看出上述题目中的this.a为undefined。

        至于上述题目中的两个a结果为什么为0?个人理解如下。

       在test函数中,a=0在var a之前,赋值在声明之前,非严格模式下是允许的;在第一个alert(a)中,根据就近原则,往上查找,找到了a=0,所以第一个alert(a)结果为0;然后程序来到了alert(this.a)得出undefined(this.a未定义,所以报undefined);程序执行到第二个alert(a),也是往上寻找a的值(a存在变量提升的情况),找到了a=0,所以第二个alert(a)结果也为0。

        下面还有两个小例子,

\\1.

var a = 5;
 function test() {

        console.log(this);    // test{}    this指向了一个空对象实例
         a = 0;                   //只要在一个函数中有声明a,则这个a=0就不是全局变量,存在变量提升
         alert(a);     // 0
        alert(this.a);     // undefinded 
        var a=12;
        alert(a);     // 12  这个a会根据就近原则往上查找,离它最近的是12,所以为12
}
new test();

console.log(a);    //5 

//2.函数中未声明变量但是赋了值的,则注意为全局变量

var a = 5;
 function test() {

        console.log(this);    // test{}    this指向了一个空对象实例
         a = 0;         //因为在函数中未声明a,所以a=0为全局变量
         alert(a);     // 0
        alert(this.a);     // undefinded 
}
new test();

console.log(a); /// 0   因为在test函数中未声明a,所以test函数中的a=0为全局变量

综上所述题目的答案为:

        下列程序的输出结果是多少?------0 undefined 0  

        你能理清楚test函数的this指向吗?-------test函数中的this指向实例对象test{}

知识总结:

1)new关键字会创建一个对象实例,而里面的this指向这个实例对象;如果要声明属性和方法,需要用到this.xx=cc或者this.xx=function(){}来声明;

2)构造函数首字母不大写有什么影响没任何影响,只不过一般大写,这是一个规范,普通函数首字母是小写,是为了区别构造函数首字母大写(最好按规范走);

3)函数中,如果未声明变量但是赋了值的,则注意为全局变量;

      如果先赋值了,下面再声明,则注意为非严格模式,存在变量提升(注意声明的关键字不能为let和const等)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值