一些奇怪理解记录

50 阅读2分钟
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

image.png

解释了一半
[] + {}
// 加法会进行隐式类型转换,规则是调用其 valueOf() 或 toString() 以取得一个非对象的值(primitive value)。如果两个值中的任何一个是字符串,则进行字符串串接,否则进行数字加法。
[] 和 {} 的 valueOf() 都返回对象自身,所以都会调用 toString(),最后的结果是字符串串接。
[].toString() 返回空字符串,({}).toString() 返回“[object Object]”。
最后的结果就是“[object Object]”。

{} + []
// {} 被解析为空的 block,随后的 + 被解析为正号运算符。即实际上成了:{ // empty block }
+[]即对一个空数组执行正号运算,实际上就是把数组转型为数字。首先调用 [].valueOf(). 返回数组自身,因此继续调用 [].toString(),返回空字符串。空字符串转型为数字,返回0,即最后的结果.