• 主页
  • 归档
  • 分类
  • 照片墙
所有文章 友情链接 关于我

  • 主页
  • 归档
  • 分类
  • 照片墙
  1. 1. 第一问
  2. 2. 第二问
  3. 3. 第三问
  4. 4. 第四问
  5. 5. 第五问
  6. 6. 第六问

变量的定义提升

2017-10-14 00:30:18
总字数 724
预计阅读时间 2 分钟

从一道笔试题说起

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();

第一问

Foo是一个函数对象 , Foo.getName = … 在其中定义了一个名为getName的属性 , 也是一个函数
所以第一问当中的调用输出的应该是2

第二问

这里涉及到了变量的定义提升问题 , 如果不了解容易误认为答案是5
例如如下语句

1
2
console.log("x" in window);
var x;

虽然变量的定义是在第二个语句 , 但是输出的结果仍然是true
因为代码执行时 JS引擎会把变量的声明语句提升到最上方
但是提升的仅仅是变量声明 , 如果声明变量的时候包含初始化
则会将初始化作为单纯的一条赋值语句保留在原处
例如

1
2
console.log("x" in window);
var x = 10;

在JS引擎处理之后会改变为

1
2
3
var x;
console.log("x" in window);
x = 10;

补充说明 : 只有显式的变量定义才会被提升
隐式的变量定义并不会
比如

1
2
console.log("x" in window);//false
x = 10;

输出就是false , 因为x未定义

全局函数的定义与全局变量的定义本质是一样的
所以它也会被提升到顶部
但是 var x = function(){}与function x(){}两种定义方式最终效果相同
执行过程却是不同的

1
2
3
console.log(x);//function x(){}
function x(){}
console.log(x);//function x(){}

或者

1
2
3
console.log(x);//undefined
var x = function(){}
console.log(x);//function x(){}

那么具体到这个题目
代码

1
2
var getName = function () { console.log (4);};
function getName() { console.log (5);}

会被JS引擎在解析时修改为

1
2
3
var getName;
function getName() { console.log (5);}
getName = function () { console.log (4);};

显然 , 第三行的赋值会将第二行的定义覆盖掉
最终这个全局的getName函数输出的值是4

第三问

Foo() 是在全局的基础上调用的 , 也就是由window对象调用的
所以return this返回的是window对象
但是在这个函数的内部 , 修改了全局的getName的值
现在名为getName的全局函数输出是1了
所以再调用window.getName() 的输出当然是1

第四问

同样是调用全局的getName函数 , 所以结果和第三问一样 , 也是1

第五问

成员访问的点号( . )优先级高于 new , 所以结果与第一问相同 , 也是2

第六问

括号运算符的优先级高于点号( . )
实际执行为 ( new Foo( ) ).getName()
所以调用的是原型对象上的getName函数 , 输出是3

  • JavaScript
  • 函数
  • JavaScript

扫一扫,分享到微信

实现bind方法
函数形参与arguments 
© 2024 夏夜梦星辰
鲁ICP备19028444号
Power By Hexo
  • 所有文章
  • 友情链接
  • 关于我
{{searchItem.query}}
标签: 分类:
  • maven
  • 持续集成
  • JMS
  • 线程
  • JavaScript
  • ECMAScript6
  • 单元测试
  • Promise
  • Web Worker
  • 函数
  • prototype
  • 模块化
  • 正则表达式
  • 数据库
  • MongoDB
  • 索引
  • 集群
  • 全文检索
  • flutter
  • dart
  • git
  • 版本控制
  • linux
  • shell
  • docker
  • nginx
  • jenkins
  • opencv
  • vim
  • react
  • react native
  • 前端
  • css
  • HTML5
  • Hexo
  • sass
  • Three.js
  • TypeScript
  • Vue
  • 组件化
  • base64
  • webpack
  • nodejs
  • gulp
  • TensorFlow
  • 机器学习
  • 算法
  • 动态规划
  • 数据结构
  • Java
  • JavaScript
  • MongoDB
  • flutter
  • Git
  • linux
  • react
  • 前端杂烩
  • 男生女生
  • 算法
  • 十年饮冰,难凉热血
  • †少女癌†
  • 猫与向日葵
  • coderfun
  • JENKINS
  • API管理后台
愿你最终能接纳每一面每一种的自己
独自活着便是团圆