Javascript的奇怪行为';s____定义设置__

Javascript的奇怪行为';s____定义设置__,javascript,firefox,google-chrome,variable-assignment,Javascript,Firefox,Google Chrome,Variable Assignment,我有一个大型项目,需要截取对element.src、element.href、element.style等的赋值。我想用defineSetter实现这一点,但它的行为非常奇怪(使用Chrome 8.0.552.231) 例如: var attribs = ["href", "src", "background", "action", "onblur", "style", "onchange", "onclick", "ondblclick", "onerror", "onfocus", "onk

我有一个大型项目,需要截取对element.src、element.href、element.style等的赋值。我想用defineSetter实现这一点,但它的行为非常奇怪(使用Chrome 8.0.552.231)

例如:

var attribs = ["href", "src", "background", "action", "onblur", "style", "onchange", "onclick", "ondblclick", "onerror", "onfocus", "onkeydown", "onkeypress", "onkeyup", "onmousedown", "onmousemove", "onmouseover", "onmouseup", "onresize", "onselect", "onunload"];
for(a = 0; a < attribs.length; a++) {
  var attrib_name = attribs[a];
  var func = new Function("attrib_value", "this.setAttribute(\"" + attrib_name + "\", attrib_value.toUpperCase());");
  HTMLElement.prototype.__defineSetter__(attrib_name, func);
}
新的src是“测试”,就像它应该是一样

然而

element.href = "test"
新的href是“test”,而不是大写

然后,即使我尝试
元素。\uuuu lookupSetter\uuuu(“href”)
,它也会返回正确的大写设置器

最奇怪的是,Chrome和Firefox之间正确地截取了不同的变量


救命

这不是个好主意。主机对象(如DOM元素)不受应用于本机JavaScript对象的常规规则的约束,基本上可以做自己喜欢做的事情,所有浏览器或多或少都会利用这一事实。浏览器没有义务为宿主对象提供原型,也没有义务允许您重写宿主对象属性的getter和setter,或者尊重任何重写默认行为的尝试

我强烈建议放弃这种方法,改用另一种方法,比如为DOM元素编写包装器对象

更新:包装器方法示例

您可以为DOM元素创建包装器对象,并通过这些包装器执行所有DOM操作。这是许多图书馆(比如YUI)所做的事情。例如:

function ElementWrapper(el) {
    this.domElement = el;
}

ElementWrapper.prototype = {
    // Wrap the DOM methods you need
    appendChild: function(child) {
        this.domElement.appendChild(child);
    },

    // Add custom behaviour, such as converting certain
    // property values to upper case
    setProperty: function(name, value) {
        if (/^(src|href|action)$/i.test(name)) {
            this.domElement[name] = value.toUpperCase();
        } else {
            this.domElement[name] = value;
        }
    }
};

var wrappedEl = new WrappedElement( document.getElementById("foo") );
wrappedEl.setProperty("href", "http://www.google.com/");

如果您等待为DOM完全定义ECMAScript绑定,那么以更跨浏览器、更符合标准的方式响应Tim并添加我自己的两分钱,您的运气会更好。在这一点上重写应该为您提供精确的、指定良好的行为。但是现在你会感到奇怪。

你能推荐一些其他的方法,或者进一步解释你的意思/如何实现DOM元素的包装器对象吗?
function ElementWrapper(el) {
    this.domElement = el;
}

ElementWrapper.prototype = {
    // Wrap the DOM methods you need
    appendChild: function(child) {
        this.domElement.appendChild(child);
    },

    // Add custom behaviour, such as converting certain
    // property values to upper case
    setProperty: function(name, value) {
        if (/^(src|href|action)$/i.test(name)) {
            this.domElement[name] = value.toUpperCase();
        } else {
            this.domElement[name] = value;
        }
    }
};

var wrappedEl = new WrappedElement( document.getElementById("foo") );
wrappedEl.setProperty("href", "http://www.google.com/");