简体   繁体   English

如何在jQuery / JavaScript中扩展返回的对象

[英]How to extend returned object in jQuery/JavaScript

I would like to extend/derive from the XML Document returned by jQuery's $.parseXML() function, to add my own properties/functions. 我想从jQuery的$.parseXML()函数返回的XML文档中扩展/派生,以添加我自己的属性/函数。 I am new to jQuery/JavaScript object inheritance. 我是jQuery / JavaScript对象继承的新手。 I have tried to read all over the web but am not "getting" it. 我试图阅读整个网络,但没有“了解”它。

In, say, C# classes I could write something (kept simple) like this: 在C#类中,我可以这样写(保持简单):

public class MyXmlDocument : XmlDocument
{
  public MyXmlDocument(string xmlText)
  {
    this.LoadXml(xmlText);
  }

  public string SomeVariable;
  ...

  public XmlNode FindCertainNode()
  {
    return this.SelectSingleNode("certain");
  }
  ...
}

MyXmlDocument xmlDoc = new MyXmlDocument(xmlText);
xmlDoc.AppendChild(...);  // XmlDocument method
XmlNode xmlNode = xmlDoc.FindCertainNode();  // MyXmlDocument method
etc.

I hesitate to show my jQuery/JavaScript attempt because I am quite at sea, but I know people like to see something, so please regard it as "some ideas I have been playing with": 我犹豫要显示我的jQuery / JavaScript尝试,因为我正处于海上航行,但是我知道人们喜欢看到一些东西,因此请将其视为“我一直在使用的一些想法”:

// One approach
function XMLDoc(xmlText)
{
  var parseXML = function (xmlText)
  {
    //var parser = new DOMParser();
    //var xmlDoc = parser.parseFromString(xmlText, "text/xml");
    var xmlDoc = $.parseXML(xmlText);
    return xmlDoc;
  };

  var findCertainNode = function ()
  {
    return this.find('certain');
  }

  return parseXML(xmlText);
}

// Another approach
var XMLDoc = $.extend({}, $.parseXML.prototype, {
  findCertainNode: function () {
    this.find('certain');
  }
});

I am expecting to be able to access existing functionality for the XML document plus my own extensions, along the lines of: 我希望能够通过以下方式访问XML文档的现有功能以及我自己的扩展:

var xmlDoc = new XMLDoc(xmlText);
var $xmlDoc = $(xmlDoc);
$xmlDoc.find('certain');  // jQuery method
$xmlDoc.findCertainNode();  // my additional method

I also know that I am unclear about whether my code should be returning plain JavaScript objects or jQuery ones. 我也知道我不清楚我的代码应该返回纯JavaScript对象还是jQuery对象。 I am thinking jQuery ones, so that I can easily call for example jQuery's .find() etc. 我在考虑jQuery,因此可以轻松地调用jQuery的.find()等。

It is important to me that the code should all be wrapped inside a single function/object or similar for editing/viewing, as both my attempts do. 对我来说很重要,就像我的两次尝试一样,都应将代码全部包装在一个函数/对象或类似物中以进行编辑/查看。

If someone could show how they would implement the C# pattern I think that would answer my question, and I should be most grateful. 如果有人可以展示他们将如何实现C#模式,我认为这将回答我的问题,我应该非常感谢。

EDIT: Solution 编辑:解决方案

I am marking @Karol's solution below ( https://stackoverflow.com/a/42672481/489865 ) as the accepted one as he did the most work to answer my question as phrased. 我在下面将@Karol的解决方案( https://stackoverflow.com/a/42672481/489865 )标记为可以接受的解决方案,因为他在回答我提出的问题方面做得最多。

However, I have come to realise that the object returned from $.parseXML() / DOMParser().parseFromString() is not some special "XML document", it's just an element, and as such has no special methods. 但是,我已经意识到从$.parseXML() / DOMParser().parseFromString()返回的对象不是某些特殊的“ XML文档”,它只是一个元素,因此没有特殊的方法。 It is not worth it to derive/inherit from it, and so encapsulation is adequate and simpler. 从它派生/继承是不值得的,因此封装是足够且简单的。 My pattern looks like: 我的模式如下:

var XMLDoc = function (xmlText) {
  this._xmlDoc = $.parseXML(xmlText);
};

$.extend(XMLDoc.prototype, {
    doc: this._xmlDoc,
    find: function (selector) {
      return $(this._xmlDoc).find(selector);
    },
    findCertain: function () {
      return $(this._xmlDoc).find("certain");
    },
    ...
});

var xmlDoc = new XMLDoc(xmlText);
xmlDoc.find('something');
xmlDoc.findCertainNode();

Try with: 尝试:

var xmlDoc = new XMLDoc(xmlText);
$.extend( xmlDoc, {
  find: function(par){
          // your function
        }
});

Try to do sth like this: 尝试做这样的事情:

function XMLDoc(xmlText) { //constructor
  this._xmlDoc = $.parseXML(xmlText); //'_' is JS convention for private fields
}
XMLDoc.prototype = {
  findCertainNode: function() {
    return $(this._xmlDoc).find('certain');
  }
  /* other methods here */
}

var myXML = new XMLDoc('<a><certain /></a>')
myXML.findCertainNode(); //[<certain />]

Or the same with ES6 syntax: 或与ES6语法相同:

class XMLDoc {
  constructor(xmlText) {
    this._xmlDoc = $.parseXML(xmlText);
  }
  findCertainNode() {
    return $(this._xmlDoc).find('certain');
  }
}

var myXML = new XMLDoc('<a><certain /></a>')
myXML.findCertainNode(); //[<certain />]

I think the real inheritance from jQuery is impossible, but if you really want to have an ability to use it in C# way, you can do sth like this: 我认为从jQuery真正继承是不可能的,但是如果您真的想拥有以C#方式使用它的能力,则可以执行以下操作:

Object.keys(Object.getPrototypeOf($())).forEach(function(key){
  XMLDoc.prototype[key] = function() {
    return $(this._xmlDoc)[key].apply(null, arguments);
  }
})

Or in ES6: 或在ES6中:

Object.keys(Object.getPrototypeOf($())).forEach(key => {
  XMLDoc.prototype[key] = () => {
    return $(this._xmlDoc)[key](...arguments);
  }
})

Then you can fire all jQuery methods as they were inherited. 然后,您可以在所有jQuery方法被继承时触发它们。

And if you'd like to overload some of them, remember to do this overloading after the code above. 而且,如果您想重载其中的一些,请记住在上面的代码之后进行此重载。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM