一道掉头发的前端JS输出题

这道题涉及到了作用域,this,原型,构造函数,变量声明提升,运算优先级

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

// 请写出以下输出结果;
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

1.第一问

Foo.getName(), 即执行第五行,FoogetName方法。 输出 2.

2.第二问

getName() 直接调用 全局的 getName函数。那是4还是5呢?第七行与第八行关于getName的声明有什么不同呢?

  • 第七行的var getName = function(){alert(4)}函数表达式
  • 第八行的function getName(){alert(5)}函数声明
  • 函数表达式 会被拆解为 变量声明 + 变量赋值
  • 由于由于变量声明提升的关系,变量声明 和 函数声明 会被提升至最上方(肯定在同作用域的赋值操作之前)。

所以七八行的相对执行顺序改写为如下

var getName; // 原第七行拆解出来的 变量声明
function getName(){alert(5)}; // 原第八行的函数声明
getName = function(){alert(4)}; // 原第七行拆解出来的赋值 (值是函数)

显然,第二问 getName()的输出是4。

3.第三问

Foo().getName() 字面意思是 Foo()函数执行完的返回值的getName()方法的调用。

  • Foo()的返回值由第一行可知是this,因为Foo()是在全局下调用的所以这里的thiswindow
  • 那么Foo().getName即全局作用域下的getName
  • 由于此刻Foo()的执行。Foo()里面的未声明的getName的作用域(本作用域里没有)会指向上一层即全局。所以会覆盖之前的

所以 第三问的Foo().getName() 的输出是1。

4.第四问

getName(),由第三问可知,至此全局(即window)的getName 应该是在Foo()函数体内所定义的。
所以第四问的getName()的输出也是1.

5.第五问

new Foo.getName 显然这里包括第六七问都涉及到了运算符的优先度的问题。是(new Foo).getName呢?还是new (Foo.getName)呢。
这里需要先补充一下JS运算符优先级。参照
在这里插入图片描述
显然本问的 new 无括号(无参数),比. 优先级低,所以第五问等价于new (Foo.getName) 所以先执行Foo.getName 再创建其实例。输出是2。

第六问

new Foo().getName(),由上一问的优先级知识可知 new有括号(有参数)与.处于同一优先级,从左往右运算。所以应该等价于(new Foo()).getName。 显然这里以构造函数Foo() new 出一个实例对象。由于本身(new Foo())就是一个空对象,所以需要从Foo的原型上查找getName方法。
所以第六问的输出是3。

第七问

new new Foo().getName().首先由一元表达式由右向左的规则可知。先计算后面的new Foo().getName,表达式等价于new (new Foo().getName)()。 咦?为什么不是new (new Foo().getName())?

  • 这里需要试想一下:obj.method1()其实是个执行语句。obj.method 本身是个表达式(类似于函数声明)加上()之后才是执行它。而()的优先级最低。

所以第七问的输出也是3

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值