第86题 下面这道题输出什么

    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()
    getName()
    Foo().getName()
    getName()
    new Foo.getName()
    new Foo().getName()
    new new Foo().getName()
```**答案**

不要去读代码内部的东西,只是定义而已,而是要模拟执行代码(把自己当成`JS`引擎去执行)执行到再去看函数内部的东西
```js
    2 
    4
    1
    1
    2
    3
    3

解析

本题考察:

  • 声明提前,function(){}整体提前,var 变量 = xxvar 变量声明提前,= xx函数执行在赋值
  • 任何函数都是普通对象,都可以添加自己的属性
  • 任何函数都可以当做构造函数被new调用,且任何函数都有原型对象prototype属性,只不过大部分函数不是标准的构造函数内容而已
    function Foo(){
      // getName没有声明会在window全局自动创建getName变量
      getName = function(){ 
        console.log(1)
      }
      // new Foo的过程中如果返回了对象,则以返回的对象为准
      /**new的实现过程
       * function myNew(fn, ...args) {
        // 基于原型链 创建一个新对象,继承构造函数的原型对象(Person.prototype)上的属性
        let newObj = Object.create(fn.prototype);
        // 添加属性到新对象上 并获取obj函数的结果
        // 调用构造函数,将this调换为新对象,通过强行赋值的方式为新对象添加属性
        let res = fn.apply(newObj, args); // 改变this指向新创建的对象
    
        // 如果函数的执行结果有返回值并且是一个对象, 返回执行的结果, 否则, 返回新创建的对象地址
        return typeof res === 'object' ? res: newObj;
      }
      */
      return this
    }
    // 函数也是对象,也可以在对象上添加属性getName
    Foo.getName = function(){
      console.log(2)
    }
    Foo.prototype.getName = function(){
      console.log(3)
    }
    // var getName变量会被function声明给覆盖,函数执行的时候getName会重新赋值为{console.log(4)}
    var getName = function(){
      console.log(4)
    }
    // 声明会提前,函数声明优先于变量声明
    function getName(){
      console.log(5)
    }
    
    Foo.getName() // 调用Foo上的方法,返回2
    getName() // 4
    Foo().getName() // getName={console.log(1)} 此时Foo内部this指向window,调用全局的getName方法,返回1
    getName() // 1
    // new 函数() 任何函数都可以放到new后面,new要找到离它最近的一个()
    new Foo.getName() // 调用Foo上的方法,返回2
    new Foo().getName() // 调用Foo()返回值是this,在调用this上的getName()  调用Foo原型上的方法 ,返回3
    new new Foo().getName() // 返回3
Last Updated:
Contributors: leeguooooo