delete ( )
delete ( )
;var n = new Number( 1 )
console.log( n + 1 ) // 2 #请在括号内填写两行语句使得其结果为 11
-----------------------------------------------------------------------------------------------
var obj = { }
console.log( obj + obj ) // [[object ...]...] #请为obj添加一个属性使得结果为 2
------------------------------------------------------------------------------------------------------
上面这是啥?
写到这的时候特别想灌点水烘托出高大上的氛围,至少来两段文字波澜不惊地铺垫一下,可惜没有多余的脑细胞贡献在咬文嚼字上了,还是直奔主题吧。。
为了更好地回答上面两个问题,需要读者对JavaScript原型的本质有一个较为清晰的认识,如果你很久没有脑补过原型链在对象间穿梭的画面了,非常推荐去看下鄙人另一篇拙文:
------从原型链探究JavaScript这么火的原因------
首先请忽略文章标题挂羊头卖狗肉的成分,这里我想分享的是在加法操作符下js对象的具体表现:
对象在做加法操作时首先会默认沿着原型链寻找 valueOf 方法(数字对象的valueOf仍旧返回数字类型),在任何一级原型对象找到此方法都会返回结果,可以通过下面代码得到论证:
var f = function () {}
f.prototype.valueOf = () => 1
var obj = new f()
console.log( obj + 1 ) // 2
由于我已经在此实例对象的构造函数的原型里写入了 valueOf 这一方法,因此,obj在它的上一级原型就找到结果 1 并返回了。
那假如沿着原型链一直寻找都没有 valueOf 方法可用,怎么办呢?这时候数字对象 Number 就会启用 toString 方法,返回一个字符串类型。看到这里的朋友可能会心一笑,原来窍门在这里,用 delete 解除原型链上所有 valueOf 方法的链接,上面那两道填空题岂不就迎刃而解了。
为了解决上面两道填空题,我们不得不去寻找对象的顶级原型究竟在哪里,看过鄙人拙文的朋友应该很快就能反应过来,并填写:
delete Object.prototype.valueOf
delete Function.prototype.valueOf
这样填写你会发现结果仍旧是 2 ,首先这里有两个误区,第一个误区是,虽然 Number 这个构造函数对象是由 Function 构造而来,然而它的 valueOf 方法并不是通过继承 Function 原型而来,事实上 Function 的原型里我只发现有 toString 这个方法:
Number.prototype.hasOwnProperty( 'valueOf' ) // true
Function.prototype.hasOwnProperty( 'valueOf' ) // false
另一个误区是,obj 根本就不会继承 Function 的原型,这一话题我在 从原型链探究JavaScript这么火的原因 这篇文中已经提过,虽然原型链理论上会使所有实例对象也继承 Function 的原型,但 JavaScript 为了能在逻辑上修正这一‘错误’,在原型链的顶级和第二级间修改了继承规则,使得所有函数对象和实例对象采取了新的继承方法。
此时,第一题的答案也就呼之欲出了:
delete Object.prototype.valueOf
delete Number.prototype.valueOf
对于第二题而,看过我在原型链中那篇文提到的继承规则,答案也是不言而喻:
obj = { valueOf : () => 1 }
大家还有什么别的问题,欢迎给我留言一起讨论,转载请注出。。