整理了一些之前面试遇到的题
NAN === NAN
是否成立,为什么?
不成立。因为JavaScript规定,NaN表示的是非数字,但是这个非数字也是不同的,因此 NaN 不等于 NaN,两个NaN永远不可能相等。
0.1+0.2 == 0.3
和 0.1+0.2 === 0.3
哪个成立,为什么?
都不成立.在正常的数学逻辑思维中,0.1+0.2=0.3这个逻辑是正确的,但是在JavaScript中0.1+0.2!==0.3,这是为什么呢?在JavaScript中的二进制的浮点数0.1和0.2并不是十分精确,在他们相加的结果并非正好等于0.3,而是一个比较接近的数字 0.30000000000000004 ,所以条件判断结果为false。
可以通过
(0.1 + 0.2).toFixed(2) // "0.30"
和parseFloat((0.1 + 0.2).toFixed(2)) //0.3
的方法使0.1+0.2==0.3
什么是闭包?
如果一个函数用到了它作用域外面的变量,那么这个变量和这个函数之间的环境就叫闭包。
举一个简单的例子
1 | function fun(){ |
闭包的使用场景
封装局部变量
例如:一个游戏,主人公有10条命,我们如果把var live=10
写在全局作用域的话,全局中任何地方都能调用修改,就会出现安全性,容易出bug。
但如果写在局部作用域,会有如下问题:
在全局环境中调用不了
局部环境执行完毕后,会被清出环境栈,局部环境中的变量和函数都会垃圾回收机制回收。
因此我们用闭包去将var live=10
变量封装起来
1 | function liveFun(){ |
箭头函数与普通函数的区别?
区别:
- 箭头函数没有自己的
this
属性,arguments
属性、而普通函数有,箭头函数的this
指向当前函数作用域的this
。 - 箭头函数没有不能使用
new
命令,因为没有自己的this
,无法调用call
,apply
,没有prototype显示原型,所以不能作为构造函数。 - 不可以使用
yield
命令,因此箭头函数不能用作Generator
函数。
箭头函数的好处:
- 没有箭头函数的时候,函数闭包
var that = this
的事没少干,有了箭头函数,就不需要这么写了 - 极简语法,函数式风格
js原型原型链
首先我们要清除明白两个概念
js分为函数对象和普通对象,每个对象都有
__proto__
属性,但是只有函数对象才有prototype
属性Object、Function都是js的内置函数,类似的还有我们常用的Array,RegExp、Date、Boolean、Number、String
属性
prototype
是一个对象,他有两个属性,constructor
和__proto__
;原型对象
prototype
有一个默认的constructor
属性,用于记录实例是由哪个构造函数创建;
举个例子:
1 | //有以下构造函数Person,他的原型上有所属国属性motherland='china' |
通过new Person()创建的persson01实例
1 | let persion01 = new Person('小明',18) |
js在设计原型、原型链的时候遵从以下两个准则:
1 | 1. Person.prototype.constructor == Person // **准则1:原型对象(即Person.prototype)的constructor指向构造函数本身** |
举个例子:
1 | function Foo(); |
除了Object的原型对象(Object.prototype)的proto指向null,其他内置函数对象的原型对象(例如:Array.prototype)和自定义构造函数的proto都指向Object.prototype, 因为原型对象本身是普通对象。即:
1 | Object.prototype.__proto__ = null; |
原型对象的作用,是用来存放实例中共有的那部份属性、方法,可以大大减少内存消耗。
em、rem 是什么?
em:em是相对于⽗元素的尺⼨单位
rem:相对于html元素的尺⼨单位(html默认font-size:16px)