前端面试知识点----基础javascript篇(3)
1.cookie , sessionStrage 和 localStrage
cookie : 用来保存登录信息,大小限制为 4kb 左右。
localStrage : html5 新增 ,用于本地数据存储, 数据不会过期,持久化,一般浏览器大小限制在 5 MB。
seesionStrage : 与 localStrage
类似,保存的数据只在当前会话保存,关闭就会清空。
2. 0.1+0.2 != 0.3
javaScript
在计算0.1+0.2时,会把十进制的 0.1 和 0.2 转换为二进制,但是由于浮点数用二进制表示时是无穷的,
因浮点数小数位的限制而截断的二进制数字,再转换为十进制,就产生误差不相等了
解决方法:把需要计算的数字升级(乘以10的n次幂)成为计算机能够精准识别的整数,计算完成后再降级(除以10的n次幂),但是有时候还会出现精度问题可以用toFixed()
把number
四舍五入为指定小数位,或者重写toFixed
()方法,具体参考:http://xieyufei.com/2018/03/07/JS-Decimal-Accuracy.html
(0.1*10 + 0.2*10)/10 == 0.3 // true
3. 深拷贝和浅拷贝
前言:javaScript的数据类型分为基本数据类型和引用数据类型
基本数据类型:String ,Number ,Null , Undefined , Booleam , Symbol
(es6新增)
变量值存放在栈内存中,可以直接修改,不存在拷贝,好比是无法修改数值为1的值
引用数据类型:Object , Function , Math , Date ,RegExp
变量值存放在堆内存中,在栈内存中变量保存的是一个指针,指向堆内存的地址。
浅拷贝:只拷贝到了基本数据类型和引用数据类型的指针(地址),只进行了引用的传递,而没有创建一个新的对象,还是原来的东西,并没有拷贝复制
深拷贝:俩者都拷贝并且复制到了完全的一样的值,在对引用数据类型进行拷贝时,新创建了一个对象,并且完全复制原对象的成员变量
4.定义函数的方法
函数声明
//ES5
function getSum(){}
function (){}//匿名函数
//ES6
()=>{}
函数表达式
//ES5
var getSum=function(){}
//ES6
let getSum=()=>{}
构造函数
const getSum = new Function('a', 'b' , 'return a + b')
5 js数组去重
5.1、遍历循环:使用数组的indexOf
5.2、排序比较:使用数组的 sort()
,先排序,后比较相邻的俩个元素的值
5.3、存放Hash对象的方法,将数组元素转化为对象的键名,利用键名的不可重复性来去重。
(存在问题:比遍历快,但内存占用多,就是所谓的:空间换时间)
5.4、若开发环境支持ES6,可以用Set
(ES6中提供了Set
数据容器,这是一个能够存储无重复值的有序列表。)
let arr = [1,'1',2,'2',1,2,'x','y','f','x','y','f'];
function unique4(arr){
return Array.from(new Set(arr));
}
console.log(unique4(arr));
6.一道容易被轻视的前端js题
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//答案:
Foo.getName();//2
getName();//4
Foo().getName();//1
getName();//1
new Foo.getName();//2
new Foo().getName();//3
new new Foo().getName();//3
此题涉及的知识点众多,包括变量定义提升、this指针指向、运算符优先级、原型、继承、全局变量污染、对象属性及原型属性优先级等等。
题意:
1.首先定义了一个叫做Foo的函数,之后为Foo创建了一个getName的静态属性存储了一个匿名函数,再为Foo的原型对象创建了一个getName的匿名函数。
2.之后又通过函数量表达式创建了一个getName函数,最后声明了一个叫getName的函数。
当我们依次做题:
第一问:
Foo.getName(),访问了Foo的静态属性,答案是:2 。
第二问:
这有俩个坑,一是变量提升,二是函数表达式。
变量提升:即所有声明的变量或声明函数都会提升到当前函数顶部。
函数表达式:最大的问题就是会把代码分为俩部分。
运行过程为:
function Foo() {
getName = function () { alert (1); };
return this;
}
var getName;
function getName() { alert (5);}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
getName = function () { alert (4);};
getName();//最终输出4,答案为:4 。
第三问:
先执行Foo函数,再调用Foo函数的返回对象的getName属性。
注意:
Foo函数的第一句 getName = function () { alert (1); };
是一句函数赋值语句,注意它没有var声明,所以先向当前Foo函数作用域内寻找getName变量,没有。再向当前函数作用域上层,即外层作用域内寻找是否含有getName变量,找到了,也就是第二问中的alert(4)函数,将此变量的值赋值为 function(){alert(1)}。
第四问:
直接调用getName函数,相当于window.getName(),因为这个变量已经被Foo函数执行修改了,所以与第三问一样,为 1 。
第五问:
此处考察js的运算符优先级问题。
点的优先级高与new
new (Foo。getName)();
所以,答案为:2 。
第六问:
括号运算符高于new
输出为 3
(new Foo())。getName()
第七问:
同上,答案 3
new ((new Foo())。getName)();
推荐阅读
-
python3-开发面试题(python)6.24基础篇(3)
-
前端知识点汇总—面试看这一篇就够了
-
Java基础篇——线程、并发编程知识点全面介绍(面试、学习的必备索引文档)
-
第五篇:前端开发-通过JavaScript求1/1-1/2+1/3-1/4…..1/100的和
-
前端知识点汇总—面试看这一篇就够了
-
前端面试题整合(基础篇)
-
前端 —— JavaScript 基础篇 --- 递归
-
python3-开发面试题(python)6.22基础篇(1)
-
web前端篇:JavaScript基础篇(易懂小白上手快)-1
-
从零开始学习前端JAVASCRIPT — 3、JavaScript基础Math和Date对象的介绍