目录
成都创新互联公司专业提供成都主机托管四川主机托管成都服务器托管四川服务器托管,支持按月付款!我们的承诺:贵族品质、平民价格,机房位于中国电信/网通/移动机房,四川移动机房托管服务有保障!1、Promsie.all() 使用过吗, 它是怎么使用的 ?
2、for in 和 for of 循环的区别 ?
3、 什么是事件流以及事件流的传播机制 ?
4、token 一般存放在哪里 ? 为什么不存放在 cookie 内 ?
5、 数组方法 forEach 和 map 的区别 ?
6、 ES6 中 Set 和 Map 的区别 ?
7、 0.1 + 0.2 为什么不等于 0.3, 在项目中遇到要怎么处理 ?
8、 什么是模块化思想 ?
9、 说说怎么用js 写无缝轮播图
10、 闭包的使用场景 ?
10.1 防抖:
10.2 节流:
10.3 迭代器:
10.4 缓存:
10.5 getter和setter:
10.6 函数的柯里化:
10.7 循环中绑定事件或执行异步代码:
10.8 单例模式:
1、Promsie.all() 使用过吗, 它是怎么使用的 ?
🌻 promise.all()用于一个异步操作需要在几个异步操作完成后再进行时使用。 🌻 promise.all()接受一个 promise 对象组成的数组参数,返回 promise 对象。 🌻 当数组中所有promise 都完成了,就执行当前 promise 对象的 then 方法,如果数组中有一个 promise 执行失败了,就执行当前promise 对象的 catch 方法。2、for in 和 for of 循环的区别 ?
`for in` 用于遍历对象的键 ( `key` ) , `for in` 会遍历所有自身的和原型链上的可枚举属性。如果是数组,for in 会将数组的索引 (index) 当做对象的 key 来遍历,其他的 object 也是一样的。
`for of` 是 `es6` 引入的语法,用于遍历 所有迭代器 iterator ,其中包括 `HTMLCollection` , `NodeList` , `Array` , `Map` , `Set` , `String` , `TypedArray` , `arguments` 等 对象的值 ( `item` )3、 什么是事件流以及事件流的传播机制 ?
事件触发后,从开始找目标元素,然后执行目标元素的事件,再到离开目标元素的整个过程称之为事件流。 W3C 标准浏览器事件流的传播分为 3 个阶段:捕获阶段、目标阶段、冒泡阶段 🌻 捕获阶段指找目标元素的过程,这个找的过程,是从大的document 对象到 html ,再到body,......直到目标元素。 🌻 找到目标元素后,调用执行他绑定事件时对应的处理函数,这个过程被称之为目标阶段。 🌻 当目标元素的事件执行结束后,再从目标元素,到他的父元素。。。body 、 html 再到 document 的过程,是冒泡阶段。4、token 一般存放在哪里 ? 为什么不存放在 cookie 内 ?
🌻 token一般放在本地存储中。 token 的存在本身只关心请求的安全性,而不关心 token 本身的安全,因为 token 是服务器端生成的,可以理解为一种加密技术。但如果存在cookie 内的话,浏览器的请求默认会自动在请求头中携带cookie,所以容易受到 csrf 攻击。5、 数组方法 forEach 和 map 的区别 ?
🌻 forEach和 map 都是循环遍历数组中的每一项。 forEach() 和 map() 里面每一次执行匿名函数都支持 3 个参数:数组中的当前项item, 当前项的索引 index, 原始数组 input 。匿名函数中的 this 都是指 Window 。只能遍历数组。 🌻 他们的区别是:forEach 没有返回值,但 map 中要有返回值,返回处理后的所有新元素组成的数组。6、 ES6 中 Set 和 Map 的区别 ?
🌻 Set 是无重复值的有序列表。根据 `Object.is()` 方法来判断其中的值不相等,以保证无重复。 Set 会自动移除重复的值,因此你可以使用它来过滤数组中的重复值并返回结果。 Set 并不是数组的子类型,所以你无法随机访问其中的值。但你可以使用`has()` 方法来判断某个值是否存在于 Set 中,或通过 `size` 属性来查看其中有多少个值。 Set 类型还拥有 `forEach()` 方法,用于处理每个值 🌻 Map 是有序的键值对,其中的键允许是任何类型。与 Set 相似,通过调用 `Object.is()` 方法来判断重复的键,这意味着能将数值 5 与字符串 "5" 作为两个相对独立的键。使用 `set()` 方法能将任何类型的值关联到某个键上,并且该值此后能用 `get()` 方法提取出来。 Map 也拥有一个 `size` 属性与一个 `forEach()` 方法,让项目访问更容易7、 0.1 + 0.2 为什么不等于 0.3, 在项目中遇到要怎么处理 ?
🌻 计算机内部存储数据使用2 进制存储,两个数字进行的数学运算,首先是将这两个数字以 2 进制形式,存储在计算机内部,然后在计算机内部使用两个2 进制数字进行计算,最后将计算结果的 2 进制数字转为 10 进制展示出来。 🌻 由于10 进制的小数在转 2 进制的时候,规则是小数部分乘以 2 ,判断是否得到一个整数,如果得到整数,转换完成;如果没有得到整数,则继续乘以2 判断。所以, 0.1 和 0.2 在转换 2 进制的时候,其实是一个无限死循环,也就是一直乘以2没有得到整数的时候,但计算机内部对于无线死循环的数据,会根据一个标准保留 52 位。也就是说,计算机内部在存储0.1 和 0.2 的时候,本来就不精准,两个不精准的小数在计算后,距离精准的结果是有一定误差的。 🌻 项目中碰到这种情况,有3 种处理方法:
🍀 将小数乘以10的倍数,转为整数,然后计算,计算完成后,再缩小10的倍数,例如:
var result = ((0.1 * 10) + (0.2 * 10)) / 10
// result === 0.3
🍀
使用数字的toFixed
方法,强制保留小数点后多少位,例:
var result = (0.1 + 0.2).toFixed(2)
// result === 0.30
🍀
自定义数字运算方法,当需要进行数学运算的时候,不直接进行,调用自定义的方法进行,例: (加法封装)
function add(...args){
var num = args.find(item =>{
if(item != 0 && !item){
throw new Error("数学运算要使用数字")
}
})
var arr = args.map(item =>{
var index = (item+'').indexOf('.')
if(index >= 0){
return (item+'').split('.')[1].length
}
})
arr = arr.filter(item =>item)
if(arr.length){
var max = Math.max(...arr)
var data = args.map(item =>item * Math.pow(10, max))
var data.reduce((a, b) =>a + b) / Math.pow(10, max)
}else{
var data = args
return data.reduce((a, b) =>a + b)
}
}
// 调用使用:
var num1 = add(0.1, 0.2)
console.log(num1); // 0.3
var num2 = add(1, 2)
console.log(num2); // 3
var num3 = add(1, 2.1)
console.log(num3); // 3.1
8、 什么是模块化思想 ? 🌻 就是JS 中将不同功能的代码封装在不同的文件中 , 再互相引用时不会发生命名冲突的一种思想 , 大多数情况下 , 一个文件就是一个模块 🌻 模块化的实现,有多种方案:
🍀 CommonJS:
CommonJS 是 nodejs 中使用的模块化规范
在 nodejs 应用中每个文件就是一个模块,拥有自己的作用域,文件中的变量、函数都是私有的,与其他文件相隔离。模块导出: module.exports=数据 ,模块导入: require('模块文件路径')
🍀 ES6的模块化:
模块功能主要由两个命令构成: export 和 import 。 export 命令用于规定模块的对外接口, import 命令用于输入其他模块提供的功能。 一个模块就是一个独立的文件。该文件内部的所有变量,外部无法获取。如果你希望外部能够读取 模块内部的某个变量,就必须使用 export 关键字输出该变量。下面是一个 JS 文件,里面使用 export 命令输出变量。🍀 AMD (Asynchronous Module Definition):
特点 : 提倡依赖前置,在定义模块的时候就要声明其依赖的模块:导入模块 require([module],callback) ; 定义模块: define(' 模块名称 ', 函数 ) 。🍀 CMD (Common Module Definition):
CMD 规范是国内 SeaJS 的推广过程中产生的。提倡就近依赖(按需加载),在用到某个模块的时候 再去 require 。定义模块: define(function (require, exports, module) {}) ,使用模块: seajs.use() 9、 说说怎么用js 写无缝轮播图🌻 将所有需要轮播的内容动态复制一份,放在原本的容器中,加定时器让整个容器中的内容滚动轮播,当内容轮播到left值为原本的内容宽度时,快速将内容切换到 left 值为 0 的状态。10、 闭包的使用场景 ?
🌻 一个函数被当作值返回时,也就相当于返回了一个通道,这个通道可以访问这个函数词法作用域中的变量,即函数所需要的数据结构保存了下来,数据结构中的值在外层函数执行时创建,外层函数执行完毕时理因销毁,但由于内部函数作为值返回出去,这些值得以保存下来。而且无法直接访问,必须通过返回的函数。这也就是私有性。 🌻 本来执行过程和词法作用域是封闭的,这种返回的函数就好比是一个虫洞,开了挂。 🌻 闭包的形成很简单,在执行过程完毕后,返回函数,或者将函数得以保留下来,即形成闭包。10.1 防抖:
function debounce(fn, interval) {
let timer = null; // 定时器
return function() {
// 清除上一次的定时器
clearTimeout(timer);
// 拿到当前的函数作用域
let _this = this;
// 拿到当前函数的参数数组
let args = Array.prototype.slice.call(arguments, 0);
// 开启倒计时定时器
timer = setTimeout(function() {
// 通过apply传递当前函数this,以及参数
fn.apply(_this, args);
// 默认300ms执行
}, interval || 300)
}
}
10.2 节流:function throttle(fn, interval) {
let timer = null; // 定时器
let firstTime = true; // 判断是否是第一次执行
// 利用闭包
return function() {
// 拿到函数的参数数组
let args = Array.prototype.slice.call(arguments, 0);
// 拿到当前的函数作用域
let _this = this;
// 如果是第一次执行的话,需要立即执行该函数
if(firstTime) {
// 通过apply,绑定当前函数的作用域以及传递参数
fn.apply(_this, args);
// 修改标识为null,释放内存
firstTime = null;
}
// 如果当前有正在等待执行的函数则直接返回
if(timer) return;
// 开启一个倒计时定时器
timer = setTimeout(function() {
// 通过apply,绑定当前函数的作用域以及传递参数
fn.apply(_this, args);
// 清除之前的定时器
timer = null;
// 默认300ms执行一次
}, interval || 300)
}
}
10.3 迭代器:var arr =['aa','bb','cc'];
function incre(arr){
var i=0;
return function(){
//这个函数每次被执行都返回数组arr中 i下标对应的元素
return arr[i++] || '数组值已经遍历完';
}
}
var next = incre(arr);
console.log(next());//aa
console.log(next());//bb
console.log(next());//cc
console.log(next());//数组值已经遍历完
10.4 缓存:var fn=(function(){
var cache={};//缓存对象
var calc=function(arr){//计算函数
var sum=0;
//求和
for(var i=0;i
10.5 getter和setter:function fn(){
var name='hello'
setName=function(n){
name = n;
}
getName=function(){
return name;
}
//将setName,getName作为对象的属性返回
return {
setName:setName,
getName:getName
}
}
var fn1 = fn();//返回对象,属性setName和getName是两个函数
console.log(fn1.getName());//getter
fn1.setName('world');//setter修改闭包里面的name
console.log(fn1.getName());//getter
10.6 函数的柯里化:function curryingCheck(reg) {
return function(txt) {
return reg.test(txt)
}
}
var hasNumber = curryingCheck(/\d+/g)
var hasLetter = curryingCheck(/[a-z]+/g)
hasNumber('test1') // true
hasNumber('testtest') // false
hasLetter('21212') // false
10.7 循环中绑定事件或执行异步代码:var p1 = "ss";
var p2 = "jj";
function testSetTime(para1,para2){
return (function(){
console.log(para1 + "-" + para2);
})
}
var test = testSetTime(p1, p2);
setTimeout(test, 1000);
setTimeout(function(){
console.log(p1 + "-" + p2)
},1000)
10.8 单例模式:var Singleton = (function () {
var instance;
function createInstance() {
return new Object("I am the instance");
}
return {
getInstance: function () {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
当前标题:前端面试题集锦(5)-创新互联
当前链接:http://lswzjz.com/article/dpgcco.html