在构造函数中,定义Foo.a,直接调用Foo.a之后获取到了什么

 一道面试题:

function Foo() {
    Foo.a = function () {console.log(1)};
    this.a = function () {console.log(2)};
}

Foo.prototype.a =  function () {console.log(3)};
Function.prototype.a =  function () {console.log(4)};
Foo.a();
let obj = new Foo();
obj.a();
Foo.a();


输出结果为
 

4
2
1

结合原型链回看此题目
在构造函数中,定义Foo.a,直接调用Foo.a之后获取到了什么

        沿着原型链向上寻找 是通过 __proto__ 属性完成的,在使用 new 关键字时,会执行一步 obj.__proto__ = Foo.prototype 来绑定原型对象。
        第一个 Foo.a():由于此时 Foo 未被执行 函数内的Foo.a还未被调用;我对原型链的理解不深, Foo.prototype.a 误导了我的思维,以为会从原型链向上找到 Foo.prototype.a。
        其实 Foo.prototype.a 会影响 let obj = new Foo(); 但是obj中有a属性,所以并不会沿着原型链向上找 Foo.prototype.a;
        而 Foo.a 则会被 Function.prototype.a 影响(function关键字类似于一个语法糖?由Function构造函数创建,所以 Foo.__proto__ 指向 Function.prototype),当 Foo 中找不到 a 属性时,会沿着原型链向上找到 Function.prototype 中的 a;所以第一个Foo.a() 输出 4;
        第二个 obj.a(); 是2
        最后一个 Foo.a() ; 发生在 Foo() 执行之后,Foo.a = function... 已经被执行,所以其输出 1(js中一切皆为对象,function也是对象) 

 

 

 

上一篇:【ybt高效进阶6-1-1】序列的第k个数(快速幂)


下一篇:[CQOI2007]余数求和(除法分块)