• 函数经典面试题


    方式1:一个构造函数,里面有个全局变量getName 指向一个匿名函数

    function Foo(){
        getName = function (){
        console.log(1);
        }
      return this;
    }

    方式2:构造函数的一个属性getName 指向一个匿名函数
    Foo.getName = function(){
      console.log(2);
    }

    方式3:构造函数的原型上有个getName方法
    Foo.prototype.getName = function (){
      console.log(3);
    }

    方式4:定义一个变量指向一个匿名函数
    var getName = function (){
      console.log(4);
    }

    方式5:声明一个叫getName的函数
    function getName(){
      console.log(5);
    }

    //请写出下面输出的结果

    Foo.getName();        //2

    getName();          //4

    Foo().getName();        //1

    getName();            //1

    new Foo.getName();        //2

    new Foo().getName();          //3

    new new Foo().getName();        //3

    接下来废话不多说,分析每个执行结果:

    ----->1. Foo.getName()

      此句为函数Foo的静态方法,输出结果为2.

    ----->2. getName()

       单独看此句首先想到的是一般会有个全局声明的函数方法,方式5"function getName(){}",但要放在这个上下文环境中,那肯定不一样了,因为还有个方式4"var getName = function(){}",这里要考察一个知识点,当定义的变量和声明的函数重名了怎么办?答:它们都会预解析,函数声明提前于变量声明,但是最终会被后者变量覆盖,so输出结果为4.

    ----->3. Foo().getName()

      此句有个执行顺序的,先执行方式1的Foo(),其相当于window.Foo(),故此this指向window,另外Foo()函数的第一句是getName = function(){}是一句函数赋值语句,注意它没有var声明,是一个全局变量,如果先执行window.getName()结果是4,如果先执行Foo()会返回一个window,那此时

    此时方式4已经被覆盖了,所以下面再执行全局getName()就都是结果为1了。

    ----->4. getName()

      此处跟执行的Foo().getName()有关,因为这个变量已经被Foo函数执行时修改了,所以结果为1

    ----->5. new Foo. getName()

      此句首先还是看下运算符的优先级吧,结果大概就是(new Foo()> Foo() > new Foo)相当于new (Foo.getName)();

    先运算方式函数调用Foo.getName(),静态调用,回到方式1的执行语句了,结果为2,再new一个Foo实例对象,实际上将getName函数作为了构造函数来执行,结果为2

    ----->6. new Foo(). getName()

      此句先看运算符相当于(new Foo()).getName(),先指向Foo函数,而此时Foo作为构造函数却有返回值,所以这里需要说明下js中的构造函数返回值问题

    构造函数返回值

     在传统语言中,构造函数不应该有返回值,实际执行的返回值就是此构造函数的实例化对象。

    而在js中构造函数可以有返回值也可以没有

    1.没有返回值则按照其他语言一样返回实例化对象

    2.若有返回值则检查其返回值是否为引用类型,如果是非引用类型,如基本类型(string,number,boolean,null,undefined)则与无返回值相同,实际返回其实例化对象

    3.若返回值是引用类型,则实际返回值为这个引用类型

    原题中返回的是this,而this在构造函数中本来就代表当前实例化对象,所以Foo函数返回实例化对象。

    之后调用实例化对象的getName函数,因为在Foo()构造函数中没有为实例化对象添加任何属性,所以到当前对象的原型对象(prototype)中寻找getName,所以找到了,结果为3.

    ----->7. new new Foo(). getName()

      同样先运用优先级问题,实际相当于new ((new Foo()).getName)();

    先初始化Foo的实例化对象,然后将其原型上的getName函数作为构造函数再次被new,结果为3

  • 相关阅读:
    [XJOI]noip43 T2多人背包
    Codeforces Round #198 (Div. 2)E题解
    [XJOI]noip40 T2统计方案
    Codeforces Round #198 (Div. 2)C,D题解
    Codeforces Round #198 (Div. 2)A,B题解
    9.19[XJOI] NOIP训练37
    9.18[XJOI] NOIP训练36
    kmp算法详解
    [模板系列] AC自动姬
    luogu1967[NOIP2013D1T3] 货车运输 (最大生成树+LCA)
  • 原文地址:https://www.cnblogs.com/itsmart/p/11322228.html
Copyright © 2020-2023  润新知