前端面试题 - 66. 静态方法、构造函数优先级

86 阅读2分钟
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

解释如下:

  • 首先执行 Foo.a(),输出结果为 4。因为 Foo.a 是一个静态方法,直接执行 Foo.a() 会输出 4。

  • 接着执行 let obj = new Foo(),此时会创建一个新的对象 obj 并调用构造函数 Foo。在构造函数中,定义了两个方法 this.aFoo.a。在 obj.a() 中,this.a 会优先调用实例方法,因此输出结果为 2。

  • 最后执行 Foo.a(),输出结果为 1。因为在 Foo 中重新定义了 Foo.a 方法,覆盖了原先的静态方法,所以此时调用静态方法会输出 1。

这段代码考察的是 JavaScript 中的函数和对象的相关知识。具体来说,需要了解以下几个方面:

  1. JavaScript 中的函数有两种类型:函数表达式和函数声明。函数声明会被提升到作用域的顶部,可以在函数声明之前调用。而函数表达式则需要在声明之后才能调用。
  2. JavaScript 中的对象有两种类型:实例对象和构造函数对象。实例对象是由构造函数对象通过 new 关键字创建的,可以拥有自己的属性和方法。而构造函数对象本身也是一个对象,可以拥有自己的属性和方法。
  3. 在 JavaScript 中,可以给对象动态添加属性和方法。通过 this 关键字添加的属性和方法会成为实例对象的属性和方法,而通过构造函数对象本身添加的属性和方法则会成为静态属性和方法。
  4. 在 JavaScript 中,方法的调用顺序是优先调用实例方法,如果不存在再调用静态方法。如果实例方法和静态方法同名,则优先调用实例方法。