Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

IMG的构造器是谁?

  对于DOM元素对象,W3C中的标准是很弱的。W3C中并没有对DOM元素对象做太多的限制,所以各个浏览器都按照自己喜欢的方式来实现。这就造成了DOM元素对象的构造器很不明确。你不知道这是谁家的娃,更找不到它爸是谁。这篇咱就拿IMG元素来说说这个问题。
  昨天在贴吧看到有人问这个问题,如何知道一个对象是Image的实例呢?这看似很简单吧?只要从构造器来判断就行了嘛,普通的JavaScript对象不都是这么判断的嘛。但是直接从构造器判断的前提就是它得是普通的JavaScript对象,而Image这玩意儿可不普通了。Image的实例可以直接作为DOM对象来使用,我们平时做图片预加载什么的不都是使用这玩意儿嘛。那么它是一个DOM对象吗?那也不对呀!因为DOM对象的构造器应该是HTML*Element才对(IE从IE8+开始引入)。怎么想怎么都不对劲,于是做了下面这个测试。
with(console){
  var a,b;
  a=new Image;
  b=document.createElement("img");
  log("构造器对象是什么?");
  log(a.constructor);
  log(b.constructor);
  log("构造器对象名呢?");
  log(a.constructor.name);
  log(b.constructor.name);
  log("是Image的实例吗?");
  log(a instanceof Image);
  log(b instanceof Image);
  log("是HTMLImageElement的实例吗?");
  log(a instanceof HTMLImageElement);
  log(b instanceof HTMLImageElement);
  log("Image是HTMLImageElement吗?");
  log(Image==HTMLImageElement);
};

  看这个结果要有点耐心,因为他们的差别太大了。这里使用的IE是IE8,在IE8下Image和HTMLImageElement是同一个对象。这里比较特殊,如果这俩是同一个对象就很容易解释IE8下的其它现象了。但是IE9+和其它浏览器中它们不是同一个对象,这里由于屏幕空间有限,IE9+的测试结果就没截图了。区别只是Image和HTMLImageElement在IE9+中不相同而已,和火狐的结果差不多。
  为什么会得到这样的结果呢!?这些浏览器都是如何处理Image和HTMLImageElement对象之间的关系的呢?我们先来看IE下的情况。在IE8中由于Image和HTMLImageElement就是同一个对象,所以所有输出都是合理的。我们要研究的是IE9+中的情况。既然IMG对象是同时继承于Image和HTMLImageElement的,我们就可以猜测Image和HTMLImageElement这两个对象有相同的原型。然后做个测试

  这就可以解释IE9+中为什么输出这个结果。现在我们再看火狐情况,它和IE9+的结果是差不多的,但是把IE上成功的这个结论放入火狐中测试结果为false。这就意味着火狐中的实现方式和IE是不同的,那么什么样的对象结构还可以得到之前测试的输出结果呢?既然它们的原型不同,我们就得更深入的寻找他们原型之间的关系。于是我测试了他们原型的构造器。
  虽然他们的原型构造器也不同,但是有相似之处。从这个原型的构造器来看前者的原型很有可能是继承于后者的,于是再做下面这个测试。

  阿哈,现在终于找到他们之间的关系了。虽然有些复杂,但是从这个关系来看,也可以得到我们之处测试的那个输出结果。如果非要用文字来描述这个关系可以说“HTMLImageElement的原型构造器的原型是Image的原型构造器的实例”这个太拗口了,其实对于我们家族关系复杂的中国人来说,这不算什么。HTMLImageElement他爸是Image他爸的儿子,也就是说HTMLImageElement他爸和Image是同辈的,那么HTMLImageElement应该管Image叫大爷。好吧,不扯这个,大概就是这么个关系。
  最后咱来看看Chrome的情况,从输出的情况来看。继承于Image的一定继承于HTMLImageElement,这就意味着Image的原型本身很有可能也是继承于HTMLImageElement的。直接做这个测试。

  一次搞定,Chrome下的实现还是比较简单的。现在我们就搞明白这三个浏览器中Image与HTMLImageElement之间的关系了。如果是其它浏览器也是类似的推理方法。不过这么混乱的东西,即使我们搞懂了他们之间的关系也很不容易使用。我还是习惯W3C早点对所有DOM元素做出个比较规范和详细的标准,这才是真正能解决问题的途径。
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^