原文:请写出如下代码的打印结果 - 每天一个JavaScript小知识@Js中文网 · 码农进阶题库

原文地址:https://www.javascriptc.com/interview-tips/zh_cn/javascript/printed-results-of-the-code/

题目描述:

  • 请写出如下代码的打印结果:
    function Foo() {
      Foo.a = function() {
          console.log(1)
      }
      this.a = function() {
          console.log(2)
      }
    }
    Foo.prototype.a = function() {
      console.log(3)
    }
    Foo.a = function() {
      console.log(4)
    }
    Foo.a();
    let obj = new Foo();
    obj.a();
    Foo.a();
    

解题:

  • 思路一:

  • 输出顺序是 4 2 1 . ```javascript function Foo() { Foo.a = function() { console.log(1) } this.a = function() { console.log(2) } } // 以上只是 Foo 的构建方法,没有产生实例,此刻也没有执行

Foo.prototype.a = function() { console.log(3) } // 现在在 Foo 上挂载了原型方法 a ,方法输出值为 3

Foo.a = function() { console.log(4) } // 现在在 Foo 上挂载了直接方法 a ,输出值为 4

Foo.a(); // 立刻执行了 Foo 上的 a 方法,也就是刚刚定义的,所以 // # 输出 4

let obj = new Foo(); /* 这里调用了 Foo 的构建方法。Foo 的构建方法主要做了两件事:

  1. 将全局的 Foo 上的直接方法 a 替换为一个输出 1 的方法。
  2. 在新对象上挂载直接方法 a ,输出值为 2。 */

obj.a(); // 因为有直接方法 a ,不需要去访问原型链,所以使用的是构建方法里所定义的 this.a, // # 输出 2

Foo.a(); // 构建方法里已经替换了全局 Foo 上的 a 方法,所以 // # 输出 1 ```

  • 思路二:

  • 答案为:4, 2, 1
  • 解析:

  • 1,Foo.a() 这个是调用 Foo 函数的静态方法 a,虽然 Foo 中有优先级更高的属性方法 a,但 Foo 此时没有被调用,所以此时输出 Foo 的静态方法 a 的结果:4
  • 2,let obj = new Foo(); 使用了 new 方法调用了函数,返回了函数实例对象,此时 Foo 函数内部的属性方法初始化,原型方法建立。
  • 3,obj.a(); 调用 obj 实例上的方法 a,该实例上目前有两个 a 方法:一个是内部属性方法,另一个是原型方法。当这两者重名时,前者的优先级更高,会覆盖后者,所以输出:2
  • 4,Foo.a(); 根据第2步可知 Foo 函数内部的属性方法已初始化,覆盖了同名的静态方法,所以输出:1

  • 思路三?:

:point_down:~~~~ 欢迎在下方评论补充你的答案,一起来学习~:pushpin:

扩展阅读: