zoukankan      html  css  js  c++  java
  • js经典面试题之Foo.getName

    为什么会花一上午的时间来总结这道题呢?

    原因是这样的:最近一直在准备面试的东西,也在B站学习(注意是学习!学习!学习!),看到尚硅谷分享的这道js面试题,当前学到了很多。

    昨天晚上接到字节hr的电话,预约下周的一面面试。对于我这个菜鸟来讲,当然是得去牛客网刷刷面经辣(哭脸)

    当当当当~~~~眼前一亮(这道题似曾相识啊!!!于是我翻手机相册翻到了截图(本人喜欢将一些知识点截图,蹲厕所的时候刷刷相册。哈哈哈,据说,上厕所时看知识最容易记住呢!)以下是证据(说话做事凭证据~)废话不多说,让我们一起愉快的学习吧。

    题目如下:我又修改了以下,添加了两行代码

       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 Foo().getName();
    (new Foo()).getName(); 

    new new Foo().getName()

    首先你要清楚,面试官考察的知识点(预解析,原型链,this)。面试官也是够狠的,区区十几行代码考察这么多知识点!

    下面开始梳理解题过程:

    预解析结果:(变量和函数声明提升,赋值不提升,再赋值前调用返回undefined,当变量和函数重名时,优先保留函数)

    先预解析第一个函数:

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

    碰到:

    var getName = function () { alert(4); };   =》将getName声明提前,就剩下  getName = function(){alert(4)}
      function Foo() {
          getName = function () { alert(1); };
          return this;
        }
       var getName

    碰到:

    function getName() { alert(5); }
      function Foo() {
          getName = function () { alert(1); };
          return this;
        }
       var getName;
       function getName() { alert(5); 

    以上就是预解析过程,接下来执行代码:

    碰到

    getName = function(){alert(4)},将预解析中的function getName() { alert(5); 重新赋值
    此时代码为:
      function Foo() {
          getName = function () { alert(1); };
          return this;
        }
       var getName;
        Foo.getName = function () { alert(2); };
        Foo.prototype.getName = function () { alert(3); };
        getName = function () { alert(4); };

    接下来,执行语句:

    第一条语句:

    Foo.getName(); 

    找Foo函数找到getName方法    找到Foo.getName = function () { alert(2); }; 打印输出2

    第二条语句:

    getName();  

    找到getName = function () { alert(4); }; 打印输出4

    第三条语句:

    Foo().getName();

    首先明白一件事,运算符的优先级(点.的优先级高),但是因为()括号无法.点调用所以先将Foo函数执行完再去执行.getName()方法
    等价于(Foo()).getName(); 先看Foo函数,一个全局变量getName,一个return this,
    所以此时的getName再次被重新赋值
    function Foo() {
          getName = function () { alert(1); };
          return this;
        }
       var getName;
        Foo.getName = function () { alert(2); };
        Foo.prototype.getName = function () { alert(3); };
        getName = function () { alert(1); };

    Foo返回this,返回的就是调用Foo函数的对象那么是谁调用了Foo函数呢?很明显是window大哥,所以Foo函数的运行结果为window

    所以(Foo()).getName() 等价于window,getName(),好了,你在全局找getName方法吧,getName = function () { alert(1); };,打印输出1

    第四条语句:

    getName():

    等价于window.getName();这不就是和上一步一样吗,getName = function () { alert(1); };,打印输出1

    第五条语句:

    new Foo.getName()

    还是那句话,点.的优先级高,先执行 那么就等价于 new(Foo.getName)(),问题来了,Foo.getName是什么呢?聪明的你应该已经发现了:
     Foo.getName = function () { alert(2); };
    也就是说 new(Foo.getName)() = new ( function () { alert(2); };){} ,小二又向你无情的抛出了一个知识点:new函数调用时,会执行这个函数,所以打印输出2

    第六条语句:

    new (Foo.getName)();

    你看她像不像第五题呢?,结果和第五条语句一样,输出结果为2

    第七条语句:

     

    new Foo().getName();

    还是那句话:尽管.的优先级高,但()并不能.调用,所以会将new Foo()的值求出来再去.getName
     (new Foo()).getName()-->new关键字最后会生成一个实例对象foo.getName()
    实例对象如何去找到对应的属性?(沿着隐式原型链__proto__,先去自身,再去__proto__,直到Object,直到都没有找到就返回undefined)
    找到  Foo.prototype.getName = function () { alert(3); };  打印输出3

    第八条语句:

    (new Foo()).getName();

    你看他像不像第七题呢?结果和第七条语句一样,输出3

    第九条语句:

    new new Foo().getName()

    new ((new Foo()).getName)() => new (foo.getName)()
    new (function () { alert(3); };)() ,直接执行new的函数,打印3
     
     
  • 相关阅读:
    MySql常用命令
    PHP截断函数mb_substr()
    explode() 字符串转换数组
    php取得当前时间函数
    Apache与Nginx的比较
    thinkphp5.0环境变量配置
    thinkphp5.0配置作用域
    thinkphp5.0动态配置
    Mac 下查看 Android Studio 的 SHA1的方法
    Mac 下 gradle 路径
  • 原文地址:https://www.cnblogs.com/yaya-003/p/12887535.html
Copyright © 2011-2022 走看看