前端工程师面试题汇总(我的解析,可能不一定对)(js部分)

1、介绍JavaScript的数据类型。

ECMAScript中有5种基本的数据类型:Number、String、Boolean(true||false)、Undefined(声明未赋值)、Null(空对象,表示空),基本类型是按值访问的。

还有一种复杂的数据类型——Object,本质上是一组无序的名值对组成的。(引用类型)

undefined 和 Null

  undefined 这个值表示变量不含有值

  可以通过将变量的值设置为 null 来清空变量

注意:typeof操作符的返回值(6种字符串)如下:

* "undefined"  :  如果这个值是未定义;
* "boolean"  :   如果这个值是布尔值;
* "string"  :  如果这个值是字符串;
* "number"  :  如果这个值是数字;
* "object"  : 如果这个值是对象或者null;
* "function"  :  如果这个值是函数;

只有这六种类型。
引用类型是按引用访问。

引用类型:引用类型的值是引用类型的一个实例。在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起。引用类型也被称为对象定义。

对象是某个特定的引用类型的实例。

注意区别与基本数据类型:

常见的引用类型:

var obj = new Object();//typeof(obj);结果为"object"下同。
var date = new Date();
var arr = new Array("arr");
var RegExp = new RegExp("[bc]at",i);
var fn = new Function(){};//不推荐

为了便于操作基础类型值,ECMAScript还提供了3个特殊的引用类型:(包装类型)

var boolean = new Boolean();//typeof();取值为“object”;
var num = new Number();
var str = new String();

在ECMA-262中定义了如下的内置对象:“由ECMAScript实现提供的、不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前就已经存在了。”两个单体内置对象如下:

Global对象

所有在全局作用域中定义的属性和函数都是Global的属性。

内置对象Global的方法常见如下:

*URI编码方法:encodeURI();encodeURIComponent();
*eval();eval()方法就像是一个完整的ECMAScript解析器,它只接受一个参数,即要执行的javascript字符串(语句);
*对象的属性:主要包括undefined、NaN、Infinity、引用类型的创建对象(Object、Function、Number等构造函数)、
Error(错误类型对象,包括各种错误类型的构造函数,TypeError、SyntaxError);
*window对象:web浏览器都是将这个全局对象作为window对象的一部分加以实现的。

Math对象

*属性值:常用的数学值的特殊值,如Math.PI(π的值)、Math.E(自然对数的底数,即常量e的值)等;
*min()和max()方法:用于确定一组数值中的最小和最大值。如下使用:Math.max(3,5,52,16);
*舍入方法:常用如下三个方法,Math.ceil();执行向上舍入,Math.floor();执行向下舍入,Math.round();执行标准舍入,四舍五入。
*random();方法:返回大于等于0小于1的一个随机数。
  这里如果要产生一个在一个范围内的数,如0到10;var num = Math.floor(Math.random()*11);
*其他方法:都是一些数学计算的方法。
null,undefined 的区别?

在if语句中都会被转换为false;

typeof();方法检测结果不同,如果未定义返回字符串"undefined",如果是null则会返回"object"。 首先,null像在Java里一样,被当成一个对象。但是,JavaScript的数据类型分成原始类型(primitive)和合成类型(complex)两大类,Brendan Eich觉得表示"无"的值最好不是对象。 其次,JavaScript的最初版本没有包括错误处理机制,发生数据类型不匹配时,往往是自动转换类型或者默默地失败。Brendan Eich觉得,如果null自动转为0,很不容易发现错误。

因此,Brendan Eich又设计了一个undefined。 JavaScript的最初版本是这样区分的:null是一个表示
"无"的对象,转为数值时为0;undefined是一个表示"无"的原始值,转为数值时为NaN。 但是,上面这样的区分,在实践中很快就被证明不可行。目前,null和undefined基本是同义的,只有一些细微的差别。 null表示"没有对象",即该处不应该有值。典型用法是:1) 作为函数的参数,表示该函数的参数不是对象。 (2作为对象原型链的终点。 Object.getPrototypeOf(Object.prototype) // null undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。典型用法是:1)变量被声明了,但没有赋值时,就等于undefined。 (2) 调用函数时,应该提供的参数没有提供,该参数等于undefined。 (3)对象没有赋值的属性,该属性的值为undefined。 (4)函数没有返回值时,默认返回undefined。 var i; i // undefined function f(x){console.log(x)} f() // undefined var o = new Object(); o.p // undefined var x = f(); x // undefined

原始类型与引用类型的内存图:简而言之,堆内存存放引用值,栈内存存放固定类型值。

                                           前端工程师面试题汇总(我的解析,可能不一定对)(js部分)

2、eval是做什么的?

对 eval 的态度应该是:学习它,并远离它。

eval() 函数可计算某个字符串并执行其中的的 JavaScript 代码

eval()方法就像一个完整的ECMAScript解析器,接受一个字符串参数,执行其中的js代码。

严格模式下,给eval赋值会导致错误;代码注入就是使用eval()来操作的。

3、javascript 代码中的”use strict”;是什么意思 ? 使用它区别是什么?

主要的观点如下:

##"严格模式"(strict mode)。顾名思义,这种模式使得Javascript在更严格的条件下运行。

##设立"严格模式"的目的,主要有以下几个:

  - 消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;

  - 消除代码运行的一些不安全之处,保证代码运行的安全;

  - 提高编译器效率,增加运行速度

  - 为未来新版本的Javascript做好铺垫

## "严格模式"体现了Javascript更合理、更安全、更严谨的发展方向,包括IE10在内的主流浏览器,都已经支持它,许多大项目已经开始全面拥抱它。

  另一方面,同样的代码,在"严格模式"中,可能会有不一样的运行结果一些在"正常模式"下可以运行的语句,在"严格模式"下将不能运行

4、对如下代码的理解

真的挺有意思:
[].forEach.call($$("*"),function(item){ 
    item.style.outline="1px solid #"+(~~(Math.random()*(1<<24))).toString(16);
});

/**
 *它的作用是用来调试你的CSS层。简单来说,这段代码只是首先获取了所有的页面元素,然后使用一个不同的颜色为它们添加了一个1px的轮廓线。
 *Chrome浏览器中特有的函数$$。你可以在你的Chrome浏览器控制台中输入$$('a'),然后你就能得到一个当前页面中所有锚元素的列表。
 *1、$$("*");获取所有的元素,替代方法如:document.querySelectorAll("*")或者直接使用document.all获取所有元素。
 *2、用了Array对象的forEach方法,Array.forEach(function(item,index,array));执行给定的函数。没有返回值。依次对所有元素调用这个匿名函数。
 *3、outline(轮廓)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用。轮廓线不会占据空间,也不一定是矩形。outline 能告诉用户那一个可以激发事件的html元素获取了焦点,对钟爱键盘操作的用户尤其有意义。
 *区别于border:
 * border 可应用于几乎所有有形的html元素,而outline 是针对链接、表单控件和ImageMap等元素设计。
 * 从而另一个区别也可以推理出,那就是:outline 的效果将随元素的 focus 而自动出现,相应的由 blur 而自动消失。这些都是浏览器的默认行为,无需JavaScript配合CSS来控制。
outline 不会象border那样影响元素的尺寸或者位置。去除焦点虚线:style="outline:medium none;" hidefocus="true"
 *4、颜色值:Math.random()*(1<<24)表示一个位于0和16777216之间的数。
 *5、转化浮点数为整数:我们的代码中使用波浪号操作符来完成这件事。波浪操作符在javascript中被用来对一个变量进行取反。但是我们在这里并不关心取反,我们指向获取整数部分。因此我们还可以知道两次取反可以去掉一个浮点数的小数部分,因此~~的作用相当于parseInt。
 *6、我们获得了一个位于0和16777216之间的随机整数,也就是我们想要的随机颜色。此时我们只需要使用toString(16)将它转化为十六进制数即可。
 */

5、那些操作会造成内存泄漏?

一、什么是内存泄露

  内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束。在C++中,因为是手动管理内存,内存泄露是经常出现的事情。而现在流行的C#和Java等语言采用了自动垃圾回收方法管理内存,正常使用的情况下几乎不会发生内存泄露。浏览器中也是采用自动垃圾回收方法管理内存,但由于浏览器垃圾回收方法有bug,会产生内存泄露。

二、内存泄露的几种情况

1、当页面中元素被移除或替换时,若元素绑定的事件仍没被移除,在IE中不会作出恰当处理,此时要先手工移除事件,不然会存在内存泄露。

2、对于纯粹的 ECMAScript 对象而言,只要没有其他对象引用对象 a、b,也就是说它们只是相互之间的引用,那么仍然会被垃圾收集系统识别并处理。

但是,在 Internet Explorer 中,如果循环引用中的任何对象是 DOM 节点或者 ActiveX 对象,垃圾收集系统则不会发现它们之间的循环关系与系统中的其他对象是隔离的并释放它们。最终它们将被保留在内存中,直到浏览器关闭。

3、闭包可以维持函数内局部变量,使其得不到释放。上例定义事件回调时,由于是函数内定义函数,并且内部函数--事件回调的引用外暴了,形成了闭包

解决之道,将事件处理函数定义在外部,解除闭包

4、 执行这段代码之后b.x的值依然是1.由于已经删除的属性引用依然存在,因此在JavaScript的某些实现中,可能因为这种不严谨的代码而造成内存泄露。所以在销毁对象的时候,要遍历属性中属性,依次删除。