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(); //
代码如上,都可以复制到F12执行看下,等大佬作答,实在懵逼### 题目描述
###把你上面的代码分为两部分:
- 代码部分
- 问题部分
先看代码部分
:
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); }
基于以下原因:
-
函数提升
和变量提升
-
函数提升
优先级高于变量提升
-
函数提升
不会被变量提升
的声明覆盖
改造上面的代码:
function Foo() {
getName = function(){ console.log(1); };
return this;
}
function getName(){ console.log(5); } // 注意这里
var getName; // 这里
Foo.getName = function() { console.log(2); };
Foo.prototype.getName = function(){ console.log(3); };
getName = function() { console.log(4); }; // 这里
然后再看问题部分
:
-
Foo.getName()
这个没有什么好说的,执行下面的代码:Foo.getName = function() { console.log(2); };
所以输出
2
-
getName()
这个再看上面的代码,getName
被赋值为function() { console.log(4); };
所以输出4
-
Foo().getName()
这个分两部分:Foo()
和.getName()
:function Foo() { getName = function(){ console.log(1); }; return this; }
执行这个代码之后,
getName
被重新赋值为function(){ console.log(1); }
,然后返回this
。
这个this
指的是谁?Foo()
函数调用,没有使用new
,所以这个this
指的是全局this
。
所以现在这个代码变成了全局的getName()
的调用,就是赋值的那个getName
的函数的调用。
所以输出1
-
getName()
这个现在跟【3】中的getName
是一样的。
所以输出1
-
new Foo.getName()
这个写法比较迷惑人,转换一下,就是new (Foo.getName)()
,什么意思呢,就是相当于:var a = Foo.getName; new a();
这样写是不是清楚一些,所以答案就清楚了。
输出2
-
new Foo().getName()
这个比较简单,简单拆分一下吧:var obj = new Foo(); obj.getName();
obj
原型链上存在一个getName
函数,Foo.prototype.getName = function(){ console.log(3); };
所以输出3
所以答案就是:2
4
1
1
2
3
参考链接:https://juejin.im/post/5d8d82...
Foo.getName(); // 2,调用 Foo.getName 函数
getName(); // 4
// 原因
// var getName = function() { console.log(4); };
// function getName(){ console.log(5); }
// 这两句都声明 getName 函数,因为变量提升原则,变成了下面的执行顺序:
// var getName;
// function getName(){ console.log(5); }
// getName = function() { console.log(4); } 所以最后执行结果为4
Foo().getName(); //1
// 先执行 Foo(),?? Foo 函数里的 getName 函数前面没有 var/let,所以是个全局变量
// 重写了全局函数 getName,Foo返回的结果是 this,
// 根据默认绑定原则,this 代表全局作用域
getName(); // 1,调用的也是全局函数 getName()
new Foo.getName(); //2
// 等效于 new (Foo.getName()),执行 Foo.getName()
new Foo().getName(); //3
// 等效于 (new Foo()).getName(),先执行 Foo(),得到 this
// 此时 this 是新建的对象,此对象上没有 getName 方法,就去原型链上找