题目:代码如下,求输出结果
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);
}
1,函数和变量提升
题目:
Foo.getName(); // 2
getName(); // 4
Foo.getName()分析:
Foo是一个函数,而函数其实也是一个对象,可以给函数赋值。
Foo.getName();
会执行Foo.getName函数体内的处理,所以显示结果为2。
getName()分析:
getName存在变量提升,我们来看看变量提升后的样子就知道为什么getName();
的结果是4了。
//这里是提升之后的内容
var getName;
function getName() {
console.log(5);
}
////////////////////
function Foo() {
getName = function () {
console.log(1);
}
return this;
}
Foo.getName = function () {
console.log(2);
}
Foo.prototype.getName = function () {
console.log(3);
}
getName = function () {
console.log(4);
}
可以看到,var getName = function ()
的定义var getName
被提升到最前面了,赋值还保留在原来的位置。而function getName()...
本身就是定义,所有整个被提升到前面了。
所以,根据最终的赋值结果来看,显示结果是4。
2,函数和作用域
题目:
Foo().getName(); // 1
getName(); // 1
Foo().getName()分析:
- Foo的函数体内,getName是没有用var声明的,所以getName是一个全局变量。
-
Foo()
的意思是运行Foo的函数体,这个函数体中做的事情就是,把全局变量getName的函数体替换成console.log(1)
。 - Foo函数体的返回值是this,这里的this指向的是window对象。
Foo().getName();
就相当于window.getName();
,也就是直接调用getName()函数,显示结果就是1。
getName()分析:
在这里,getName()
,this.getName()
,window.getName()
这三者的意思是一样的。所以显示结果也是1。
3,运算符和优先级
从以上的MDN运算符优先级资料中可以看出,"."运算符的优先级是比"new"运算符的优先级高的。
题目1:
new Foo.getName(); // 2
分析1:
- 相当于
new (Foo.getName)();
- 执行Foo.getName函数,这时候就已经输出2了
- 实例化一个对象
题目2:
new Foo().getName(); // 3
分析2:
- 相当于
(new Foo()).getName();
.运算符的优先级是19,就是指.会优于其他运算符之前执行,但是执行点的时候,是按照点前和点后的表达式依次执行的,因为Foo后面有个括号,所以new运算符是归Foo()这个函数的。 - 执行
new Foo()
,实例化一个对象,这个对象中拥有Foo.prototype.getName
方法。 - 执行
.getName()
,调用Foo.prototype.getName
方法,输出为3。
题目3:
new new Foo().getName(); // 3
分析3:
相当于
new (new Foo()).getName();
.运算符的优先级是19,就是指.会优于其他运算符之前执行。执行点的时候,是按照点前和点后的表达式依次执行的。
看看左边的new new Foo()
,带参数的new优先级是比不带参数的new优先级高的,所以左边的部分就相当于new (new Foo())
什么是带参数的new:new Foo()
什么是不带菜蔬的new:new Foo执行
(new Foo()).getName()
,相当于foo.getName()
。
foo
是new Foo()
出来后的实例,这个结果和题目2是一样的。这时候已经输出3了。执行
new
,实例化一个对象