【问题标题】:Object.create not supported in ie8ie8 不支持 Object.create
【发布时间】:2013-08-03 22:09:19
【问题描述】:

我遇到了一个插件问题,该插件使用 jquery 中的 object.create 创建日期下拉列表。我刚刚在 IE 8 中注意到它抛出了以下错误:

SCRIPT438: Object doesn't support property or method 'create'

代码如下:

var dropdateobj = Object.create(dropdatefuncs);
dropdateobj.create(options, this);
$.data(this, 'dropdate', dropdateobj);

对于 IE8 或更高版本的跨浏览器兼容有什么好的解决方法?

提前致谢!

【问题讨论】:

  • 如果你看,不难找到垫片。
  • 这是谷歌搜索Object.create IE8时出现的第一个问题。 +1

标签: javascript jquery object internet-explorer-8


【解决方案1】:

如果您需要Object.create,您很有可能还需要依赖其他 es5 功能。因此,在大多数情况下,适当的解决方案是使用es5-shim

但是,如果 Object.create 是您唯一需要的,并且您只使用它来纯粹设置原型链,那么这里有一个轻量级的 poly-fill,它不支持将 null 作为第一个参数并且不支持第二个properties 参数。

这是规格:

15.2.3.5 Object.create(O[,Properties])

create 函数创建一个具有指定原型的新对象。 调用create函数时,会采取以下步骤:

如果 Type(O) 不是 Object 或 Null,则抛出 TypeError 异常。

让 obj 是创建一个新对象的结果,就好像通过表达式 new Object() 其中 Object 是标准的内置构造函数 那个名字

设置obj的[[Prototype]]内部属性为O。

如果参数属性存在且未定义,则添加自己的 obj 的属性,就像调用标准的内置函数一样 带有参数 obj 和 Properties 的 Object.defineProperties。

返回对象。

这是轻量级的实现:

if (!Object.create) {
    Object.create = function(o, properties) {
        if (typeof o !== 'object' && typeof o !== 'function') throw new TypeError('Object prototype may only be an Object: ' + o);
        else if (o === null) throw new Error("This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.");

        if (typeof properties != 'undefined') throw new Error("This browser's implementation of Object.create is a shim and doesn't support a second argument.");

        function F() {}

        F.prototype = o;

        return new F();
    };
}

【讨论】:

  • 第二个参数开个玩笑,不知道有没有人真的在实际代码中使用那种可笑的冗长语法来创建对象
  • @plalx:MDN 是协作编辑的。没有“官方”的。我在 MDN 上看到了一些 seriously 有缺陷的代码。 (例如,查看Array#forEach page 上的第一个“兼容性”示例。完全完全错误。)请参阅es5-shim 中的实现,以了解至少尽最大努力的内容。
  • @Esailija:这种荒谬冗长的语法是目前唯一可用于定义属性描述符的语法。
  • @CrazyTrain defineProperty 还是 defineProperties?
  • @Esailija:它们对属性描述符使用相同的语法。
【解决方案2】:

有几个 shims 提供此功能,包括 this one

请注意,Object.create 不能完美地填充,因为除其他外,它可以创建不可枚举的属性或带有 getter 和 setter 的属性,而您不能在所有情况下都这样做ES5 之前的浏览器。 (您可以使用专有语法在一些 ES5 之前的浏览器上执行 getter 和 setter,但我不相信在 IE8 上。)它只能是伪垫片。

但是对于您引用的用例,可以使用伪垫片。

为了完整起见,这里有一个可以填充的简单版本:

if (!Object.create) {
    Object.create = function(proto, props) {
        if (typeof props !== "undefined") {
            throw "The multiple-argument version of Object.create is not provided by this browser and cannot be shimmed.";
        }
        function ctor() { }
        ctor.prototype = proto;
        return new ctor();
    };
}

【讨论】:

  • 这个 polyfill 比 plalx 在另一个答案中提出的那个更容易阅读,尽管两者都可以。
  • @plalx:重新效率:我敢打赌,这是无法衡量的 :-) ——当然在任何实际用例中都不重要。我更喜欢创建的对象之间绝对没有联系的清洁度。 “另外,我认为直接抛出字符串不是很好,因为它破坏了错误约定。” JavaScript 中没有错误约定。但是是的,new Error 在支持它的浏览器上可能会更好。
  • @T.J.Crowder 我认为您不留下链接是对的。我更改了发布的实现以使其更接近规范,同时尽可能保持轻量级。也转换为社区 wiki。
  • @plalx:你很好地整理了被接受的答案,真是太好了。 SO 的全部内容。
【解决方案3】:

这将使 Object.create() 在 IE 8 中工作。

我尝试了 shim/sham,但这对我不起作用。

if (typeof Object.create !== 'function') {
 Object.create = function(o, props) {
  function F() {}
  F.prototype = o;

  if (typeof(props) === "object") {
   for (prop in props) {
    if (props.hasOwnProperty((prop))) {
     F[prop] = props[prop];
    }
   }
  }
  return new F();
 };
}

【讨论】:

    猜你喜欢
    • 2013-05-30
    • 1970-01-01
    • 2013-01-04
    • 2015-06-23
    • 2012-02-09
    • 2011-12-25
    • 1970-01-01
    • 2014-02-13
    • 2016-10-28
    相关资源
    最近更新 更多