把99%的程序员烤得外焦里嫩的JavaScript面试题
var a = 10;
{
a = 99;
function a() {
} a = 30;
}
console.log(a);
var a = 10;
{
function hello() {
a = 99;
function a() {
} a = 30;
}
hello();
}
console.log(a);
{
var a = 1;
var b = 2;
console.log(a + b);
}
function add()
{
var a = 1;
var b = 2;
console.log(a + b);
}
add();
{
var a = 1;
var b = 2;
function sub() {
return a - b
}
}
console.log(a + b); // 输出3
console.log(sub()); // 输出-1
var a = 14;
function b() { }
{
var a = 1; var b = 2;
function sub() {
return a - b
}
} console.log(a + b); // 输出3
console.log(sub()) // 输出-1
let a = 14;
class b{}
{
var a = 1; var b = 2;
function sub() {
return a - b
}
} console.log(a + b);
console.log(sub())


function myfun()
{
var a = 1;
var b = 2;
}
console.log(a + b);

var a = 100
{
a = 10;
function a() { }
a = 20; }
console.log(a); // 输出10
var a = 100
{
function hello() {
a = 10;
function a() { } a = 20;
}
hello(); }
console.log(a); // 输出100
function hello() {
}
hello()
hello()
// hello函数是在使用之后定义的
function hello() {
}
hello()
function hello() {
}
hello()
function hello() {
console.log('hello')
}
var h = new hello(); // 抛出异常
class hello { }

class hello {
}
var h = new hello(); // 正常创建类的实例
var p1 = 10
{
p1 = 40;
class p1{}
p1 = 50;
}

var a = 99;
function a() {
}
console.log(a)
{
var a = 99;
function a() {
}
console.log(a)
}
{
a = 99;
function a() {
}
console.log(a)
}
function hello()
{
var a = 99;
function a() {
}
console.log(a)
}
hello();

var a = 99;
function a() {
}
console.log(a)
function hello()
{
var a = 99;
function a() {
}
console.log(a)
}
hello();
{
var a = 99; // 抛出异常
function a() {
}
console.log(a)
}
{
a = 99; // 正常执行
function a() {
}
console.log(a)
}

var a = 10; // 不处理
{
a = 99; // 不处理
function a() { // 提升作用域到顶层作用域
} a = 30; // 不处理
}
console.log(a); // 不处理
// 在第2遍扫描时,其实已经发现在第1遍扫描中存在一个顶层的函数a(作用域被提升的),所以这个变量a其实是覆盖了第1遍扫描时的a函数
// 所以说,不是函数a覆盖了变量a,而是变量a覆盖了函数a。也就是说,当执行到这时,函数a已经被干掉了,以后再也没函数a什么事了
var a = 10;
{
a = 99; // 提升作用域,将a的值设为99,在这时还没有局部函数a呢!
// 在第2遍扫描时仍然处理,由于第1遍扫描,只扫描函数,所以是没有顶级变量a的,因此,会将函数a提升到顶级作用域
// 而第2遍扫描,由于存在顶级变量a,所以这个函数a会作为局部函数处理,这是执行级代码块的规则
function a() {
} a = 30; // 实际上替换的是局部函数a
}
console.log(a); // 第2遍执行这条语句,输出99
var a = 10; // 不处理
{
function hello() { // 提升到顶级作用域
a = 99; // 不处理
function a() { // 添加到hello函数作用域的符号表中
}
a = 30; // 不处理
}
hello(); // 不处理
}
console.log(a); // 不处理
var a = 10; // 定义顶层变量a
{
function hello() { // 提升到顶级作用域
a = 99; // 如果是非执行级代码块,会优先考虑局部同名符号,如局部函数a,因此,这里实际上覆盖的是函数a,而不是全局变量10
function a() { // 在非执行级代码块中,只在第1遍扫描中处理内嵌函数,第2遍扫描不处理,所以这是函数a已经被a=99覆盖了
}
a = 30; // 覆盖a = 99 在hello函数内部,a的最终值是30
}
hello(); // 执行
}
console.log(a); // 输出10
好了,现在大家清楚为什么最开始给出的两段代码,一个修改了全局变量a,一个没修改全局变量a的原因了吧。就是可执行级代码块和非可执行级代码块在处理作用域提升问题上的差异造成的。其实这么多编程语言,只有JavaScript有这些问题,这也是js太灵活导致的,这就是要自由而付出的代价:让某些程序的执行结果难以琢磨!

把99%的程序员烤得外焦里嫩的JavaScript面试题的更多相关文章
- 前端程序员经常忽视的一个 JavaScript 面试题
题目 function Foo() { getName = function () { alert (1); }; return this; } Foo.getName = function () { ...
- 前端程序员经常忽视的一个JavaScript面试题
在网上找到一个有关JavaScript的面试题,特整理如下: function Foo() { getName = function () { alert (1); }; return this; } ...
- 【原文】前端程序员必须知道的高性能Javascript知识
原文:前端程序员必须知道的高性能Javascript知识 想必大家都知道,JavaScrip是全栈开发语言,浏览器,手机,服务器端都可以看到JS的身影. 本文会分享一些高效的JavaScript的最佳 ...
- 好程序员技术分享html5和JavaScript的区别
好程序员技术分享html5和JavaScript的区别,HTML5广义上讲是前端开发学科的代名词,包含HTML5.CSS3及JavaScript三个重要的部分,是运行在浏览器上应用的统称.如PC端网站 ...
- 程序员找工作必备 PHP 基础面试题
1.优化 MYSQL 数据库的方法 (1) 选取最适用的字段属性,尽可能减少定义字段长度,尽量把字段设置 NOT NULL, 例如’省份,性别’, 最好设置为 ENUM (2) 使用连接(JOIN)来 ...
- 99%的程序员都在用Lombok,原理竟然这么简单?我也手撸了一个!|建议收藏!!!
罗曼罗兰说过:世界上只有一种英雄主义,就是看清生活的真相之后依然热爱生活. 对于 Lombok 我相信大部分人都不陌生,但对于它的实现原理以及缺点却鲜为人知,而本文将会从 Lombok 的原理出发,手 ...
- 聊聊一直困扰前端程序员的浏览器兼容-【JavaScript】
上篇已经写过浏览器的兼容发展历史以及主流浏览器,主要的css兼容我知道的已全部写到,这篇这篇专攻javascript的兼容. 1.getYear()方法 var year = new Date().g ...
- 计算机世界的道(C/ASM)生一(OS),一生二(API),二生万象(MFC/COM)——学包装技术的程序员将来会损失比较大,因为不了解本质,一旦包装过时就会被淘汰
道生一,一生二,二生万象.OO的思想就是抽象,万象归宗,化繁为简.99%的程序员使用OO,或者所谓的类库的目的就是好用,不必了解内部实现就可以直接达到所期望的结果.这时一种生产力的进步,一种流水线式半 ...
- 正则表达式——Java程序员懂你
正则表达式 关键字:正则表达式,Pattern,Matcher,字符串方法,split,replace 前文书立下了一个flag,这里要把它完成,就是正则表达式,它是一个工具,是很早就存在于标准Uni ...
随机推荐
- D. 蚂蚁平面
D. 蚂蚁平面 单点时限: 2.0 sec 内存限制: 512 MB 平面上有 n只蚂蚁,它走过的路径可以看作一条直线 由这n 条直线定义的某些区域是无界的,而另一些区域则是有界的. 有界区域的最大个 ...
- 尝试用Vue.js开发网页小游戏的过程
准备 首先去官方下载并安装VSCODE,下载地址 https://code.visualstudio.com/.安装后打开会发现是英文版的,需要去安装插件来汉化.具体是在扩展插件搜索chinese,选 ...
- Java 自动拆箱 装箱 包装类的缓存问题--结合源码分析
都0202 了 java 1.8 已经是主流 自动装箱 .拆箱已经很普遍使用了,那么有时候是不是会遇到坑呢? 我们先来看一段代码: public class TestWraperClass { pub ...
- js拼接php拼接
当我们用到ajax的时候,局部替换的时候,我们可以在前台拼接,后台拼接,这个取决于你是前端后端这样拼接判断比较好, 判断不拼接,判断的值进行拼接 然后在html 替换 $.each 前台循环 ...
- redis部署与卸载
1.先到Redis官网(redis.io)下载redis安装包 cd /tmp wget http://download.redis.io/releases/redis-4.0.10.tar.gz 2 ...
- Linux open() 一个函数,两个函数原型
open在手册中有两个函数原型, 如下所示: int open(const char *pathname, int flags); int open(const char *pathname, int ...
- 以命令行界面启动 Ubuntu
1. /etc/default/grub 将GRUB_CMDLINE_LINUX_DEFAULT一行中改为"quiet splash 3" 2. update-grub 3. 重启
- [Windows API] Listing the Files in a Directory,可用来数文件夹下有多少个子文件(夹)
转载 #include <windows.h> #include <tchar.h> #include <stdio.h> #include <strsafe ...
- C#多线程(16):手把手教你撸一个工作流
目录 前言 节点 Then Parallel Schedule Delay 试用一下 顺序节点 并行任务 编写工作流 接口构建器 工作流构建器 依赖注入 实现工作流解析 前言 前面学习了很多多线程和任 ...
- Excel中的clean函数
纯属note. 之前经常用excel处理数据的时候,对长文本或网站上拉取的值都会用clean函数清除一些我们肉眼看不到的非打印字符. Excel官方介绍:clean 删除文本中的所有非打印字符. 此次 ...