扩展现有对象以添加额外的 JavaScript 原型方法

Extending existing Object to add additional JavaScript Prototype methods

假设我有一个类似于下面的函数,它创建了一个非常简单的微型图书馆:

var microLib = function(selector) {
    var el;
    var selectorEngine = function(selector)
    {
        var selector_value = selector.slice(1);
        return document.getElementById(selector_value);
    };

    el = selectorEngine(selector);

    Element.prototype.func_1 = function(){
        return 'first';
    };

    Element.prototype.func_2 = function(){
        return 'second';
    };

    return el;
};
window._$ = microLib;

此脚本将允许我编写如下代码:

var elem = _$("#div_with_id");   //some element on my web page
console.log(elem.func_2());      //outputs 'second' in the console 

所以现在,我正在寻找一种方法来在补充代码中扩展 _$ 以添加额外的 Element.prototype 方法,这样我就可以编写:

console.log(elem.func_3());    //to output 'third' in the console

我需要这样做的原因是因为这个 extension 需要在另一个 JavaScript 文件中进行,否则我会添加另一个方法并且是完成它。

我该怎么做?

这是我建议的方法示例:http://jsfiddle.net/rbxssmx8/

JS:

var toArray = Function.prototype.call.bind(Array.prototype.slice);
var qAll = document.querySelectorAll.bind(document);

var _$ = (function() {
    function dom(selector) {
        if(!(this instanceof dom)) {
            return new dom(selector);
        }

        this.elements = toArray(qAll(selector));
    }    

    dom.prototype.iterate = function(func) {
        this.elements.forEach(func);
        return this;
    };

    dom.prototype.addClass = function() {
        var klasses = arguments;
        return this.iterate(function(element) {
            element.classList.add.apply(element.classList, klasses);
        });
    };

    dom.extend = function(name, func) {
        this.prototype[name] = func;    
    };

    dom.ready = function(func) {
        document.addEventListener("DOMContentLoaded", func);    
    };

    return dom;
})();

_$.extend("removeClass", function() {
    var klasses = arguments;
    return this.iterate(function(element) {
        element.classList.remove.apply(element.classList, klasses);    
    });
});

_$("div").addClass("gray");
var $el = _$("div:last-of-type");
$el.removeClass("gray");

所以我在 What's wrong with extending the DOM and the alternative suggested by the author was to use Object Wrappers. A quick search on that led me to this post on SO: Using object wrappers to extend the JavaScripts DOM?

上阅读了这篇 post

结合@DRD 的回答,我更新了我的代码:

(function() {

    var microLib = function (selector){
        return new Dom(selector);
    };

    function Dom(selector)
    {
        var selector_value = selector.slice(1);
        this.element = document.getElementById(selector_value);
    }

    Dom.prototype.func_1 = function(){
        return 'first';
    };

    Dom.prototype.func_2 = function(){
        return 'second';
    };

    microLib.extend = function(name, func){
        Dom.prototype[name] = func;
    };

    window._$ = microLib;

})();

然后,每当您想扩展和添加另一个功能时,请在之后执行此操作:

_$.extend('func_3', function(){ //this is inline with my earlier question
     return 'third';
});

很有魅力!与扩展 Element.prototype.

相比,绝对 更安全 选项