`
timelessmemory
  • 浏览: 4585 次
  • 性别: Icon_minigender_1
  • 来自: 常州
社区版块
存档分类
最新评论

js面试题

    博客分类:
  • js
js 
阅读更多

 

for (var i = 0; i < 3; i++) {
	setTimeout(function() {
		console.log(i);
	}, 0);
	console.log(i);
}

 结果是:0 1 2 3 3 3
很多公司面试都爱出这道题,此题考察的知识点还是蛮多的。
为了防止初学者栽在此问题上,此文稍微分析一下。
都考察了那些知识点呢?
异步、作用域、闭包,你没听错,是闭包。
我们来简化此题:

 

 

setTimeout(function() {
        console.log(1);
}, 0);
console.log(2);

 先打印2,后打印1。
因为是setTimeout是异步的。
正确的理解setTimeout的方式(注册事件):
有两个参数,第一个参数是函数,第二参数是时间值。
调用setTimeout时,把函数参数,放到事件队列中。等主程序运行完,再调用。
没啥不好理解的。就像我们给按钮绑定事件一样:

 

 

btn.onclick = function() {
        alert(1);
};

 这么写完,会弹出1吗。不会!!只是绑定事件而已!
必须等我们去触发事件,比如去点击这个按钮,才会弹出1。
setTimeout也是这样的!只是绑定事件,等主程序运行完毕后,再去调用。
setTimeout的时间值是怎么回事呢?
比如:

 

setTimeout(fn, 2000)

我们可以理解为2000之后,再放入事件队列中,如果此时队列为空,那么就直接调用fn。如果前面还有其他的事件,那就等待。
因此setTimeout是一个约会从来都不准时的童鞋。
继续看:

 

setTimeout(function() {
        console.log(i);
}, 0);
var i = 1;

 程序会不会报错?
不会!而且还会准确得打印1。
为什么?
因为真正去执行console.log(i)这句代码时,var i = 1已经执行完毕了!
所以我们进行dom操作。可以先绑定事件,然后再去写其他逻辑。

 

 

 

window.onload = function() {
        fn();
}
var fn = function() {
        alert('hello')
};

 这么写,完全是可以的。因为异步!

es5中是没有块级作用域的

 

 

 

for (var i = 0; i < 3; i++) {}
console.log(i);

 也就说i可以在for循环体外访问到。所以是没有块级作用域。
但此问题在es6里终结了,因为es6,发明了let。

这回我们再来看看原题。
原题使用了for循环。循环的本质是干嘛的?
是为了方便我们程序员,少写重复代码。
让我们倒退50年,原题等价于:

 

 

var i = 0;
setTimeout(function() {
	console.log(i);
}, 0);
console.log(i);
i++;
setTimeout(function() {
	console.log(i);
}, 0);
console.log(i);
i++;
setTimeout(function() {
	console.log(i);
}, 0);
console.log(i);
i++;

 

因为setTimeout是注册事件。根据前面的讨论,可以都放在后面。
原题又等价于如下的写法:

 

var i = 0;
console.log(i);
i++;
console.log(i);
i++;
console.log(i);
i++;
setTimeout(function() {
	console.log(i);
}, 0);
setTimeout(function() {
	console.log(i);
}, 0);
setTimeout(function() {
	console.log(i);
}, 0);

 这回你明白了为啥结果是0 1 2 3 3 3了吧。

那个,说它是闭包,又是怎么回事?
为了很好的说明白这个事情,我们把它放到一个函数中:

 

 

var fn = function() {
        for (var i = 0; i < 3; i++) {
                setTimeout(function() {
                        console.log(i);
                }, 0);
                console.log(i);
        }
};
fn();

 上面的函数跟我们常见另一个例子(div绑定事件)有什么区别:

 

 

var fn = function() {
        var divs = document.querySelectorAll('div');
        for (var i = 0; i < 3; i++) {
                divs[i].onclick = function() {
                        alert(i);
                };
        }
};
fn();

 点击每个div都会弹出3。道理是一样的。因为alert(i)中的i是fn作用越中的,因而这是闭包。
《javascript忍者秘籍》书里把一个函数能调用全局变量,也称闭包。
因为作者认为全局环境也可以想象成一个大的顶级函数。
怎么保证能弹出0,1, 2呢。
解决之道:以毒攻毒!
再创建个闭包!!

 

 

var fn = function() {
        var divs = document.querySelectorAll('div');
        for (var i = 0; i < 3; i++) {
                divs[i].onclick = (function(i) {
                        return function() {
                                alert(i);
                        };
                })(i);
        }
};
fn();

 或者如下的写法:

 

 

var fn = function() {
        var divs = document.querySelectorAll('div');
        for (var i = 0; i < 3; i++) {
                (function(i) {
                        divs[i].onclick = function() {
                                alert(i);
                        };
                })(i);
        }
};
fn();

 因此原题如果也想setTimeout也弹出0,1,2的话,改成如下:

 

 

for (var i = 0; i < 3; i++) {
	setTimeout((function(i) {
		return function() {
			console.log(i);
		};
	})(i), 0);
	console.log(i);
}

 


本文完。

 

 

分享到:
评论

相关推荐

    JavaScript面试题,JS面试题,WEB前端面试题下载.pdf

    JavaScript 面试题知识点总结 JavaScript 面试题是前端开发领域中常见的面试题,涵盖了 JavaScript 基础、Web 前端开发等方面的知识点。本文将对 JavaScript 面试题的知识点进行总结,包括 Object.create、...

    js面试题下载

    面试题集合通常包含各种问题,旨在考察候选人在JS基础、jQuery库以及Ajax技术方面的理解和应用能力。现在,让我们深入探讨这些关键知识点。 1. **JavaScript基础**: - 变量与数据类型:了解`var`, `let`, `const`...

    JavaScript面试题阿里巴巴JavaScript面试题 阿里巴巴

    ### JavaScript面试题解析 #### 一、ES6的新语法 ES6(ECMAScript 6)是JavaScript语言标准的一个重要版本,它引入了许多新的特性和语法改进,旨在提高开发效率和代码可读性。以下是一些重要的新特性: 1. **let ...

    javascript面试题汇总

    JavaScript面试题汇总涵盖了广泛的知识点,以下是其中一些关键点的详细说明: 1. **变量声明**:在JavaScript中,可以使用var关键字声明变量。在给定的题目中,选项A `( )` 是一个无效的声明,因为没有提供任何值,...

    js面试题面试题面试题

    根据给定的文件信息,以下是对每一道JS面试题的知识点进行详细解析: ### 第一题:编写一个方法求一个字符串的字节长度 #### 解析: 在这道题目中,我们需要编写一个函数来计算字符串的字节长度。这里的重点在于...

    91道js面试题,附必过答案.pdf

    为了提高 JavaScript 的性能,需要遵循严格模式、将 js 脚本放在页面底部、将 js 脚本将脚本成组打包、使用非阻塞方式下载 js 脚本、尽量使用局部变量来保存全局变量、尽量减少使用闭包、使用 window 对象属性方法时...

    javascript 面试题

    这份“JavaScript面试题”文档旨在帮助你深入理解JavaScript的基础和高级概念,以便在面试中展现出扎实的技术功底。以下是一些关键的知识点,涵盖了标题和描述中提及的JavaScript面试重点。 1. **基本语法与数据...

    JavaScript面试题集锦

    "JavaScript面试题集锦详解" 这篇文章涵盖了JavaScript的多个方面,包括eval函数、window和document对象、null和undefined的区别、数组的map方法、事件机制、use strict模式等。 eval函数 eval函数可以将字符串...

    一套完整的javascript面试题(含有答案)

    JavaScript是一种广泛应用于Web开发的...以上是对这套JavaScript面试题的解析,涵盖的知识点全面,适合准备JavaScript面试的开发者进行自我检测和学习。理解并掌握这些知识点,对于提升JavaScript编程能力大有裨益。

    前端面试题库,包含不限于Vue面试题,React面试题,JS面试题,HTTP面试题,工程化面试题,CSS面试题

    3. **JS面试题**:JavaScript是前端开发的基础,面试中会涵盖ES6+的新特性(如箭头函数、类、Promise、async/await等),原型链,闭包,作用域,异步编程,数据结构与算法等。 4. **HTTP面试题**:理解HTTP协议对于...

    2022 vue.js面试题大全 PDF 下载.pdf

    Vue.js面试题大全 Vue.js是一款流行的前端框架,具有强大的数据绑定能力和灵活的组件化开发模式。以下是Vue.js面试题大全的摘要信息: 1. Vue的基本原理 当一个Vue实例创建时,Vue会遍历data中的属性,并使用...

    vue.js面试题大全

    ### Vue.js 面试题知识点详解 #### 一、MVVM 概念与 Vue.js 架构 **1. 对于 MVVM 的理解** MVVM(Model-View-ViewModel)是一种软件架构设计模式,主要应用于简化用户界面的开发。在 Vue.js 中,这种模式得到了...

    前端面试题库,包含Vue面试题React面试题JS面试题HTTP面试题

    3. **JS面试题**: JavaScript是前端开发的基础,面试中会涉及到语言特性、数据类型、作用域、闭包、原型链、异步编程(回调、Promise、async/await)、事件循环、错误处理等。 4. **HTTP面试题**: 理解HTTP协议...

    2021必备React.js 面试题整理(自己使用的资料).pdf

    "React.js 面试题整理" React.js 是一个流行的前端框架,它提供了一种declarative编程模型,可以帮助开发者构建快速、可维护的用户界面。以下是React.js相关知识点的总结: 1. React 事件机制 React并不是将click...

    Vue.js面试题整理带答案pdf_vue.js面试题及答案.pdf

    Vue.js 面试题整理带答案 Vue.js 是一个基于MVVM 模式的前端框架,它使用数据劫持结合发布者-订阅者模式来实现双向数据绑定。下面是 Vue.js 相关知识点的总结: 1. Vue 基础 * Vue 实例创建时,Vue 会遍历 data ...

    75个JavaScript面试题集锦

    以下是一些基于给定面试题集锦的知识点详细说明: 1. **undefined 和 null 的区别**:`undefined` 表示变量已声明但未定义,而 `null` 是一个特殊值,表示一个空或无值的引用。 2. **&& 运算符**:它执行逻辑与...

    2022java面试题、JVM面试题、多线程面试题、并发编程、Redis面试题、MySQL面试题、Java2022面试题

    Java面试题、设计模式面试题、Spring面试题、MyBatis面试题、Memcached面试题、MongoDB面试题、ZooKeepe面试题、RabbitMQ面试题、HTML面试题、CSS面试题、Vue面试题、React面试题、JavaScript面试题、2021java面试题...

    javascript的经典面试题汇总

    根据给定的信息,我们将深入分析并提取出与JavaScript面试题相关的知识点。 ### 一、单选题 #### 1. 以下哪条语句会产生运行错误: - **选项A**: `var obj = ();` - **解析**:在JavaScript中,括号`()`通常用于...

Global site tag (gtag.js) - Google Analytics