写出输出结果
function Foo() {
getName = function () {
alert(1);
};
return this;
}
var getName;
function getName() {
alert(5);
}
Foo.getName = function () {
alert(2);
};
Foo.prototype.getName = function () {
alert(3);
};
getName = function () {
alert(4);
};
Foo.getName(); // ?
getName(); // ?
Foo().getName(); // ?
getName(); // ?
new Foo.getName(); // ?
new Foo().getName(); // ?
new new Foo().getName(); // ?
扫描下方二维码,获取答案以及详细解析,同时可解锁800+道前端面试题。
Foo.getName()
===>直接找定义好的Foo.getName方法 输出2
getName()
===>全局调用,function getName(){} 被 getName = function(){} 覆盖,因此输出4
Foo().getName()
===> 先执行Foo()返回this(这里this指向window)并且将全局getName()方法覆盖,因此输出1
getName()
===> 因为这个函数已经被覆盖成输出1的函数了,因此输出1
new Foo.getName()
===> 实例化 Foo.getName ,因此输出 2
new Foo().getName()
===> 实例化Foo函数,再调用实例化对象的getName方法,因此是在原型链上查找,因此输出3
new new Foo().getName()
===> 实例几次,也还是按照原型查找,因此输出3
function Foo() {
getName = function () {
alert(1);
};
return this;
}
// 定义了Foo构造函数,new的实例拥有getName方法,提示1
var getName;
// window中定义getName,开辟栈
function getName() {
alert(5);
}
// window中的getName定义为一个提示5的方法
Foo.getName = function () {
alert(2);
};
// 定义Foo类的静态方法getName,提示2
Foo.prototype.getName = function () {
alert(3);
};
// 更改Foo原型的getName,现在new的实例getName提示3
getName = function () {
alert(4);
};
// window中的getName方法改为提示4
Foo.getName(); // ?
// 调用Foo类的静态方法,提示2
getName(); // ?
// 调用window的getName方法,提示4
Foo().getName(); // ?
// 先调用Foo,是window调用的,将window的getName改为提示1
// 返回window
// window调用getName,提示1
getName(); // ?
// 调用window的getName,提示1
new Foo.getName(); // ?
// Foo类的静态方法,提示2,返回一个空实例
new Foo().getName(); // ?
// 新建Foo实例,调用实例的getName,提示3
new new Foo().getName(); // ?
// 新建Foo实例,新建实例getName构造的实例,提示3,返回空实例
按顺序提示
- 2
- 4
- 1
- 1
- 2
- 3
- 3
Foo.getName(); // 弹窗2 getName(); // 弹窗4 Foo().getName(); // 弹窗1 getName(); //被赋值 弹窗1 new Foo.getName(); // 弹窗2 new Foo().getName(); // 弹窗1 new new Foo().getName(); //弹窗3 新对象 .getname 弹窗3