废话不多说,先上代码
function Foo() {
getName = function () {
console.log(1);
}
}
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(); //问题六
new new Foo().getName(); //问题七
很经典,一道面试题考的知识点很全,也很细.使用的到的知识有:
1.变量的声明
函数内没有var,let,const,声明的变量是全局变量
2.普通函数和构造函数的区别
普通函数内部如果没有return就没有返回值,生成的局部变量会随着函数的调用结束被js垃圾回收机制回收.
构造函数使用new fun()方式会创建一个新的对象,对象属性的添加要在函数内使用this.属性名=属性值.
3.声明提前的优先级
函数的声明提前要高于变量的声明提前
4.new实例化的顺序
new和()相匹配,向new Foo.getName()可以理解为
var a=Foo.getName
new a()
而向new Foo().getName()可以理解为
var a=new Foo()
a.getName()
5.多个new同时存在时的处理方式
这里放到题目里具体的说
6.原型对象
- 问题一:输出的结果是2
考察:方法的属性,Foo.getName()对应着一个方法,执行该方法输出2
- 问题二:输出的结果是4
考察:声明提前的优先级,可以将代码写成如下形式
function getName(){
console.log(5);
}
var getName;
getName = function(){
console.log(4);
}
方法被覆盖,输出4
- 问题三:输出报错
报错内容:
这种书写方式是错误的,语法错误.
Foo()执行后返回underfined, underfined.getName()是错误的,找不到这个函数
- 问题四:输出的结果是1
考察:变量的声明,因为上一步执行了Foo(),Foo方法内的getName函数没有var,let,const,声明的是全局变量,getName 方法被重写.所以输出1
- 问题五:输出的结果是2
考察:new的实例化.new和()相匹配,向new Foo.getName()可以理解为
var a=Foo.getName
new a()
//相当于实例化下面函数
Foo.getName = function () {
console.log(2);
}
- 问题六:输出的结果是3
考察:new的实例化.可以理解为
var a=new Foo()
a.getName()
实例化Foo()后,调用原型对象上的方法,输出3
- 问题七:输出的结果是3
考察:这部相对复杂,不过不要被吓住,一步一步的走.需要扎实的基础,相当于问题五与问题六的结合
new new Foo().getName();
//先是new和()匹配,得到new Foo()
//new Foo()得到一个对象obj,式子变为new obj.getName();
//下一步到了obj.getName(),obj.getName 就是 Foo.prototype.getName,Foo.prototype.getName 是一个构造函数
//new Foo.prototype.getName,执行 alert(3)