上篇文章因篇幅原因还有一些es6的面试题没有写完,这边文章就时间委托、预获取、和es6等一些面试题进行讲解记录。
事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件;
通过事件处理函数的唯一参数 event
对象;
事件委托可以少写很多代码,却能大大减少dom的操作,可以提高性能;
示例代码(使用了 event.type
属性):
let btn = document.getElementById("myBtn");
let handler = function(event) {
switch(event.type) {
case "click":
console.log("Clicked");
break;
case "mouseover":
event.target.style.backgroundColor = "red";
break;
case "mouseout":
event.target.style.backgroundColor = "";
break;
}
};
btn.onclick = handler;
btn.onmouseover = handler;
btn.onmouseout = handler;
===
操作规则:
==
操作规则:===
运算符的规则Array.isArray()
```JavaScript console.log(Array.isArray([1, 2, 4]))* `Object.prototype.toString.call(obj) == [object Array]`
```JavaScript
console.log(Object.prototype.toString.call([1,2,4]) == "[object Array]")
instanceof
console.log([1,2] instanceof Array)
显示转换一般指使用Number、String和Boolean三个构造函数,手动将各种类型的值,转换成数字、字符串或者布尔值。
隐式转换:比如不同类型变量之间的比较:
console.log({} == 0)
DNS-prefetch
(DNS预获取)能在请求资源之前解析域名
当浏览器从(第三方)服务器请求资源时,会先将该域名解析为 IP地址,然后浏览器才能发出请求。DNS 的这一解析过程会导致请求增加延迟,可以通过 DNS 预获取,在请求资源之前解析域名
<link rel="dns-prefetch" href="https://fonts.googleapis.com/">
无论何时,只要创建一个函数,就会按照特定的规则为这个函数创建一个 prototype 属性(指向 原型对象)。默认情况下,所有原型对象自动获得一个名为 constructor 的属性,指回与之关联的构 造函数。
==实例==与==构造函数原型==之间有直接的==联系==,但==实例==与==构造函数==之间==没有==。
正常的原型链都会终止于 ==Object
的原型对象==; Object
原型的原型是 null
console.log((new Object()).__proto__ == Object.prototype);
其他例子:
function Person() {}
console.log(Person.prototype.__proto__ === Object.prototype); // true
console.log(Person.prototype.__proto__.constructor === Object); // true
console.log(Person.prototype.__proto__.__proto__ === null); // true
==对象包含 __proto__
指向他的原型对象
prototype
指向原型对象==
function Person(name) {
console.log(name)
}
let kobe = new Person('科比');
console.log(kobe.__proto__ === Person.prototype)
// true
ES6之前
function Parent(value) {
this.val = value
}
Parent.prototype.getValue = function () {
console.log(this.val)
}
function Child(value) {
Parent.call(this, value)
}
Child.prototype = new Parent()
const child = new Child(1)
child.getValue() // 1
child instanceof Parent // true
以上继承的方式核心是利用 call() 方法来继承父类属性,通改变子类原型,让原型指向父类的实例,就可以共享父类的方法了
这种继承方式优点在于构造函数可以传参,不会与父类引用属性共享,可以复用父类的函数,但是也存在一个缺点 就是在继承父类函数的时候调用了父类构造函数,导致子类的原型上多了不需要的父类属性,存在内存上的浪费。
class
去继承class Parent {
constructor(value) {
this.val = value
}
getValue() {
console.log(this.val)
}
}
class Child extends Parent {
constructor(value) {
super(value)
this.val = value
}
}
let child = new Child(1)
child.getValue() // 1
child instanceof Parent // true
class
实现继承的核心在于==使用 extends
== 表明继承自哪个父类,并且在子类构造函数中必须调用 super
,因为这段代码可以看成 Parent.call(this, value)
Promise.all()
方法
该方法指当所有在可迭代参数中的 promises 已完成,或者第一个传递的 promise(指 reject)失败时,返回 promise。但是当其中任何一个被拒绝的话。主Promise.all([..])就会立即被拒绝,并丢弃来自其他所有promis的全部结果。
Promise.all 里的任务列表[asyncTask(1),asyncTask(2),asyncTask(3)],我们是按照顺序发起的。
但它们是异步的,互相之间并不阻塞,每个任务完成时机是不确定的,尽管如此,所有任务结束之
后,它们的结果仍然是按顺序地映射到resultList里,这样就能和Promise.all里的任务列表[asyncTask(1),asyncTask(2),asyncTask(3)]一一对应起来。
Promise.race()
方法
Promse.race就是赛跑的意思,意思就是说,Promise.race([p1, p2, p3])里面哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。
下面是 CancelToken 类的一个基本实例:
class CancelToken {
constructor(cancelFn) {
this.promise = new Promise((resolve, reject) => {
cancelFn(resolve);
});
}
}
JavaScript 语言是单线程,单线程就意味着,所有任务需要排队;javascript引擎实现非阻塞的关键就是 事件循环机制 event loop
所有任务可以分为两种:
只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复。
所谓"回调函数"(callback),就是那些会被主线程挂起来的代码。异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数。
==先执行执行栈上的同步任务(某些宏任务),执行完执行栈上的同步任务后再执行任务队列里面的微任务,然后再执行任务队列的宏任务,然后一直循环==
async 和 await 其实就是 Generator 和 Promise 的语法糖。 async 函数和普通 函数没有什么不同,他只是表示这个函数里有异步操作的方法,并返回一个 Promise 对象
async function async1() {
console.log("async1 start");
await async2();
console.log("async1 end");
}
// Promise 写法
async function async1() {
console.log("async1 start");
Promise.resolve(async2()).then(() => console.log("async1 end"));
}
Node.js还提供了另外两个与"任务队列"有关的方法:process.nextTick
和setImmediate
。
process.nextTick
方法可以在当前“执行栈”的尾部——下一次Event Loop(主线程读取“任务队列”)之前——触发回调函数。也就是说,它指定的任务总是发生在所有异步任务之前。
setImmediate
方法则是在当前“任务队列”的尾部添加事件,也即是说,它指定的任务总是在下一次Event Loop
时执行。promise1 = new Promise((resolve, reject) => {
reject("错误信息")
})
promise1.then(res => {
console.log(res)
}, err => {
console.log(err)
}).catch(error => {
console.log(error+"catch")
})
// 输出:错误信息
reject后的东西一定会进入then中的第二个回调,如果then中没有写第二个回调,则进入catch
0.1 + 0.2 > 0.3
JS 采用 IEEE 754双精度版本
我是 AndyHu,目前暂时是一枚前端搬砖工程师。
文中如有错误,欢迎在评论区指正,如果这篇文章帮到了你,欢迎点赞和关注呀😊
未经许可禁止转载💌
speak less,do more.