古早的prototype.js
由于几乎所有的小程序,都有自己的一套语义标签,所以几乎不可能使用js原生代码去操作node,也就无法使用fabric库去操作canvas,所以一些功能就需要参照fabric然后使用小程序对应的api去操作canvas;
因此就需要去熟悉fabric的源码,熟悉过程中,我看到了如下几行代码:
IS_DONTENUM_BUGGY = (function() {
for (var p in { toString: 1 }) {
if (p === 'toString') {
return false;
}
}
return true;
})(),
没错,乍一看是一个匿名自执行函数,没啥特别;然后一看,欸? 这个方法不应该是永远返回false吗,因为p一定是等于“tostring”吧? 转念一想,fabric这种库不可能写无用的代码,所以我特意查了查,好家伙!
原来涉及到了一个知识点,即Dont Enum:不可被枚举的; 哪些属性是不可被枚举的呢,比如js的内置属性toString、valueOf等等,这些不可枚举的内置属性,如果被我们所重写的话,不同浏览器的重写结果是不一致的; 比如较为古早的浏览器IE6/7/8,在IE6/7/8上运行上面的代码,返回的就是true;
因此,这段代码的意义,就是为了重写一些内置属性时,判断浏览器的兼容性;
虽然来源是fabric,但这段代码最初是出现在prototype.js,虽然这段代码在现代浏览器实用性微乎其微,但mark一下增长一些知识点和广度也不差~
最后,贴上fabric调用该方法后续的代码:
//fabric.text中的toString, 即下面的source.toString
toString: function() {
return '#<fabric.Text (' + this.complexity() +
'): { "text": "' + this.text + '", "fontFamily": "' + this.fontFamily + '" }>';
},
if (IS_DONTENUM_BUGGY) {
if (source.toString !== Object.prototype.toString) {
klass.prototype.toString = source.toString;
}
if (source.valueOf !== Object.prototype.valueOf) {
klass.prototype.valueOf = source.valueOf;
}
}
整段代码,我自己理解的话就是: 如果是现代浏览器,直接重写toString后,调用就会立即生效; 但IE6/7/8可能存在兼容性问题,所以需要做多余的一步,将其重写的toString、valueOf方法,挂载到对象上;