JS常见面试题(二)
整理了一些js常用的基础知识,如有问题,欢迎指正~
一、数据类型
String | Object | 本质区别: 基本数据类型和引用数据类型它们在内存中的存储方式不同。 基本数据类型是直接存储在栈中的简单数据段,占据空间小,属于被频繁使用的数据。 引用数据类型是存储在堆内存中,占据空间大。引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址,当解释器寻找引用值时,会检索其在栈中的地址,取得地址后从堆中获得实体。 |
Number | Array | |
Boolean | Function | |
Null | Regexp | |
Undefined | Date | |
Symbol | Math |
二、typeof
typeof是一个运算符,有2种使用方式:typeof(表达式)和typeof 变量名,第一种是对表达式做运算,第二种是对变量做运算
返回值:
Null | Object |
Object | Object |
Function | Object |
Number | Number |
String | String |
void(0) | undefined |
void() | SyntaxError |
undefined | undefined |
Symbol('a') | Symbol |
三、箭头函数和普通函数
匿名函数 | 可以是匿名函数也可以是具名函数 |
不能作为构造函数使用,不能使用new关键字 | |
没有yuan原型,即没有proprototype属性 | |
call、apply和bind无法改变箭头函数的this指向 | call、apply和bind可以改变普通函数的this指向 |
没有arguments对象,如果有外层函数,则集成外层函数的argument,没有外层函数则会报错,箭头函数用的是rest参数。 | |
没有generator,不能用yyield关键字。 | |
没有自己的this,它的this永远指向其定义环境,任何方法都不能改变指向 | 普通函数的this永远指向调用它的对象(谁调用就指向谁) |
四、this关键字
- 出现在全局函数中(普通函数,定时器函数,立即执行函数)this的指向永远是window,比如fun();相当于window.fun()
- 出现在严格模式中永远不会指向window,函数中使用es5的严格模式‘use strict’,this为undefined
- 以方法的形式调用时,this指向调用调用该方法的那个对象。
- 以构造函数的形式调用时,this指向构造函数创建的实例对象。
- 以事件绑定函数的形式调用时,this指向绑定事件的对象。
- 使用call和apply调用时,this指向指定的那个对象使用中。
- this出现在箭头函数中时,this和父级作用域的this指向相同。
- 若单独使用,this表示全局对象。
五、call和apply
- call和apply的作用都是改变this作用域,都是在特定作用域中调用函数。当一个对象没有某个方法,而其他对象有,我们就可以使用call或apply实现某个方法的复用。
- call和apply使用方法基本相同,唯一不同之处就是它们的参数规则: call方法接受一个参数列表, 而apply方法接受一个包含多个参数的数组。
call(apply的功能和它一样)
“外卖员炒菜”:厨师.炒菜.call(外卖员)
“外卖员弹钢琴”:演奏家.弹钢琴.call(外卖员)、
“外卖员换轮胎”:修理工.换轮胎.call(外卖员)……
programmer.programming.call(delivery) // 打印结果:外卖员编程
programmer.programming.apply(delivery) // 打印结果:外卖员编程
programmer.programming.call(delivery, '炒菜', '弹钢琴', '换轮胎')
programmer.programming.apply(delivery, ['炒菜', '弹钢琴', '换轮胎'])
第五条来自www.jianshu.com/p/5024cfcc7…
六、undefined和null的区别
逻辑角度 | 表示一个空对象指针,表示没有对象,即该处不该有值。 | 表示未定义域或者缺少值 |
使用场景 | 可以作为函数的参数,调用函数时,某个参数未设置成任何值这时可以传入null,表示该参数为空。 | 无无论在什么情况下,都没有必要把一个变量的值显式地设置成undefinded |
数据类型 | Object型 | Undefined型 |
七、变量提升
需要注意的是,仅声明会被提升,而初始化不会
(1)变量提升,很简单,就是把变量提升提到函数的top的地方。需要说明的是,变量提升只是提升变量的声明,并不会把赋值也提升上来。 (2)函数提升是把整个函数都提到前面去。 (3)函数提升优先于变量提升。 |
(1)提高性能 (2)容错性好 |
(1)函数提升的优先级高于变量 (2)由于函数声明和变量都会提升,如果函数与变量同名,如果只要在变量赋值前打印的都会是函数,在变量赋值后打印的都是变量的值。 (3)只有函数声明才会提升,函数表达式不会提升。 (4)先声明的 会被后声明的覆盖。 |
八、阻止默认行为和事件冒泡
1. 阻止默认行为
默认事件:浏览器的默认事件就是浏览器自己的行为,比如我们在点击
<a href="#">
的时候,浏览器跳转到指定页面。还有,当我们滚动鼠标时页面会向下滚动,但我们按空格键和按方向键时页面也会向下滚动,为了更好的用户体验,这时我们就需要阻止这种行为的发生。
阻止默认行为的三种方法:
- event.preventDefault();
- 低版本浏览器returnValue属性
- return false;
function preventDefa(e){
if(window.event){
//IE中阻止函数器默认动作的方式
window.event.returnValue = false;
}
else{
//阻止默认浏览器动作(W3C)
e.preventDefault();
}
}
这种是兼容性写法,但是如果你只需要支持高版本浏览器的话,那么如上文一样,一句话即可。
obj.onclick = function (){
return false;
}
这个方法比较暴力,它会同时阻止事件冒泡和默认事件,写上此代码,连接不会被打开,事件也不会传递到上一层的父元素;
可以理解为return false;
就等于同时调用了event.stopPropagation()
和event.preventDefault()
2.阻止事件冒泡
我们都知道冒泡就像水底气泡浮到水面这一过程。冒泡事件即是事件从最底层逐个经过上面一级级事件的过程,就是冒泡事件。开始时由最具体的元素接收,然后逐级向上传播到到DOM最顶层节点。
常见事件对象的属性和方法:
- event.stopPropagation();
- event.cancelBubble = true;
阻止事件冒泡的兼容性解决方案:
if (e && e.stopPropagatio "){
e.stopPropagation();
}
else {
window.event.cancelBubble = true;
}
3.&tips:vue 阻止向上和向下冒泡
<!--阻止向下冒泡-->
<div @click.self="cancelFunc"></div>
<!--阻止向上冒泡-->
<div @click.stop="cancelFunc"></div>
九、操作符之间的优先级
1.JS中常用的运算符分为以下几类
+ - * / % ++ – |
= += -= *= /= %= |
&& || ! |
< > <= >= == === != !== |
n=n>m?a:b; (解释:n是否大于m,如果是,输出a,如果不是,输出b) |
2. 优先级(高到低:)
算数操作符 → 比较操作符 → 布尔(逻辑)操作符 → “=”赋值符号 。 逻辑操作符中,逻辑与(&&)优先级高于逻辑或(||)
3. 实例:
var a = 4 >= 6 || true && 1 || false;
console.log(a);
答案:1
解析:
① 4 >= 6,结果是false(比较操作符返回布尔值)
② true && 1,结果是1(逻辑与的规则:第一个操作数是真值,则返回第二个操作数)
原式变为 false || 1 || false(按正常顺序执行)
③ false || 1,结果是1(逻辑或的规则:第一个操作数是假值,则返回第二个操作数)
④ 1 || false,结果是1(逻辑或的规则:第一个操作数是真值,则直接返回第一个操作数)
十、数据存储
1. cookie和session:
数据存放在客户的浏览器上 | 数据放在服务器上 |
安全性较低,别人可以分析存放在本地的cookie并进行cookie欺骗,考虑到安全应当使用session | 会在一定时间内保存在服务器上,当访问增多,会比较占用你服务器的性能,考虑到减轻服务器性能方面,应当使用cookie |
cookie大小受限, 单个cookie保存的数据不能超过4KB,很多浏览器都限制一个站点最多保存20个cookie | 建议将登录信息等重要信息存放为session,其他信息如果需要保留,可以放在cookie中 |
2. localStorag和sessionStorag:
localStorage的生命周期是永久的,关闭页面或浏览器之后localStorage中的数据也不会消失。localStorage除非主动删除数据,否则数据永远不会消失。 | sessionStorage的生命周期是在仅在当前会话下有效 sessionStorage引入了一个“浏览器窗口”的概念, sessionStorage是在同源的窗口中始终存在的数据。只要这个浏览器窗口没有关闭,即使刷新页面或者进入同源另一个页面,数据依然存在。但是sessionStorage在关闭了浏览器窗口后就会被销毁。 同时独立的打开同一个窗口同一个页面,sessionStorage也是不一样的。 |
因此sessionStorage 和 localStorage 的主要区别在于他们存储数据的生命周期, sessionStorage 存储的数据的生命周期是一个会话, 而 localStorage存储的数据的生命周期是永久,除非主动删除数据,否则永远不会过期 | 存储大小为5MB,都保存在客户端,不与服务器进行交互通信, |
localStorage和sessionStorage有相同的Web API:
- 保存数据到本地
const info = {name: 'Lee',age: 20,id: '001' };
sessionStorage.setItem('key', JSON.stringify(info));
localStorage.setItem('key', JSON.stringify(info));
- 从本地存储获取数据
var data1 = JSON.parse(sessionStorage.getItem('key'));
var data2 = JSON.parse(localStorage.getItem('key'));
- 本地存储中删除某个保存的数据
sessionStorage.removeItem('key');
localStorage.removeItem('key');
- 删除所有保存的数据
sessionStorage.clear();
localStorage.clear();
- 监听本地存储的变化
window.addEventListener('storage', function (e) {
console.log('key', e.key);
console.log('oldValue', e.oldValue);
console.log('newValue', e.newValue);
console.log('url', e.url);
})
3. 总结:
数据存储位置、生命周期、存储大小、写入方式、数据共享、发送请求时是否携带、应用场景 标准回答 Cookie、SessionStorage、 LocalStorage都是浏览器的本地存储。
它们的共同点:都是存储在浏览器本地的。
它们的区别:
cookie是由服务器端写入的,而SessionStorage、 LocalStorage都是由前端写入的,cookie的生命周期是由服务器端在写入的时候就设置好的,LocalStorage是写入就一直存在,除非手动清除,SessionStorage是页面关闭的时候就会自动清除。
cookie的存储空间比较小大概4KB,SessionStorage、 LocalStorage存储空间比较大,大概5M。
Cookie、SessionStorage、 LocalStorage数据共享都遵循同源原则,SessionStorage还限制必须是同一个页面。在前端给后端发送请求的时候会自动携带Cookie中的数据,但是SessionStorage、 LocalStorage不会 。
加分回答 由于它们的以上区别,所以它们的应用场景也不同,Cookie一般用于存储登录验证信息SessionID或者token,LocalStorage常用于存储不易变动的数据,减轻服务器的压力,SessionStorage可以用来检测用户是否是刷新进入页面,如音乐播放器恢复播放进度条的功能。
整理了一些JavaScript常见的面试题整理用于学习,如有问题欢迎指正,侵删~