zoukankan      html  css  js  c++  java
  • 一道面试题 包含了new的细节 和运算符的优先级 还有属性访问机制

     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.首先是变量提升

       变量提升包括var 声明的变量和fucntion 声明

       举个例子

          1.var a=4; 

          2.function test(){

           console.log(456);

         };

         

       函数变量声明会先于普通变量之前,并且不会被后面的同名覆盖

       但是会被后面的同名赋值覆盖!

       就是 function a(){};

           var a;

           这样不会覆盖函数a

           但是如果 var a=4;

           函数a就会被覆盖

          接下来从第一个开始分析

             Foo.getName();

    首先变量提升之后是这个样子滴

    //变量提升

              第一题function Foo(){

                     getName = function () { alert(1); }//foo函数执行的时候 会覆盖全局中的getName
                     return this;

                     /* 

                          new 运算符的时候会执行以下

                          var obj={};//创建一个空对象

                          将构造函数的作用域赋给新对象

                          这个新对象的内置原形指向构造函数的原形对象

                          obj.__proto__=Foo.prototype;

                          执行构造函数中的代码

                          返回这个对象(如果显示返回基本数据类型 无效 还是会返回这个对象

                                      如果返回的是引用类型 那么这个对象将没用了)

                         

                   */

                  }

               //变量提升

              //2.function getName () { alert(5); }

             //变量提升

               3.var getName;


               4.Foo.getName = function () { alert(2); }
               5.Foo.prototype.getName = function () { alert(3); }
               6.getName = function () { alert(4); }

               之前的2 会被6覆盖 所以2就可以注释掉了

              第二题 Foo.getName(); //弹出窗口值为2 不用解释了吧
    第三题 getName();//弹出窗口值为4
    第四题 Foo().getName();

    先执行Foo();
    里面的getName=function(){alert(1);} 会覆盖全局作用域中的6
    因为是在全局作用域下调用Foo函数 所以this就是window
    window.getName(); //弹出窗口值为6

    第五题 new Foo.getName();

    new (Foo.getName)(); //弹出窗口值为2
    笨想:肯定不会是执行Foo.getName 之后才new 会报错
    优先级问题 .(成员访问的优先级高于new 并且从左到右
    于是就把Foo.getName这个函数当做构造函数执行
                                

    第六题
    new Foo().getName();
    .运算符从左到右
    new Foo(); 返回一个Foo类型的对象 {}
    {}.getName();
    找不到 然后去构造它的函数Foo的prototype上找
    Foo.prototype.getName = function () { alert(3); }
    所以结果 3


    第七题
    也是运算符优先级的问
    new new Foo().getName(); 在这里面.的优先级最高
               new ((new Foo()).getName)(); 
    先执行.左 然后.右
    先执行Foo(); 然后new 返回一个Foo类型的对象
    然后得到getName的函数体
    然后当做构造函数执行 alert(3) 然后返回一个Foo.getName类型的对象


    可能有些地方不是让所有人懂
    毕竟我也是一直菜鸟


    // Foo.getName(); //2
    // getName(); //4
    // Foo().getName(); //1
    // getName(); //1
    // new Foo.getName();//2
    // new Foo().getName();//3
    // new (new Foo().getName)()//3;

    优先级

    运算类型

    关联性

    运算符

    20

    圆括号

    n/a

    ( … )

    19

    成员访问

    从左到右

    … . …

    需计算的成员访问

    从左到右

    … [ … ]

    new (带参数列表)

    n/a

    new … ( … )

    函数调用

    从左到右

    … ( … )

    18

    new (无参数列表)

    从右到左

    new …

    17

    后置递增(运算符在后)

    n/a

    … ++

    后置递减(运算符在后)

    n/a

    … --

    16

    逻辑非

    从右到左

    ! …

    按位非

    从右到左

    ~ …

    一元加法

    从右到左

    + …

    一元减法

    从右到左

    - …

    前置递增

    从右到左

    ++ …

    前置递减

    从右到左

    -- …

    typeof

    从右到左

    typeof …

    void

    从右到左

    void …

    delete

    从右到左

    delete …

    15

    从右到左

    … ** …

    14

    乘法

    从左到右

    … * …

    除法

    从左到右

    … / …

    取模

    从左到右

    … % …

    13

    加法

    从左到右

    … + …

    减法

    从左到右

    … - …

    12

    按位左移

    从左到右

    … << …

    按位右移

    从左到右

    … >> …

    无符号右移

    从左到右

    … >>> …

    11

    小于

    从左到右

    … < …

    小于等于

    从左到右

    … <= …

    大于

    从左到右

    … > …

    大于等于

    从左到右

    … >= …

    in

    从左到右

    … in …

    instanceof

    从左到右

    … instanceof …

    10

    等号

    从左到右

    … == …

    非等号

    从左到右

    … != …

    全等号

    从左到右

    … === …

    非全等号

    从左到右

    … !== …

    9

    按位与

    从左到右

    … & …

    8

    按位异或

    从左到右

    … ^ …

    7

    按位或

    从左到右

    … | …

    6

    逻辑与

    从左到右

    … && …

    5

    逻辑或

    从左到右

    … || …

    4

    条件运算符

    从右到左

    … ? … : …

    3

    赋值

    从右到左

    … = …

    … += …

    … -= …

    … *= …

    … /= …

    … %= …

    … <<= …

    … >>= …

    … >>>= …

    … &= …

    … ^= …

    … |= …

    2

    yield

    从右到左

    yield …

    yield*

    从右到左

    yield* …

    1

    展开运算符

    n/a

    ... …

    0

    逗号

    从左到右

    … , …

  • 相关阅读:
    javascript设计模式(一)职责链模式China of responsibility
    javascript设计模式(一)策略模式Strategy
    angularjs提示消息弹出框
    Javascript设计模式(一)States
    Javascript设计模式(一)Facade
    NOIP2020
    RMQ & ST表
    NOI Linux
    初赛解析
    贪心大解析
  • 原文地址:https://www.cnblogs.com/liveoutfun/p/9689873.html
Copyright © 2011-2022 走看看