0

我相信我在 IE9+ 和/或 YUI 3 中使用 hasOwnProperty javascript 方法发现了一个错误。我想知道这里是否有人以前见过这个问题,或者你是否能够进一步隔离这个问题。我想将此问题告知相关方,但我不知道是否需要联系 IE 团队或 YUI。

细节:

当 IE9/IE10 为:

  • 以标准模式渲染
  • 涉及一个初始化的 YUI 属性(示例代码中的第 11 行)

hasOwnProperty 为包含无效 javascript 标识符的键的对象返回不正确的值(ab 中的 b 可以,a.5 中的 5 无效)。有效的标识符没有这个问题。

示例代码:

http://jsfiddle.net/bobbyakadizzy/nLZJy/6/(记住这个问题只出现在IE9/IE10)

YUI.add("ie9-hasOwnProperty-test", function (Y) {

        function IE9HasOwnPropertyTest(config) {
            IE9HasOwnPropertyTest.superclass.constructor.apply(this, arguments);
        }

        Y.mix(IE9HasOwnPropertyTest, {
            NAME : "IE9HasOwnPropertyTest",
            ATTRS : {
                attributeWithNumericProperty : {
                    value : {}
                },
                attributeWithStringProperty : {
                    value : {}
                }
            }
        });

        Y.extend(IE9HasOwnPropertyTest, Y.Base, {

            initializer: function (config) {
                // Uncomment this section below the problem will be "fixed".  The problem appears to be related to attribute initialization.
                // this.set("attributeWithNumericProperty", {}); 
                var attributeWithNumericProperty = this.get("attributeWithNumericProperty");
                attributeWithNumericProperty['1234'] = 999;
                GLOBAL_attributeWithNumericProperty = attributeWithNumericProperty;

                // If the object property is an identifier can be set after a dot (e.g. a.b) then the problem will not be hit
                var attributeWithStringProperty = this.get("attributeWithStringProperty");
                attributeWithStringProperty['a1234'] = 999;
                GLOBAL_attributeWithStringProperty = attributeWithStringProperty;
            }
        });
        Y.IE9HasOwnPropertyTest = IE9HasOwnPropertyTest;
    }, "3.0.0", { requires : ["widget"]});

当它应该返回 true 时,运行new Y.IE9HasOwnPropertyTest(); GLOBAL_attributeWithNumericProperty.hasOwnProperty('1234');将返回 false。

4

1 回答 1

0

这是一个非常奇怪的行为。我需要做更多的研究来找出它发生的原因,但这似乎是 YUI 在默认值是对象时处理默认值的方式的结果。YUI 尝试克隆对象以防止这种情况发生:

function MyClass() {
  MyClass.superclass.constructor.apply(this, arguments);
}
Y.extend(MyClass, Y.Base, null, {
  ATTRS: {
    foo: {
      value: []
    }
  }
});

var obj1 = new MyClass();
var obj2 = new MyClass();

obj1.get('foo').push('bar');
console.log(obj2.get('foo')); // ['bar'] oops!

您可以通过不使用对象作为默认值而是使用返回新对象的函数来修复它。这样你总是会得到一个新的对象,YUI 不会太聪明:

MyClass.ATTRS = {
  foo: {
    valueFn: function () {
      return {};
    }
  }
};
于 2013-04-16T15:02:03.893 回答