1、关于new操作干了啥的理解
const a = { a: 1 }
function A1() { return a }
function A2() { return a }
function A3() { return 1 }
function A4() { return 1 }
const a1 = new A1()
const a2 = new A2()
const a3 = new A3()
const a4 = new A4()
console.log(a1 === a2) // true
console.log(a3 === a4) // false
第一眼看是不是感觉很奇怪,但是认真理解new干了啥就明白了。
new操作符做了什么
1、创建了一个全新的实例对象
2、将新创建的实例__proto__指向到构造函数的prototype
3、将构造函数中的this指向实例
4、若构造函数有返回值,1⃣️:返回值是原始类型,则忽略返回值,依然创建新的实例对象;
2⃣️返回值是object则返回object,则不再创建新的实例对象
function myNew(con) {
let arg = Array.prototype.slice.call(arguments, 1)
// let arg2 = [...arguments].slice(1)
// let arg3 = Array.from(arguments).slice(1)
let obj = {}
obj.__proto__ = con.prototype
let res
try {
res = con.apply(obj, arg)
} catch(error) {
return new Error(error)
}
return res instanceof Object ? res : obj
}
2、[] + {} === {} + [] true 为啥???
js的隐式转换
一般非基础类型进行转换时会先调用 valueOf,如果 valueOf 无法返回基本类型值,就会调用 toString
解释了一半
[] + {}
// 加法会进行隐式类型转换,规则是调用其 valueOf() 或 toString() 以取得一个非对象的值(primitive value)。如果两个值中的任何一个是字符串,则进行字符串串接,否则进行数字加法。
[] 和 {} 的 valueOf() 都返回对象自身,所以都会调用 toString(),最后的结果是字符串串接。
[].toString() 返回空字符串,({}).toString() 返回“[object Object]”。
最后的结果就是“[object Object]”。
{} + []
// {} 被解析为空的 block,随后的 + 被解析为正号运算符。即实际上成了:{ // empty block }
+[]即对一个空数组执行正号运算,实际上就是把数组转型为数字。首先调用 [].valueOf(). 返回数组自身,因此继续调用 [].toString(),返回空字符串。空字符串转型为数字,返回0,即最后的结果.