- A+
ES6语法有哪些,分别怎么用
参考链接:http://es6.ruanyifeng.com/
new的执行过程
- 创建一个新对象
- 将构造函数的作用域赋给新对象(因此this就指向了这个对象)
- 执行构造函数中的代码(为这个新对象添加属性)
- 返回新对象
异常捕获
call、apply、bind区别
call
call()方法使用一个指定的this值和单独给出的一个或多个参数来调用一个函数。
fun.call(thisArg, arg1, arg2, ...)
apply
apply()方法调用一个具有给定this值的函数,以及作为一个数组(或类似数组对象)提供的参数。
func.apply(thisArg, [argsArray])
bind
bind()方法创建一个新的函数,在bind()被调用时,这个新函数的this被bind的第一个参数指定,其余的参数将作为新函数的参数供调用时使用。
function.bind(thisArg[,arg1[,arg2[, ...]]])
总结
其实apply和call基本类似,他们的区别只是传入的参数不同。call方法接受的是若干个参数列表,而apply接收的是一个包含多个参数的数组。
bind和call、apply方法作用是一致的,只是该方法会返回一个函数,并且我们必须要手动去调用。
手写一个AJAX
let xhr = new XMLHttpRequest() xhr.open('GET', '/xxx',true) xhr.onreadystatechange = function(){ if(xhr.readyState === 4){ if(xhr.status >= 200 && xhr.status < 300){ console.log('请求成功') }else{ console.log('请求失败') } } } xhr.send()
什么是JSONP
请求方:xxx.com的前端程序员(浏览器)
响应方:yyy.com的后端程序员(服务器)
- 请求方创建script,src指向响应方,同时传一个查询参数?callback=xxx
- 响应方根据查询参数callback,构造形如这样的响应:
1. xxx.call(undefined,’需要的数据’)
2. xxx(‘需要的数据’) - 浏览器接收到响应,就会执行xxx.call(undefined,’需要的数据’)
- 那请求方就知道了所需要的数据了
为什么不支持POST?
- JSONP是通过动态创建script的
- 动态创建script时只能用GET,没法用POST
如何实现深拷贝
JSON.parse()、JSON.stringify()
这种方法存在一个问题:能正确处理的对象只有Number、String、Array等能够被JSON表示的数据结构,因此函数这种不能被 json 表示的类型将不能被正确处理。
var target = { a: 1, b: { b1: 11, b2: 22 } }; var targetCopy = JSON.parse(JSON.stringify(target)); targetCopy.a = 22; targetCopy.b.b1 = 111; console.log(target); //{a: 1, b: {b1: 11, b2: 22}}; console.log(targetCopy); //{a: 22, b: {b1: 111, b2: 22}}; console.log(target === targetCopy); //false
for...in + 递归
function clone(object) { var object2 if (!(object instanceof Object)) { return object } else if (object instanceof Array) { object2 = [] } else if (object instanceof Function) { object2 = eval(object.toString()) } else if (object instanceof Object) { object2 = {} } for (let key in object) { object2[key] = clone(object[key]) } return object2 } var obj1 = { name: 'zww', hi: { like: 'lol', age: 18 } } var obj2 = clone(obj1) obj2.name = 'lq' console.log(obj1) // {name: "zww", hi: {…}} console.log(obj2) // {name: "lq", hi: {…}}
全局函数eval()有什么作用
eval()函数会将传入的字符串当做JavaScript代码进行执行。
eval()是全局对象的一个函数属性
- 如果eval()的参数是一个字符串。如果字符串表示的是表达式,eval()会对表达式进行求值。如果参数表示一个或多个JavaScript语句,那么eval()就会执行这些语句。
- 如果eval()的参数不是字符串,eval()会将参数原封不动地返回。
为什么0.1+0.2!==0.3
因为JavaScript存储数值采用双精度浮点数,会出现精度丢失的问题。
0.100000000000000000000002 === 0.1 //true console.log(0.100000000000000002) //0.1
如何使得0.1+0.2===0.3呢
parseFloat((0.1 + 0.2).toFixed(10)) === 0.3 //true
==和===的区别
==:相等运算符
===:严格运算符
- 对于string、number等基础类型,是有区别的:
1. 不同类型:==:转换成同一类型后的值看值是否相等;===:如果类型不同,结果就不等。
2. 相同类型:直接进行值比较 - 对于Array、Object等高级类型,是没有区别的
- 对于基础类型与高级类型,是有区别的:
1. ===:类型不同,结果不等;
2. ==:将高级类型转化为基础类型,进行值比较。
什么是原型
什么是闭包
什么是CORS,什么是跨域
什么是instanceof操作符
typeof与instanceof区别
typeof
typeof可用于基本数据类型的类型判断,返回值都是小写的字符串。
console.log(typeof undefined) // undefined console.log(typeof null) // object console.log(typeof 1) // number console.log(typeof "a") // string console.log(typeof true) // boolean console.log(typeof [1,2]) // object console.log(typeof {}) // object console.log(typeof function(){}) // function console.log(typeof new Function()) // function console.log(typeof new String()) // object console.log(typeof new Object()) // object console.log(typeof new Number()) // object
instanceof
instanceof是判断变量是否为某个对象的实例,返回值为true或false。
var a = [] var b = {} console.log(a instanceof Array) // true console.log(a instanceof Object) // true console.log(b instanceof Array) // false console.log(b instanceof Object) // true
区别
- typeof用于基本数据类型的类型判断,无法判断对象的具体类型(除function)
- instanceof可以用来区分数组、对象,不能用来判断字符串、数字等
数组降维
二维数组
遍历
利用双重循环遍历二维数组中的每一个元素并存放到新的数组中。
var arr = [ ['z', 'w', 'w'], ['l', 'q'], [12, 52, 7] ]; var result = []; for (var i = 0; i < arr.length; i++) { for (var a = 0; a < arr[i].length; a++) { result.push(arr[i][a]); } } console.log(result); // (8) ["z", "w", "w", "l", "q", 12, 52, 7]
concat()
利用concat()方法来合并两个或多个数组。
var arr = [ ['z', 'w', 'w'], ['l', 'q'], [12, 52, 7] ]; var result = []; for (var i = 0; i < arr.length; i++) { result = result.concat(arr[i]); } console.log(result); // (8) ["z", "w", "w", "l", "q", 12, 52, 7]
concat + apply
var arr = [ ['z', 'w', 'w'], ['l', 'q'], [12, 52, 7] ]; var result = Array.prototype.concat.apply([], arr); console.log(result); // (8) ["z", "w", "w", "l", "q", 12, 52, 7]
flat()
flat()方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
var arr = [ ['z', 'w', 'w'], ['l', 'q'], [12, 52, 7] ]; var result = arr.flat() console.log(result) // (8) ["z", "w", "w", "l", "q", 12, 52, 7]
多维数组
forEach + 递归
var arr = [ 1, [2, 3, [ 4, 5, [ 6, 7 ], 8 ], 9], 10 ]; var result = [] function reduction(arr) { arr.forEach(item => { if (Array.isArray(item)) { reduction(item) } else { result.push(item) } }) return result } console.log(reduction(arr)); // (10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
flat()
flat()的参数使用Infinity,可展开任意深度的嵌套数组。
var arr = [ 1, [2, 3, [ 4, 5, [ 6, 7 ], 8 ], 9], 10 ]; var result = arr.flat(Infinity) console.log(result) // (10) [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
null与undefined的区别
null
null是一个字面量,表示空,没有对象。
用法:
- 作为函数的参数,表示该函数的参数不是对象。
- 作为对象原型链的终点。
undefined
undefined表示"缺少值",就是此处应该有一个值,但是还没有定义。
用法:
- 变量被声明了,但没有赋值时,就等于undefined。
- 调用函数时,应该提供的参数却没有提供,该参数等于undefined。
- 对象没有赋值的属性,该属性的值为undefined。
- 函数没有返回值时,默认返回undefined。
注意
null == undefined // true null === undefined // false typeof null // "object" typeof undefined // "undefined" 1 + null // 1 1 + undefined // NaN
Promise、Promise.all、Promise.race分别怎么用
含义
Promise是异步编程的一种解决方案。
Promise有以下几种状态:
- pending(进行中): 初始状态,既不是成功,也不是失败状态。
- fulfilled(已成功): 意味着操作成功完成。
- rejected(已失败) 意味着操作失败。
Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。只要这两种情况发生,状态就凝固了,不会再变了,会一直保持这个结果,这时就称为 resolved(已定型)。
Promise
function fn() { return new Promise((resolve, reject) => { 成功时调用 resolve(value) 失败时调用 reject(error) }) } fn().then(成功函数1, 失败函数1).then(成功函数2, 失败函数2)
Promise.all
Promise.all()方法用于将多个Promise实例,包装成一个新的Promise实例。
该promise对象在数组参数对象里所有的promise对象都成功的时候才会触发成功,一旦有任何一个数组参数对象里面的promise对象失败则立即触发该promise对象的失败。
promise1和promise2都成功就会调用成功函数
Promise.all([promise1, promise2]).then(成功函数, 失败函数)
let p1 = new Promise((resolve, reject) => { resolve("成功p1") }) let p2 = new Promise((resolve, reject) => { resolve("成功p2") }) let p3 = Promise.reject("失败p3") Promise.all([p1, p2]).then(result => { console.log(result) // (2) ["成功p1", "成功p2"] }).catch(err => { console.log(err) }) Promise.all([p1, p3]).then(result => { console.log(result) }).catch(err => { console.log(err) // 失败p3 })
Promise.race
Promise.race()方法同样是将多个Promise实例,包装成一个新的Promise实例。
promise1和promise2只要有一个成功就会调用成功函数
Promise.race([promise1, promise2]).then(成功函数, 失败函数)
Promise.race([promise1, promise2, promise3...])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
let p1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('成功') }, 1000) }) let p2 = new Promise((resolve, reject) => { setTimeout(() => { reject('失败') }, 500) }) Promise.race([p1, p2]).then(result => { console.log(result) }).catch(err => { console.log(err) // 失败 })