有这样一道前端小题, 问输出什么:
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(); // Q1
getName();// Q2
Foo().getName(); // Q3
getName();// Q4
new Foo.getName();// Q5
new Foo().getName();// Q6
new new Foo().getName();// Q7
回答:
1、 Q1
答案:2。 Foo.getName 为调用Foo的静态方法
2、 Q2
答案:4。function getName() {} 的写法为函数声明式写法。 var getName = function() {} 为函数表达式写法
JavaScript 解释器中存在一种变量声明被提升的机制,也就是说
函数声明
会被提升到作用域的最前面,即使写代码的时候是写在最后面,也还是会被提升至最前面。而用函数表达式创建的函数是在运行时
进行赋值,且要等到表达式赋值完成后才能调用。 即函数声明在JS解析时
进行函数提升,因此在同一个作用域内,不管函数声明在哪里定义,该函数都可以进行调用。而函数表达式的值是在JS运行时
确定,并且在表达式赋值完成后,该函数才能调用。
所以function getName() {} 会提升至顶部, 运行时 被var getName = function() {} 覆盖
3、 Q3
答案: 1。Foo() 执行, getName 为全局变量; Foo()返回this , this 指向window , Foo() .getName 为 window.getName
4、 Q4
答案: 1。 直接调用getName函数,相当于window.getName(),getName 已经被第3步修改
5、Q5
对于new Foo.getName() , new Foo 为 「new 无参数列表」 优先级在表格中为18,Foo.getName 为成员访问,优先级为19 ;所以 new Foo.getName() 的执行为 new (Foo.getName)()
6、 Q6
答案:3 。 new Foo().getName() 按优先级判断为 (new Foo()).getName()
new Foo() 为Foo的实例,返回的是this,而this在构造函数中本来就代表当前实例化对象,最终Foo函数返回实例化对象。 即实例化对象的getName 方法,实例方法中没有,去原型上查找,故为3
7、 Q7
答案:3。 Q7 是Q5 与Q6问题的组合, 相当于
new ((new Foo()).getName)();
其他小知识:
1、JS中构造函数可以有返回值也可以没有。
- 如果没有返回值,则返回实例化对象。
- 若有返回值则检查其返回值是否为引用类型。如果是非引用类型,如基本类型(String,Number,Boolean,Null,Undefined)则与无返回值相同,实际返回其实例化对象。
- 若返回值是引用类型,则实际返回值为这个引用类型。
hi 今天的你点赞了没~~
网友评论