文章目录
- 1、JS数据类型和判断数据类型的方法。
- 2、== 和===的区别。
- 3、什么是原型链?
- 4、什么是闭包?闭包有什么优缺点?
- 5、es6的新特性。
- 6、let、const、var的区别。
- 7、数组的方法你知道哪些?
- 8、get和post的区别。
- 9、HTTP缓存。
- 10、箭头函数和普通函数区别。
- 11、hash值如何获取?
- 12、产生跨域的方式。
- 13、解决跨域方法。
- 14、常见的数组去重方法。
- 15、null和undefined的区别。
- 16、new操作符具体干了什么?
- 17、哪些操作会造成内存泄漏?
- 18、性能优化的方法。
- 19、cookie是什么?
- 20、cookie的优缺点。
- 21、浏览器本地存储。
- 22、Web Storage和cookie的区别。
- 23、如何实现一个不断旋转的三角形?
下面是我在学习过程中整理的有关JavaScript部分面试资料,如果哪里有错误,希望您能指出,我也会虚心接受并改正错误。希望对您能有帮助!
1、JS数据类型和判断数据类型的方法。
- 基本数据类型有number、string、boolean、undefined、null和symbol。
- 引用数据类型有object、Array、RegExp、Date、Function。
- typeof判断,可以判断number,string,boolean,undefined,symbol,function的数据类型。
console.log(typeof 123); //number
console.log(typeof "123"); //string
console.log(typeof true); //boolean
console.log(typeof undefined); //undefined
console.log(typeof null); //object
console.log(typeof Symbol()); //symbol
console.log(typeof { a: 1, b: 2 }); //object
console.log(typeof function () {}); //function
console.log(typeof [1, 2, 3]); //object
console.log(typeof /\d/);//object
console.log(typeof new Date()); //object
console.log(typeof new Error());//object
- constructor可以判断除了undefined和null之外的数据的数据类型
console.log(new Number(1).constructor == Number); //true
console.log("123".constructor == String); //true
console.log(true.constructor == Boolean); //true
console.log(Symbol().constructor == Symbol); //true
console.log({ a: 1, b: 2 }.constructor == Object); //true
console.log(function () {}.constructor == Function); //true
console.log([1, 2, 3].constructor == Array); //true
console.log(/\d/.constructor == RegExp); //true
console.log(new Date().constructor == Date); //true
console.log(new Error().constructor == Error); //true
- instanceof不可判断symbol数据类型。当number、string和boolean不是通过new实例化的方式创建时,也无法判断。
console.log(123 instanceof Number);//false
console.log(new Number(123) instanceof Number);//true
console.log('123' instanceof String);//false
console.log(new String(123) instanceof String);//true
console.log(true instanceof Boolean);//false
console.log(new Boolean(true) instanceof Boolean);//true
console.log( {a: 1, b: 2 } instanceof Object);//true
console.log(function () {} instanceof Function);//true
console.log([1, 2, 3] instanceof Array);//true
console.log(/\d/ instanceof RegExp);//true
console.log(new Date() instanceof Date);//true
console.log(new Error() instanceof Error);//true
- toString
console.log(Object.prototype.toString.call(123)); // [object Number]
console.log(Object.prototype.toString.call("123")); // [object String]
console.log(Object.prototype.toString.call(true)); // [object Boolean]
console.log(Object.prototype.toString.call(Symbol())); //[object Symbol]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(function () {})); // [object Function]
console.log(Object.prototype.toString.call(new Date())); // [object Date]
console.log(Object.prototype.toString.call([1, 2, 3])); // [object Array]
console.log(Object.prototype.toString.call(/\d/)); // [object RegExp]
console.log(Object.prototype.toString.call(new Error())); // [object Error]
2、== 和===的区别。
- ==两边类型不同的时候,要先进行类型转换在比较。
- ===不做类型转换,类型不同的一定不等。
3、什么是原型链?
- 当访问一个对象的某个属性时,会先在这个对象本身属性上查找,如果没有找到,则会去它的__proto__隐式原型上查找,即它的构造函数的prototype,如果还没有找到就会在构造函数的prototype的__proto__中查找,这样一层一层的向上查找就会形成一个链式结构,我们称为原型链。
4、什么是闭包?闭包有什么优缺点?
- 闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式就是在一个函数内部创建另一个函数。闭包的优点,可以读取函数内部的变量;可以让这些局部变量永久保存在内存中,延长作用域,实现数据共享。闭包的缺点,由于闭包会使得函数中的变量常驻内存,对内存的消耗很大,所以不能滥用闭包,否则对网页的性能会有影响,在IE中可能会导致内存泄漏。
5、es6的新特性。
- 增加了let和const
- 模板字符串
- 箭头函数
- 对象和数组结构赋值
- 对象超类
- for of 和 for in
- 去重数组new Set
- 对象合并Object.assign()
6、let、const、var的区别。
- let和const是ES6提出的。
- var声明的变量存在变量提升,变量可以在声明之前调用,值为undefined。let和const不存在变量提升,即它们所声明的变量一定要在声明后使用,否则会报错。
- let和const存在暂时性死区
- var允许重复声明变量,let和const在同一个作用域不允许重复声明变量。
- var不存在块级作用域。let和const存在块级作用域
- var和let可以修改声明的变量,const声明的是一个只读的常量,一旦声明,常量的值就不可以改变。
7、数组的方法你知道哪些?
- push,在数组末尾添加一位或多位元素
- pop,删除数组最后一位元素
- unshift,在数组的开头添加一位或多位元素
- shift,删除数组的第一位元素
- join,将数组转换为字符串
- reserve,反转数组元素的顺序
- sort,对数组进行排序
- concat,连接两个或多个数组
- splice,添加或删除数组中的元素
- slice,从已有的数组中返回选定的元素
- indexOf、lastIndexOf,查找数组中的元素
- forEach,对数组进行遍历循环,对数组中每一项运行指定的函数
- map,迭代数组
- filter,对数组中的元素进行指定的检查返回符合条件的元素放入一个新数组中
- every,测试所有元素是否都符合指定条件
- some,测试某个元素是否符合指定条件
- reduce,接收一个函数作为累加器,数组中的每个值开始缩减,最终计算为一个值
- toString,将数组转换为字符串
8、get和post的区别。
- get请求的数据会附在URL之后,以?分割URL和传输数据,多个参数用&连接。post请求会把请求的数据放置在HTTP请求包的包体中。
- get传输的数据的大小会受到URL长度的限制,post是服务器规定数据的大小。
- post的安全性比get的安全性高
- get能被缓存,而post不能缓存
9、HTTP缓存。
- HTTP缓存指的是,当客户端向服务器请求资源时,会先抵达浏览器缓存,如果浏览器中存在“要请求资源”的副本,就可以直接从浏览器缓存中提取,从而不需要从原始服务器中提取这个资源。
- HTTP缓存主要分为强缓存和协商缓存。
- 强缓存的基本原理是所请求的数据在缓存数据中尚未过期,不予服务器进行交互,直接使用缓存中的数据。
- 协商缓存主要原理是从缓存数据中取出缓存的标识,然后向浏览器发送请求验证请求的数据是否已经更新,如果已更新则返回新的数据,若未更新则使用缓存数据库中的缓存数据。
10、箭头函数和普通函数区别。
- 外形不同,箭头函数使用箭头定义,普通函数没有
- 箭头函数全是匿名函数
- 箭头函数不能用于构造函数
- this指向不同。普通函数中,this总是指向它的调用者。箭头函数指向它的父级
- 箭头函数不具有arguments对象
- 箭头函数不具有prototype原型对象
- 箭头函数不具有super
11、hash值如何获取?
- 可以通过window.location.hash获取hash值
12、产生跨域的方式。
- 域名不同
- 协议不同
- 端口不同
- 二级域名相同,子域名不同
- 域名和域名对应的ip
13、解决跨域方法。
- 后端代理
- cors(跨资源共享)
- jsonp(原理是动态的插入script标签)
- document.domain+iframe
14、常见的数组去重方法。
- 使用ES6 Set
var arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];
arr = Array.from(new Set(arr));
console.log(arr);//[1, 4, 2, 3, 6]
- 使用indexOf
var arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];
var newArr = [];
arr.forEach((item) => {
newArr.indexOf(item) === -1 ? newArr.push(item) : "";
});
console.log(newArr);//[1, 4, 2, 3, 6]
- 使用双重for循环加splice方法
var arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] == arr[j]) {
arr.splice(j,1);
j--;
}
}
}
console.log(arr);//[1, 4, 2, 3, 6]
- 使用forEach和includes方法
var arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];
var newArr = [];
arr.forEach((item) => {
newArr.includes(item) ? "" : newArr.push(item);
});
console.log(newArr);//[1, 4, 2, 3, 6]
- 使用fliter和includes方法
var arr = [1, 1, 4, 2, 2, 3, 3, 3, 6, 6, 6];
var newArr = [];
arr.filter((item) => {
newArr.includes(item) ? "" : newArr.push(item);
});
console.log(newArr);//[1, 4, 2, 3, 6]
15、null和undefined的区别。
- null是一个表示"无的对象",转为数值时为0
- undefined是一个表示"无"的原始值,转为数值时为NaN
- 当声明的变量还未被初始化时,变量的默认值为undefined
- null用来表示尚未存在的对象,常用来表示函数返回一个不存在的对象
- undefined的典型用法
- 变量被声明了,但没有赋值时,就等于undefined
- 调用函数时,应该提供的参数没有提供,该参数为undefined
- 对象没有赋值的属性,该属性值为undefined
- 函数没有返回值时,默认返回undefined
- null的典型用法
- 作为函数的参数,表示该函数的参数不是对象
- 作为函数原型的终点
16、new操作符具体干了什么?
- 创建一个空对象,并且this变量引用该对象,同时还继承了该对象的原型
- 属性和方法被加入到this引用的对象中
- 新创建的对象由this引用,并且最后隐士的返回this
17、哪些操作会造成内存泄漏?
- setTimeout的第一个参数使用字符串而非函数时
- 闭包
- 控制台日志
- 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)
18、性能优化的方法。
- 减少http请求次数:CSS Sprites, JS、CSS 源码压缩、图片大小控制合适;网页 Gzip,CDN 托管,data 缓存 ,图片服务器
- 前端模板 JS + 数据,减少由于HTML标签导致的带宽浪费,前端用变量保存 AJAX 请求结果,每次操作本地变量,不用请求,减少请求次数
- 用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能
- 当需要设置的样式很多时设置 className 而不是直接操作 style
- 少用全局变量、缓存DOM节点查找的结果。减少 IO 读取操作
- 避免使用 CSS Expression
- 图片预加载,懒加载
- 将样式表放在顶部,将脚本放在底部,加上时间戳
19、cookie是什么?
- cookie又叫会话跟踪技术,是由web服务器保存在用户浏览器上的小文本文件,它可以包含相关用户的信息。无论何时用户链接到服务器,web站点都可以访问cookie信息。
- 特点
- 禁用cookie后,无法正常注册登陆
- cookie是与浏览器相关的,不同浏览器之间的cookie不能互相访问
- cookie可以被删除,因为每个cookie都是硬盘上的一个文件
- cookie安全性不够高
20、cookie的优缺点。
- 优点
- 通过良好的编程,控制保存在cookie中session对象的大小
- 通过加密技术和安全传输技术,减少cookie被破解的可能
- 只在cookie中存放不敏感数据,即使被盗也不会有重大的损失
- 控制cookie的生命周期,使之不会永久有效。偷盗者可能拿到一个过期的cookie
- 缺点
- cookie有数量和长度的限制。每个domain最多有20条cookie,每个cookie长度不能超过4KB,否则会被裁掉。
- 安全性问题。如果cookie被人拦截了,那个人就可以取得所有的session信息。即使加密也于事无补,因为拦截者不需要知道cookie的意义,他只需要原样转发就能达到目的。
- 有些状态不可能保存在客户端。
21、浏览器本地存储。
- 在较高版本的浏览器中,js提供了sessionStorage和globalStorage。在HTML5中提供了localStorage来取代globalStorage。
- HTML5中的Web Storage包含了两种存储方式,sessionStorage和localStorage。
- sessionStorage用于本地存储一个会话中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此,sessionStorage不是一种持久化的本地存储,仅仅是会话级别的存储。
- localStorage用于持久化的本地存储,除非主动删除数据,否则数据永远不会过期。
22、Web Storage和cookie的区别。
- cookie的大小是受限的,并且每次请求一个新的页面的时候cookie都会被发送过去,这样无形浪费了带宽,另外cookie还需要指定作用域,不可以跨域使用。
- Web Storage拥有setitem,getitem,removeitem,clear等方法,而cookie需要前端开发者自己封装setCookie,getCookie等方法。
- cookie的作用是与服务器交互的,作为HTTP规范的一部分存在,而Web Storage仅仅是为了在本地存储数据。
23、如何实现一个不断旋转的三角形?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>旋转三角形</title>
<style>
.box {
width: 0;
height: 0;
border-bottom: 100px solid red;
border-left: 50px solid transparent;
border-right: 50px solid transparent;
transform: rotate(0deg);
}
</style>
</head>
<body>
<div class="box"></div>
<script>
const oBox = document.querySelector(".box");
let i = 10;
setInterval(function () {
oBox.style.transform = "rotate(" + i + "deg)";
i++;
}, 16);
</script>
</body>
</html>