题目:
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();
看到这个题感觉如何?是不是脑瓜子嗡嗡的😄。
Foo.getName();
=>2
这个应该没有什么质疑的, 因为函数Foo
内部没有执行,所以执行外面的结果是2
getName();
=>4
这里考察了一个相对久远的var
和function
预解析的问题,他们两个是有优先级的 函数的优先级更高一些,而且预解析时函数是声明 + 赋值(这就是因为为什么日常函数声明写在下面,调用写在上面,也是可以用的) 而var
是只声明,还没有赋值Foo().getName();
=>1
这个应该没有什么质疑的,函数执行,调用里面的getName
方法,所以结果打印 1getName();
=>1
因为上面的Foo().getName()
执行, 里面的getName
替换了外面的getName
函数到全局上,所有执行的是Foo
内部的getName
new Foo.getName();
=>2
这里应该又会有疑问,因为我这里第一次也写错了🤣,我以为会是 1 😅 因为:.
的优先级比new
高,所以这里就是一个次Foo.getName()
调用,所以是 2 ,new
是误导用的
(实例化的是Foo
的静态函数getName
内部的代码会执行输出2)new Foo().getName();
=>3
这里我第一次写的 1 😳,然后不是和上面那个一样吗 🤔
其实不是,因为:new Foo()
加个括号,是提升了优先级,会去先执行new Foo()
, 然后在调用.getName()
, 那问题又来了,为啥不是 1,因为内部的getName
不是绑定在 this 上的呀,所以就去找原型上的方法,结果是 3
(实例化Foo
对象,最后返回的this
,也就是当前创建的对象。调用getName
时,会在自己对象上查找,没有找到。然后会沿着对象中的__proto__
(创建这个实例的构造函数的原型)查找。也就是在Foo.prototype
这个对象查找,最终找到了。调用,输出3)