43.async是promise暴露出来的语法糖?
- async函数就是generator函数的语法糖
44.箭头函数与function的区别?
(1) 箭头函数与function定义函数的写法:
//function function fn(a, b){ return a + b; } //arrow function var foo = (a, b)=>{ return a + b };
(2) this的指向:
使用function定义的函数,this的指向随着调用环境的变化而变化的,而箭头函数中的this指向是固定不变的,一直指向的是定义函数的环境。
(3) 构造函数
function是可以定义构造函数的,而箭头函数是不行的。
(4) 变量提升
由于js的内存机制,function的级别最高,而用箭头函数定义函数的时候,需要var(let const定义的时候更不必说)关键词,而var所定义的变量不能得到变量提升,故箭头函数一定要定义于调用之前!
45.箭头函数中没有this对象,this是最近的this
(1) 由于箭头函数不绑定this, 它会捕获其所在(即定义的位置)上下文的this值, 作为自己的this值
(2)方法的箭头函数this指向全局window对象,而普通函数则指向调用它的对象,箭头函数没有this
46.箭头函数可以作为构造函数吗?
因为箭头函数没有自己的this,它的this其实是继承了外层执行环境中的this,且this指向永远不会随在哪里调用、被谁调用而改变,所以箭头函数不能作为构造函数使用,或者说构造函数不能定义成箭头函数,否则用new调用时会报错!
47.箭头函数替代arguments的方法?
箭头函数没有自己的arguments对象。在箭头函数中访问arguments实际上获得的是外层局部(函数)执行环境中的值。可以在箭头函数中使用rest参数代替arguments对象,来访问箭头函数的参数列表
48.解构和负载的场景?
- 解构赋值,即对某种结构进行解析,然后将解析出来的值赋值给相关的变量,常见的有数组、对象、字符串的解构赋值等
数组解构
只要等号两边的模式相同,左边的变量就会被赋予对应的值。
let [foo, [[bar], baz]] = [1, [[2], 3]]; foo // 1 bar // 2 baz // 3
对象结构
对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { bar, foo } = { foo: 'aaa', bar: 'bbb' }; foo // "aaa" bar // "bbb"
字符串结构
字符串被转换成了一个类似数组的对象
const [a, b, c, d, e] = 'hello'; a // "h" b // "e" c // "l" d // "l" e // "o"
- 负载
49.扩展运算符了解?
- 概念
扩展运算符(spread)是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列。扩展运算符与正常的函数参数可以结合使用,后面也可以放置表达式,但如果后面是一个空数组,则不产生任何效果。
let arr = []; arr.push(...[1,2,3,4,5]); console.log(arr); //[1,2,3,4,5] console.log(1, ...[2, 3, 4], 5) //1 2 3 4 5 console.log(...(1 > 0 ? ['a'] : [])); //a console.log([...[], 1]); //[1]
应用
1 替代函数的apply方法
由于扩展运算符可以展开数组,所以不再需要apply方法,将数组转为函数的参数了。
// ES5 的写法 Math.max.apply(null, [14, 3, 77]) // ES6 的写法 Math.max(...[14, 3, 77])
2 复制数组
// ES5 的写法 const a1 = [1, 2]; const a2 = a1.concat(); // ES6 的写法 const a1 = [1, 2]; onst a2 = [...a1]; //或 const [...a2] = a1;
3 合并数组
// ES5 的写法 [1, 2].concat(more); arr1.concat(arr2, arr3); // ES6 的写法 [1, 2, ...more]; [...arr1, ...arr2, ...arr3]
4 与结构赋值结合
// ES5 的写法 a = list[0], rest = list.slice(1) // ES6 的写法 [a, ...rest] = list
50.深拷贝的方法?
答:对数组进行深拷贝:
- for循环
- slice方法
- concat方法
- ES6扩展运算符
对对象进行深拷贝: - for循环
- 先转换成json在转换成对象
- ES6扩展运算符
51.扩展运算符的方法进行拷贝,是深拷贝还是浅拷贝?
答:深拷贝
52.set的用法:数组去重。
答:有两种方法:
方法一: Set + Array.from()
var set1 = Array.from(new Set([1,1,2,2,33,'33',44,'44' ]))
方法二: …[拓展运算符] + Set
var tt = [...new Set([5,5,6,6,8,])] // 5,6,8
53.es6判断是否是数组:isArray,以及其他判断数组的方法?typeof 检测数组返回值
答:
判断数组方法:
- 1.用instanceof判断
使用instanceof运算符可以分辨数组和对象,可以判断数组是数组。 - 2.用constructor判断
实例化的数组拥有一个constructor属性,这个属性指向生成这个数组的方法。
当constructor属性被修改之后,就无法用这个方法判断数组是数组了
3.用Object的toString方法判断
toString方法将会返回"[object type]",其中的type代表的是对象的类型,根据type的值,我们就可以判断这个疑似数组的对象到底是不是数组了
4.用Array对象的isArray方法判断
isArray方法返回true,当参数不为数组的时候,isArray方法返回false
typeof 检测数组返回值 typeof是javascript原生提供的判断数据类型的运算符,它会返回一个表示参数的数据类型的字符串
54.数组去重的方法?
答:
- 利用ES6中的Set
- 利用for嵌套for,然后splice去重(ES5中最常用)
- 利用indexOf去重
- 利用sort()
- 利用includes
- 利用hasOwnProperty
- 利用filter
- 利用递归去重
- 利用Map数据结构去重
- 利用reduce+includes
55.数组中出现重复数字的重复统计?
思路:
//统计一个数组中有多少个不重复的单词: // 不用reduce时: var arr = ["apple","orange","apple","orange","pear","orange"]; function getWordCnt(){ var obj = {}; for(var i= 0, l = arr.length; i< l; i++){ var item = arr[i]; obj[item] = (obj[item] +1 ) || 1; } return obj; } console.log(getWordCnt());//{apple: 2, orange: 3, pear: 1} // 用reduce时: var arr = ["apple","orange","apple","orange","pear","orange"]; function getWordCnt(){ return arr.reduce(function(prev,next){ prev[next] = (prev[next] + 1) || 1; return prev; },{}); } console.log(getWordCnt());//{apple: 2, orange: 3, pear: 1}
56.数组常见的api
- 数组api又叫应用程序接口,函数方法
常见api
arr.push():数据添加 - 在数组尾部添加元素
push方法一次可添加单个或多个元素到数组末端,也可以添加数组
数组名.push("元素1","元素2",...)
arr.pop():数据更新 - 删除数组的最后一个元素
pop方法的作用是移除数组末尾的一个元素。把数组长度减1,并且返回它的删除值,如果数组为空,则pop()不改变数组,返回undefind
数组名.pop()
arr.concat():连接两个或更多的数组,并返回结果。
arr.join():字符连接
若不想要任何连接符,则括号中用空字符即可。
数组名.join("连接符")
arr.reverse():颠倒数组中元素的顺序。
arr.shift():删除数据 - 移除数组顶端的元素
shift方法与pop相反,移除数组的第一个元素并将其返回。该方法执行后,数组剩下的元素向前移动,下标索引号重新调整从0开始。
数组名.shift()
arr.unshift():添加数据 - 在数组头部添加元素
nshift方法与push方法正好相反,是将元素插入数组的首部。一次可以插入单个或多个元素,所有元素按顺序插入,操作完成后返回新数组的引用
数组名.unshift("元素1","元素2",...)
arr.slice():生成特定数据 - 获取数组中的一部分元素
slice方法的作用是抽取数组的一段元素,抽取指定下标索引区间中的元素作为新数组返回
数组名.slice(start,end)
注:splice是直接修改原数组,而slice不会修改原数组。
arr.sort():对数组的元素进行排序
arr.splice():更新移动数据 - 删除、替换或插入数组元素
splice方法的作用是,从一个数组中移除一个或多个元素。剩下的元素组成一个数组,移除的元素组成另一个数组并返回它的引用。同时,原数组可以在移除的开始位置处顺带插入一个或多个新元素,达到修改替换数组元素的目的。这个操作效果通常称为接合
数组名.splice(start,deleteCount,item1,item2,...)
参数说明:
start:必选项,表示从数组中剪切的起始位置下标索引号。
deteleCount:必选项,表示从数组中切取的元素个数。
item:可选项,表示切取时插入原数组切入点开始出的一个或多个元素。
arr.indexof():查找元素对应下标
arr.forEach():数组遍历
arr.filter():数组遍历,将返回的值新建成一个新数组
arr.map():遍历数组,直接操作数组,返回一个新数组
arr.reduce():数组归并
57.数组中sort的用法。sort的返回值?没有传比较函数的比较?
用法:对数组的元素进行排序
arr.sort()直接操作原有数组,返回原有数组,当没有传比较函数的话不会按大小排序,而是按顺序排序
var arr = [22,12,3,43,56,47,4]; arr.sort(); console.log(arr); // [12, 22, 3, 4, 43, 47, 56] arr.sort(function (m, n) { if (m < n) return -1 else if (m > n) return 1 else return 0 }); console.log(arr); // [3, 4, 12, 22, 43, 47, 56]
58.canvas与webGL的区别
- 概要 Canvas 位图,是需要自己画点的白板; WebGL 3D位图,是基于 Canvas 的 3D 框架。 - 用途 Canvas 适用于位图,高数据量高绘制频率(帧率)的场景,如动画、游戏; WebGL 主要用来做 3D 展示、动画、游戏。 - canvas缺点: - 只能绘制2D图像,暂时不支持3D图像。 -canvas绘制图形出并非可以直接操作的dom对象。如果要对其进行类似dom的操作,例如添加属性等等,比较麻烦(这就是为什么必须使用类库)。 - canvas优点: - 由于canvas绘图不会给每个点生成对象,所以绘制速度快,消耗内存少。(这点主要是相对于SVG,VML技术而言) - 兼容性较好。除了IE6,其他浏览器都可以支持。(IE7,8需要载入扩展JS,终究还是能用的) - webGL 是一项使用JavaScript实现3D绘图的技术,浏览器无需插件支持,Web开发者直接使用js调用相关API就能借助系统显卡(GPU)进行编写代码从而呈现3D场景和对象。
59.BOM对象与DOM对象的区别?实现由BOM对象还是先有DOM对象
BOM:浏览器对象模型(Brower Object Model),是用于操作浏览器而出现的API,BOM对象则是Javascript对BOM接口的实现。 BOM提供了独立于内容的、可以与浏览器窗口进行交互的对象结构。通过BOM对象可以访问浏览器功能部件和属性。 BOM中代表浏览器窗口的window对象是Javascript顶层对象,其他BOM对象均为window对象的子对象。被作为window对象的属性来引用。 其他BOM对象都是在window对象中进行操作。 DOM 是文档对象模型,比如 html 是树结构的,操作 dom 就是操作这颗树: DOM:文档对象模型(Document Object Model),是W3C定义的一套用于处理HTML和XML文档内容的标准编程接口API。javascript实现DOM接口的对象对应的是document对象,JS通过该对象来对HTML/XML文档进行增删改查。DOM定义了HTML和XML的逻辑结构,将整个页面划分成由层次节点构成的文档,以树的形式来展现,如上面那张图所示。 在BOM和DOM结构层次图中,document对象属于window对象,所以DOM也可以看作是BOM的一部分
- 0-9 ↩︎