【问题标题】:Inheriting from the DOM Element object in javascript ! Whats wrong with this code?继承自 javascript 中的 DOM Element 对象!这段代码有什么问题?
【发布时间】:2013-04-11 02:18:03
【问题描述】:

我正在尝试从 DOM Element 对象继承,当我创建对象时所有代码都运行良好,但是当我尝试调用 appendChild() 方法时,它给出了一个错误提示:

MyObject doesn't have an appendChild method

这是我的代码:

var content=document.createTextNode("This was dynamically created");
function MyObject(tagName){
    Element.constructor.call(this,tagName);
    this.prototype=Element.prototype;
    this.prototype=Object.defineProperties(this.prototype,{
       newMethod:function(){
       //dosomething

       }
    });
}
var newObj=new MyObject("div");
newObj.appendChild(content);

【问题讨论】:

    标签: javascript dom element prototypal-inheritance


    【解决方案1】:

    虽然你做错了(稍后会详细介绍),你最终还是试图传递一个继承自 DOM 元素而不是 DOM 元素本身的对象。这是不允许的。

    看起来应该可以,但是 DOM 元素和 DOM 方法是宿主对象。它们不会按照您对本机对象所期望的所有相同规则进行操作。 .appendChild() 方法只需要一个元素,仅此而已。所以你试图做的事情不会奏效。


    关于您的继承方法,这是完全不正确的。您不会修改正在创建的新对象的 .prototype 属性。您修改构造函数的.prototype。它只完成一次,然后从构造函数创建的所有新对象都继承自分配给该构造函数的 .prototype 属性的对象。

    因为没有继承方式,所以没有.appendChild() 方法。下面的代码修复了它,但由于上面给出的原因,它仍然无法工作。

    function MyObject(tagName){
        Element.call(this, tagName);
    }
    
    MyObject.prototype=Object.create(Element.prototype);
    
    Object.defineProperties(MyObject.prototype,{
       newMethod: {
           value:function(){
               //dosomething
           }
       }
    });
    

    你的属性描述符语法也是错误的,所以我修复了它。

    【讨论】:

    • 您能否解释一下宿主对象允许什么以及不允许什么?
    • @RomanticElectron:这很难做到。我相信 ECMAScript 5 对宿主对象的行为和不需要实现的行为给出了更多的定义,但这可能是一个比我想在这里深入探讨的更大的话题。我需要再读一遍。我建议在the spec 中搜索“主机对象”。我做了一个快速的,我发现的第一件事是“本机对象是否可以将宿主对象作为其 [[Prototype]] 取决于实现。”
    • 我相信您的代码在Element.call(this,tagName) 出现错误
    • @RomanticElectron:确实如此......原因与我在回答的第一部分中提到的原因相同。 Element 构造函数(一个宿主对象) 只想以它的典型方式被调用。不与this 一样的任何其他对象。我只是展示了您通常如何设置继承。
    【解决方案2】:

    这是因为调用Element的构造函数不会创建DOM Element对象的实例,而是尝试设置DOM Element对象的构造函数设置的属性,例如

    function MyObject(tagName){
    Element.constructor.call(this, tagName);
    }
    var newObj=new MyObject("div");
    

    不会创建tagName 属性,就像我们创建 DOM Element 对象的实例时可用的属性,并且

    alert("Tag Name is set to "+newObj.tagName);
    

    会显示

    Tag Name is set to undefined
    

    因为构造函数试图设置它但它不能因为没有tagName属性但是如果我用document.createElement(tagName)替换Element.constructor.call(this, tagName);你会得到结果

    Tag Name is set to DIV
    

    【讨论】:

    • 这是不正确的。 1) 您的构造函数没有返回继承自 DOM 元素的 MyObject 的新实例。它返回 DOM 元素本身,因此您可以完全删除构造函数,只需直接调用 document.createElement(),您就会做同样的事情。 2) tempObj.prototype = Element.prototype 只是向指向Element.prototype 的新元素添加一个新属性。它与继承无关。 3) 当您在tempObject.prototype 上放置新属性时,您现在将它们直接放在Element.prototype 上,因为...
    • ...我在上面第 2 点中提到的您的任务。这意味着您正在添加 newMethod() do all DOM 元素。最终结果与this example 几乎相同。
    • ...我在回答中试图向您传达的是,您无法做您想做的事情。如果可以的话,世界各地的人都会这样做,因为它真的很方便。但是没有人这样做......因为他们不能......因为它不起作用。
    • @amnotiam 是的,你是对的兄弟,谢谢你的帮助,我会更新我的答案
    猜你喜欢
    • 1970-01-01
    • 2022-11-16
    • 2016-10-05
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多