一道经典new new Foo().getName()面试题解析

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);
}
//请写出以下输出结果:
1.Foo.getName(); // 2
2.getName(); // 4
3.Foo().getName(); // 1
4.getName(); // 1
5.new Foo.getName(); // 2
6.new Foo().getName(); // 3
7.new new Foo().getName(); //3

 首先分析函数提升和变量提升,其实内部执行顺序是下面这样的。

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

1.Foo.getName();

直接找Foo.getName = function () {alert(2);}; 所以Foo.getName();为alert(2);

有同学会有疑问Foo不是一个函数吗,函数还可以当对象使用吗,是的在JavaScript中,函数拥有对象所拥有的全部功能。从下面的原型上就不难看出。

2.getName();

function getName() {
alert(5);
};
var getName = undefined
getName = function () {
alert(4);
};

因为执行顺序是这样的所以alert(5);被alert(4);覆盖了,所以getName()执行完答案应该是alert(4);

3.Foo().getName();

先执行Foo(),

function Foo() {
getName = function () {
alert(1);
};};

执行完之后getName = function () {alert(1);};全局getName被重新赋值,此时调用完之后返回this,这里的this因为是直接调用的指向window,也就是Foo().getName();等同于window.getName(),因为上面全局getName被重新赋值为alert(1);所以执行完成答案为alert(1);

4.getName();

因为执行完Foo().getName();全局getName函数被重新赋值为alert(1);所以执行getName();答案为alert(1);

5.new Foo.getName();

new (Foo.getName()),先执行 Foo.getName(),输出 alert(2);,然后new一个实例;


6.new Foo().getName();

这里等价于 (new Foo()).getName(), 先new一个Foo的实例,再执行这个实例的getName方法,所以去原型链__proto__上边找,实例.__proto__ === Foo.prototype,Foo.prototype.getName = function () {alert(3);};所以答案为alert(3);


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

可以解析为new (new Foo().getName) () 先new Foo().getName 此时getName没有被调用,然后调用先输出alert(3);,然后new 一个 new Foo().getName() 的实例。

这个题给我的感觉就是new与最近的()匹配去new一个实例,new实例过程中函数会执行一遍

比如以下new实例的过程

 function Chinese(name, age) {
            // Human.apply(this, [name]),
                this.color = 'yellow',
                this.age = age
                alert('aaa')
        }
  
        var aaa = new Chinese()

结果

 

好了本篇文章就到这里了,喜欢的话可以关注我,会持续更新的,有错误欢迎大家指出,大家可以在我这里互相讨论学习,一起进步。

青山不改 绿水长流 我们下篇文章见😋

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值