美文网首页
[前端基础]一道前端小题的简单分析

[前端基础]一道前端小题的简单分析

作者: 捡了幸福的猪 | 来源:发表于2021-08-04 20:47 被阅读0次

    有这样一道前端小题, 问输出什么:

    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();  // Q1
    getName();// Q2
    Foo().getName(); // Q3
    getName();// Q4
    new Foo.getName();// Q5
    new Foo().getName();// Q6
    new new Foo().getName();// Q7
    

    回答:
    1、 Q1
    答案:2。 Foo.getName 为调用Foo的静态方法

    2、 Q2
    答案:4。function getName() {} 的写法为函数声明式写法。 var getName = function() {} 为函数表达式写法

    JavaScript 解释器中存在一种变量声明被提升的机制,也就是说函数声明会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是会被提升至最前面。而用函数表达式创建的函数是在运行时进行赋值,且要等到表达式赋值完成后才能调用。 即函数声明在JS解析时进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用。而函数表达式的值是在JS运行时确定,并且在表达式赋值完成后,该函数才能调用。

    所以function getName() {} 会提升至顶部, 运行时 被var getName = function() {} 覆盖

    3、 Q3
    答案: 1。Foo() 执行, getName 为全局变量; Foo()返回this , this 指向window , Foo() .getName 为 window.getName

    4、 Q4
    答案: 1。 直接调用getName函数,相当于window.getName(),getName 已经被第3步修改

    5、Q5

    答案: 2 。 此处涉及符号优先级问题。 image.png

    对于new Foo.getName() , new Foo 为 「new 无参数列表」 优先级在表格中为18,Foo.getName 为成员访问,优先级为19 ;所以 new Foo.getName() 的执行为 new (Foo.getName)()

    6、 Q6
    答案:3 。 new Foo().getName() 按优先级判断为 (new Foo()).getName()
    new Foo() 为Foo的实例,返回的是this,而this在构造函数中本来就代表当前实例化对象,最终Foo函数返回实例化对象。 即实例化对象的getName 方法,实例方法中没有,去原型上查找,故为3

    7、 Q7
    答案:3。 Q7 是Q5 与Q6问题的组合, 相当于

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

    其他小知识:

    1、JS中构造函数可以有返回值也可以没有。

    • 如果没有返回值,则返回实例化对象。
    • 若有返回值则检查其返回值是否为引用类型。如果是非引用类型,如基本类型(String,Number,Boolean,Null,Undefined)则与无返回值相同,实际返回其实例化对象。
    • 若返回值是引用类型,则实际返回值为这个引用类型。

    hi 今天的你点赞了没~~

    相关文章

      网友评论

          本文标题:[前端基础]一道前端小题的简单分析

          本文链接:https://www.haomeiwen.com/subject/ycojvltx.html