一道经典的js面试题getName

一、题目

面试某互联网大厂时遇到这道题,发现原来是一道经典原题,早知道就好好刷真题了,这里整理一下

function Foo() {
    getName = function () {
        console.log(1);
    };
    console.log('this is' + this)
    return this;
}
Foo.getName = function () {
    console.log(2);
};
Foo.prototype.getName = function () {
    console.log('baidu' && 'google');
};
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();
console.log('baidu' && 'google');
console.log('baidu' || 'google');

二、分析

1.整体分析

本题涉及到变量提升函数提升以及二者的优先级问题、运算符.、()、new 的优先级问题、原型链方法问题

2.变量提升和函数提升

函数提升优先级高于变量提升

3.运算符优先级

优先级:成员访问 > new > 函数调用,尽管 . 的优先级高,但 (). 这种情况下,() 并不能被 . 调用,因此,会先将 new Foo() 的值求出来再执行 .,应该不会有同学问为啥不把 new 、Foo、() 拆开来看吧?原因就是 new Foo() 是构造函数执行的方式,不能拆开,不熟悉的同学去补基础!
构造函数方式返回的结果是一个新的实例对象,所以 this 的值不再是调用它的那个。
在这里插入图片描述

4.逐句运行
  • 解析器走完一遍执行了变量提升和函数提升,先提升 gatName 变量到顶部,此时全局上有个 getName 的属性,值为 undefined, 又因为函数提升优先级比变量提升高,所以此时 getName 又变成了console.log(5) 的那个函数,随着代码的执行,对 getName 变量进行了赋值操作,因此这个变量的值又被改变成了console.log(4)这个函数
  • 开始执行 Foo.getName()
    是 Foo 函数的静态属性,指向一个匿名函数
  • getName()
    调用全局上的 getName 函数,这里的 this 就是 windows
  • Foo().getName()
    执行 Foo 函数后,在修改了全局变量 getName, 因为 getName 前没有 var. Foo 里返回的 this 是调用 Foo 函数的this,即 windows,再调用 windows 上的 getName,输出 1
  • getName();
    调用 windows 上的 getName 函数,输出1
  • new Foo.getName();
    实际上执行顺序是: new (Foo.getName) ()
    访问 Foo 的静态属性指向的函数,输出2
  • new Foo().getName();
    尽管.的优先级高,但()并不能被.调用,所以会将new Foo()的值求出来再去.getName。(有个小技巧,就是先找 ., 能调用就调用,不能就先执行与它最近的运算符,有new Foo()就一定是执行构造函数,不能拆开成 new Foo 和 (), 或者 new 和 Foo())。new Foo() 返回一个新的实例,即此时 Foo 函数内返回的 this 是指向那个新实例的。再调用这个实例的 getName 方法,就是调用原型链上的方法
  • new new Foo().getName();
    执行顺序:new ((new Foo()).getName)()
参考链接

一道经典的js面试题Foo.getName()

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值