文章目录
  1. 1. defined
  2. 2. 相关知识点
  3. 3. 题目
  4. 4. 解析
    1. 4.1. 0x00 通读
    2. 4.2. 0x01 Foo.getName();
    3. 4.3. 0x02 getName();
    4. 4.4. 0x03 Foo().getName();
    5. 4.5. 0x04 getName();
    6. 4.6. 下面三题和运算符优先级相关
    7. 4.7. 0x05 new Foo.getName();
    8. 4.8. 0x06 new Foo().getName();
    9. 4.9. 0x07 new new Foo().getName();

defined

@掘金上看到的, 做了发现以前看得都还给书本了.
题目博客地址: http://www.cnblogs.com/xxcanghai/p/5189353.html#!comments

相关知识点

变量提升, 变量声明优先级, 函数表达式VS变量声明, js对象继承, 构造函数, this指向, 运算符优先级

题目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//	line-1
function Foo() {
getName = function() {
alert(1);
};
// console.log(this);
return this;
}
// line-2
Foo.getName = function() {
alert(2);
};
// line-3
Foo.prototype.getName = function() {
alert(3);
};
// line-4
var getName = function() {
alert(4);
};
// line-5
function getName() {
alert(5);
}

//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

解析

0x00 通读

  1. line-1中的getName是一个全局函数变量
  2. line-4是一个变量声明和赋值两个过程
  3. line-5是一个函数声明

0x01 Foo.getName();

按照前面讲的, 根据原型链查找, 直接找到了line-2函数, 输出: 2

0x02 getName();

小笔记
函数变量声明优先级比变量声明高, 变量提升仅仅提升了变量声明.demo演示

执行顺序依次: line-5函数声明, line-4变量声明, line-4变量赋值, getName()

0x03 Foo().getName();

这题仔细看, 然后看一下0x00.
在line-1中返回了this, 这个this向上查找对象, 最后找到了window对象(浏览器), 所以真正执行的函数应该是window.getName(), 而line-1将这个全局变量进行了赋值, so…

0x04 getName();

由于Foo()被执行, 全局变量被污染, 所以和上题答案一样

下面三题和运算符优先级相关

Reference:运算符优先级-MDN
园括号 > 成员访问 > 计算型成员访问 > new([x]) > 函数调用 > new
() > ... . ... > ...[...] > new ...(...) > ...(...) > new ...
new操作顺序从右到左, 注意: new func 也算带参数

0x05 new Foo.getName();

即new (Foo.getName)()

如果把上面那句改成new Date();是不是一下看懂了呢.构造函数的new操作~

0x06 new Foo().getName();

理解为: (new Foo().getName)();
差点忘记, 这边返回了this, 然后对象找不到直接的getName函数, 于是跟着原型链把line-3的函数继承上去.

0x07 new new Foo().getName();

理解为: (new (new Foo().getName))();
(new Foo().getName) 表示的是构造函数, 然后就和0x05一样的理解即可.

文章目录
  1. 1. defined
  2. 2. 相关知识点
  3. 3. 题目
  4. 4. 解析
    1. 4.1. 0x00 通读
    2. 4.2. 0x01 Foo.getName();
    3. 4.3. 0x02 getName();
    4. 4.4. 0x03 Foo().getName();
    5. 4.5. 0x04 getName();
    6. 4.6. 下面三题和运算符优先级相关
    7. 4.7. 0x05 new Foo.getName();
    8. 4.8. 0x06 new Foo().getName();
    9. 4.9. 0x07 new new Foo().getName();