关于JS两道有意思的题--作用域与提升

本文探讨了JavaScript中函数声明、变量提升和作用域的概念。重点在于如何理解引擎对变量和函数的处理顺序,以及在不同场景下,如Foo.getName()、getName()和Foo().getName()的执行逻辑。同时,文章提到了new运算符的优先级问题,帮助读者理解new运算符与函数调用的结合方式。
摘要由CSDN通过智能技术生成

  第二道题是关于作用域和提升的。

  你应该知道声明都是会被提升的,即var声明跟function声明都会被提升到顶部。你也应该知道有两个操作,声明跟赋值,先声明再赋值。(不知道的话,就得好好在复习一下基础了。)

  基本流程:

var a = 2;

首先var a声明一个a变量,初始化为undefined,提升到顶部,就像

var a;
a = 2;

两者是一个意思。然后再对a进行赋值。这有个过程

引擎:作用域,你见过a吗?

作用域:见过,编译器刚声明过这个a变量,拿去用吧!

引擎:好嘞,我给它赋值下。

你还得知道的是,函数优先提升。

var a = 2;
function a(){
	console.log(1);
}
a//2
函数声明被优先声明到顶部,然后被变量声明覆盖!

好了,接下来看这道题

function Foo() {
    getName = function () { 
    	console.log('1');
    };
    return this;
}
Foo.getName = function () {
	console.log('2');
};
Foo.prototype.getName = function () { 
	console.log('3');
};
var getName = function () { 
	console.log('4');
};
function getName() { 
	console.log(5);
}

Foo.getName();  
getName();	
Foo().getName(); 
getName();  
new Foo.getName(); 
new Foo().getName();   
new new Foo().getName();
首先我们可以看到,被提升的有函数声明Foo(),Foo.getName,Foo.prototype.getName,getName,函数声明getname()。

注意这里只是声明,没有赋值,只是让引擎能找到这些东西。

Foo.getName()引擎问作用域有这个吗?作用域回答有!然后就运行函数,Foo.getName(),输出2。

同理,getName()输出4;

Foo().getName()运行的时候在Foo()作用域中没有getName这个的声明,所以当引擎对getName进行赋值操作时,发现没有这个变量存在,没有是吗?没有就给你声明一个嘛,就立刻声明一个getName的全局变量(注意,覆盖了原先的全局变量getName)。这里输出1。

所以再次调用getName()的时候,它已经被Foo中的那个getName覆盖了,也输出1。

后面三题,我看到的时候奇怪了。虽然我知道new声明,但我之前接触的都是new 一个构造函数,这种new 一个“属性”的我还是第一次见。所以它到底是new 了个什么东西,我都搞不明白,还好原博主贴了张运算符优先级表(如下)点击内容或者外部自动关闭图片预览


所以上面三个其实就是

new (Foo.getName)();

(new Foo()).getName();

new ((new Foo()).getName)();

第一个就是new 了个Foo.getName函数,所以输出的还是2;

第二个就是new了个Foo()然后调用getName方法,注意这里new后新对象是没有getName方法的,所以它要跟着原型链去找getName方法,就是调用Foo.prototype.getName,所以输出3;

第三个就是对第二个又new了一次,还是输出3。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值