前端面试知识点----基础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.10.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)();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值