趣味coding3 - valueof & tostring & [Symbol.toPrimitive]

176 阅读1分钟

1.编程题目实现 a== 1&&a==2&&a==3 为 true 与 a===1&&a===2&&a===3 为 true

  • 对于 == 进行隐式转换
class A {
	constructor(v) {
    	this.a = v
	}
    valueOf() {
        return ++this.a
    }
}
var a = new A(0)
a==1&a==2&&a==3
  • === 严格模式不会触发隐式转换
var value = 1;
Object.defineProperty(window, 'a', {
    get() {
        return value++
    }
})
console.log(a === 1 && a === 2 && a === 3))
class A {
    valueOf() {
        return 2
    }
    toString() {
        return '哈哈哈'
    }
}
let a = new A()

console.log(String(a))  // '哈哈哈'   => (toString)
console.log(`${a}`)    // '哈哈哈'   => (toString)
console.log('1'.concat(a))    // '1哈哈哈'   => (toString)
console.log(Number(a))  // 2         => (valueOf)
console.log(a + '22')   // '222'     => (valueOf)
console.log(a + 2)   // 3     => (valueOf)
console.log(a == 2)     // true      => (valueOf)
console.log(a === 2)    // false     => (严格等于不会触发隐式转换)

编程题二:用 JS 实现一个无限累加的函数 add,示例如下

add(1); // 1
add(1)(2);  // 3
add(1)(2)(3); // 6
add(1)(2)(3)(4); // 10 

A2: toString的应用

function add(a) {
    function sum(b) { // 使用闭包
        a = b ? a + b : a; // 累加
        return sum;
    }
    sum.toString = function() { // 只在最后一次调用
        return a;
    }
    return sum; // 返回一个函数
}

add(1)              // 1
add(1)(2)           // 3
add(1)(2)(3)        // 6
add(1)(2)(3)(4)     // 10 

总结:

  • valueOf偏向于运算,toString偏向于显示。
  • 在进行对象转换时,将优先调用toString方法,如若没有重写 toString,将调用 valueOf 方法;
  • 如果两个方法都没有重写,则按Object的toString输出。
  • 在进行强转字符串类型时,将优先调用 toString 方法,强转为数字时优先调用 valueOf。
  • 使用运算操作符的情况下,valueOf的优先级高于toString。
  • ES6+当[Symbol.toPrimitive]属性存在时候,优先于valueof & tostring