await 操作符
await 操作符会等待后面的 Promise 表达式兑现后获取他的值,并且只能在顶层模块或者异步函数中使用。总结一下使用方式就是:
javascript
await expression;
这里的 expression 就很有讲究
- 若为 Promise 对象,那么就等待他的执行结果
- 若是 thenable 对象,那么就将其包装成一个 Promise 对象,构造时会调用其中的 then 函数
- 除此之外的其他类型会被隐式的包装进一个已兑现的
Promise
用于等待,其结果就是表达式的值。
async function
该语句用来声明一个异步函数,如果调用这个函数,必定返回一个 promise(即使内部没有写 return 语句)
TIP
即使异步函数的返回值看起来像是被包装在了一个 Promise.resolve
中,但它们不是等价的。
如果给定的值是一个 promise,异步函数会返回一个不同的引用,而 Promise.resolve
会返回相同的引用,具体原因可以看 Promise.resolve 的实现原理
javascript
const p = new Promise((res, rej) => {
res(1);
});
async function asyncReturn() {
return p;
}
function basicReturn() {
return Promise.resolve(p);
}
console.log(p === basicReturn()); // true
console.log(p === asyncReturn()); // false
import.meta
这是一个 JavaScript 表达式,他是一个宿主环境创建的可扩展的 null
原型对象,他的所有属性均可写、可配置、可枚举。规范没有在对象上明确定义任何属性,但是宿主环境通常会定义以下属性:
url
到此模块的完整 URL(不是模块不能调用),包括查询参数和片段标识符(在
?
和#
之后)。在浏览器中,它是可获取此脚本的 URL(对外部脚本)或者是包含此脚本的文档的 URL(对内联脚本)。在 Node.js 中,它是文件路径(包括file://
协议部分)。resolve
将一个模块的标识符解析为相对于当前模块的 URL。
void
这个运算符允许在表达式执行完成时,产生(某些地方)期望获得的 undefined 值。
void
运算符通常只用于获取 undefined
的原始值,一般使用 void(0)
(等同于 void 0
)。在上述情况中,也可以使用全局变量 undefined 来代替。
当用户点击一个以 javascript:
开头的 URI 时,它会执行 URI 中的代码,然后用返回的值替换页面内容,除非返回的值是 undefined。void
运算符可用于返回 undefined
。例如:
HTML
<a href="javascript:void(0);"> 这个链接点击之后不会做任何事情 </a>
<a href="javascript:void(document.body.style.backgroundColor='green');">
点击这个链接会让页面背景变成绿色。
</a>
但这种做法很不推荐了,只能在老式脚本看到,现在推荐使用事件监听器
除此之外,箭头函数标准中,允许在函数体不使用括号来直接返回值。如果右侧调用了一个原本没有返回值的函数,其返回值改变后,则会导致非预期的副作用。安全起见,当函数返回值不会被使用到的时候,应该使用 void
运算符,来确保 API 改变时,并不会改变箭头函数的行为。
JavaScript
button.onclick = () => void doSomething();
这确保了当 doSomething
的返回值从 undefined
变为 true
的时候,不会改变代码的行为。
TIP
对于一些特定的事件,比如某些表单事件(如 onsubmit
)或锚点点击事件(如 <a>
标签的 onclick
),返回 false
会阻止默认行为。
- 返回
true
(或任何真值): 不会阻止默认行为。 - 返回
false
: 会阻止默认行为(相当于调用event.preventDefault()
)。
new
老生常谈的东西,new 操作符在调用时发生了什么?
- 首先创建一个简单的 JavaScript 空对象
- 根据 new 后面跟的变量类型分别决定逻辑
- 如果不是函数,直接 throw 一个 TypeError
- 如果是函数,且函数的 prototype 是对象,那么将前面创建的对象的
[[Prototype]]
指向构造函数的prototype
属性 - 否则其
[[Prototype]]
为Object.prototype
- 将 this 绑定到前面创建的对象上,执行构造函数
- 如果构造函数返回了对象,那么该返回的对象成为整个
new
表达式的结果。否则,如果构造函数未返回任何值或返回了一个原始值,则返回我们前面新建的对象
那么我们是否可以按照上述的规则来实现一个 new 函数?
javascript
function myNew(ctor, ...args) {
if (typeof ctor !== "function") throw new TypeError("");
const obj = Object.create(ctor.prototype); // 第一步和第二步
const res = ctor.apply(obj, args); // 第三步
if (res !== null && (typeof res === "object" || typeof res === "function"))
return res;
else return obj;
}