函数就是对象吗?对象就是函数吗?跪求大shen详解

哪位大神给我解释下走到误区了

var Foo=function(){
    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)};//被污染为1

function getName(){console.log(5)};
 
Foo.getName(); //2
getName();//4
Foo().getName();//1

getName();//1

//前几步我都懂 就是到这最后三步我清楚为什么?
//1、不懂 new Foo后,如果说函数是对象(Foo  ==Foo())为何调getName()的值不同
new Foo.getName();      //2

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

clipboard.png

阅读 1.9k
2 个回答

以下解释场景为全局作用域下,而不是一个函数体内
.成员访问操作符优先级高于new对象实例创建操作符号
new操作符的优先级高于函数调用
函数(除了箭头函数和生成器函数)都可以作为构造函数,和new操作符结合使用

var Foo=function(){
    getName=function(){console.log(1)};//污染了 [A]
    return this;
}
Foo.getName=function(){console.log(2)};// [B]

Foo.prototype.getName=function(){console.log(3)};//[C]

var getName=function(){console.log(4)};//被污染为1 //[D]

function getName(){console.log(5)};//[E]
 
Foo.getName(); //2 [F]
getName();//4 [G]
Foo().getName();//1 [H]

getName();//1 [I]

//前几步我都懂 就是到这最后三步我清楚为什么?
//1、不懂 new Foo后,如果说函数是对象(Foo  ==Foo())为何调getName()的值不同
new Foo.getName();      //2 [J]

new Foo().getName();    //3 [K]
new new Foo().getName();//3  [L]

[A] 定义了名Foo的函数对象,在函数体内定义了一个名为getName的全局函数变量
[B] 为函数对象Foo设置了一个名为getName的属性,这个属性指向一个函数
[C] 为函数对象Foo的原型对象添加了一个getName属性,这个属性指向一个函数
[D] 定义了一个全局函数变量getName,指向一个匿名函数,因为变量提升的关系getName申明放到头部,而变量赋值会留在原地不动
[E] 通过函数申明的方式定义了一个名为getName,同样因为提升的关系,函数声明将被放到最顶部,实际达到的效果是这个函数声明从来没有出现过
[F] 调用Foo函数对象的getName方法,也就是是[B]定义的函数,输出2
[G] 调用[D]定义的函数变量getName执行的函数,输出 4
[H] 执行Foo函数,此时全局函数变量getName被重新赋值,此时Foo函数返回的this指向的是全局对象,全局函数变量getName就是附在其上的,那么在全局对象上执行getName方法,输出 1
[I] 全局函数变量getName的指向已经通过[H]执行被重新赋值了,指向

  getName=function(){console.log(1)};//污染了 [A]

输出 1
[J] new Foo.getName();==>new (Foo.getName)();
Foo.getName返回一个函数,通过new操作,此函数被当做构造函数处理,函数执行,输出 2
[K] new Foo().getName();分解成2步:
第1步 new Foo() ==> someFooInstance
第2步 someFooInstance.getName()
此时的getName函数为[C]定义的函数
[L] new new Foo().getName(); ==> new (new Foo().getName)();
new Foo().getName返回的函数对象体为[C]定义的函数,输出 3

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题