zoukankan      html  css  js  c++  java
  • 一道关于JavaScript经典的笔试题

     

    原题:

    复制代码
    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 new Foo().getName();
    复制代码

    下面是我个人的分析:(先进行变量和函数的提升,在进行分析)

    复制代码
     1  function Foo(){
     2             getName = function(){//这里是函数表达式,但是没有使用var,执行的时候,会现在当前作用域查找有没有getName,如果有就返回,如果没有就想上找,直到直到全局作用域下,本例中,当前作用域没有,但是全局作用域中有var getName的声明,并且还有赋值,这个时候,会被他覆盖掉,变成getName = function(){console.log(1)};也就是覆盖了下面的getName = function(){console.log(4)};
     3                 console.log(1);
     4             }
     5             return this;
     6             }
     7       
     8         var getName;
     9         // Foo().getName();
    10         function getName(){console.log(5)};//函数声明,在函数提升的时候会把整个函数体提升
    11         Foo.getName = function(){console.log(2)};//给Foo中创建了一个getName的属性,并赋值了一个匿名函数
    12         Foo.prototype.getName=function(){console.log(3)};
    13         getName = function(){console.log(4)};//这里是赋值操作,会覆盖40行的函数声明
    14 
    15         Foo.getName();//2//访问Foo中的静态属性getName,也就是上面的赋值的匿名函数,所以输出的2
    16         getName();//4因为45的赋值操作覆盖了42行的函数声明,顾输出的是4
    17         Foo().getName();//1这里是这样操作的(Foo()).getName();我们可以看出Foo()属于window调用,this指向的就是window,
            他返回的this就是window,所以这里就相当于window.getName();window调用的时候会在当前作用域下找有没有getName,如果有就执行,
            这里全局环境的的赋值也就是getName = function(){console.log(4)};但是他已经被Foo中的getName覆盖了,变成了getName = function(){console.log(1)};
            所以这里输出的就是1;(注意这些覆盖是发生在调用的时候);;这里涉及this的问题 18 getName();//1、、由于上面的操作,getName = function(){console.log(4)};已经被覆盖成了getName = function(){console.log(1)};
                所以这里再直接访问getName()的时候,已经变了1 19 new Foo.getName();//2这里涉及的时候运算符的优先级,点的优先级高于new的优先级。所以先执行Foo.getName的操作,那就是输出2 20 new Foo().getName();//3这里也是优先级的问题,小括号的优先级最高,所以是(new Foo()).getName();那么就是先实例一个Foo的对象,然后去调用实例方法getName();
          根据属性搜索原则,先去构造函数中找,没有就上原型中去找,这里构造函数Foo中没有,但是原型中已经添加了getName = function(){console.log(3)};所以这里输出的是3 21 new new Foo().getName();//3//还是优先级的问题,应该是new ((new Foo()).getName)();先实例化Foo,在将Foo原型中的getName当成构造函数,
                        继续实例化,然后调用 22 // 这里我们写一个小demo 23 function fn(){ 24 setName = function(){console.log(1)}; 25 } 26 fn.prototype.setName= function(){console.log(2)}; 27 // new new fn().setName(); 28 // console.log(new((new fn()).setName)()); 29 new((new fn()).setName)();
    复制代码
  • 相关阅读:
    线上查询及帮助命令:
    windows: 2.7 3.5 (主要)
    get the execution time of a sql statement.
    java-kafka安装以及使用案例
    java-黑马头条 weex前端路由
    MYSQL安装
    缓存
    Flask中current_app和g对象
    [ValueError: signal only works in main thread]
    Flask-SQLAlchemy操作
  • 原文地址:https://www.cnblogs.com/zhou195/p/7521160.html
Copyright © 2011-2022 走看看