创建一个`.prototype` getter

时间:2013-10-15 11:59:13

标签: javascript prototype

我想要一个javascript函数来获取元素的数据属性。我想在本机JS'元素上使用它。

我一直在寻找原型吸气剂,但我无法理解它是如何工作的(javascript不是我的一杯茶 )。

我想要的是什么:

this.myCustomFunction('fooBar'); // the `this` element
document.getElementById('ExampleId').myCustomFunction('fooBar'); // another way of selecting

我找到的所有例子都是我自己创建的对象,我想要一个像上面的例子。

提供基准here you can find the benchmark

如果有人能给我一个小例子,并对代码如何流动做出一些解释,那就太好了(或者如何调用它,以备将来参考)。


第一条评论建议我不要这样做。如果还有其他解决方案,我会再解释一下我的目标。这就是我现在所处的位置:

Object.prototype.cms_getDataAttr = function(dataname){
    // IE upto 10 doenst work with dataset, so use the slower 'getAttribute'
    if( typeof this.dataset == 'undefined'){
         return this.getAttribute('data-'+dataname);
    }
    else{
        // I want to use this one instead, benchmarked this is ALOT faster
        return this.dataset.bigsrc;
    }
}

3 个答案:

答案 0 :(得分:1)

我不确定这是你想要的,但你可以使用setAttribute和getAttribute读取和编写元素的html属性(包括数据属性):

element.getAttribute("data-foo"); // ==> Returns the value of the data-attribute
element.setAttribute("data-foo", "newValue"); // ==> Changes the value of the data-attribute to "newValue"

答案 1 :(得分:1)

通常,您应该避免扩展本机Javascript对象的原型。这个建议的最大原因之一是,如果不同的程序员使用相同的函数名进行本机原型扩展,它可能会导致冲突,这意味着第一个程序员的函数现在会做一些完全不同的事情。如果您想在某些时候将某些代码转换为可重用的库以与其他程序员或项目共享,该怎么办?如果其中一个程序员有他/她自己的getDataAttr函数做了与你不同的函数,那么你的代码或其他程序员都需要重写。因此,如果每个人都避免扩展本机对象,那就更好了,除了编写填充程序以添加对旧版浏览器的支持以获得已成为标准的功能。

正如@Bergi指出的那样,在这种情况下,您实际上可以使用较新浏览器上可用的本机dataset属性。使用垫片,例如this one,您现在可以简单地访问任何元素的dataset属性,无论您使用哪个浏览器,这意味着您不再需要自定义函数。这就是我在这种情况下推荐的,因为当那些旧的浏览器过时时,你甚至不再需要垫片了,显然本机方法表现更好,并且更容易让其他程序员使用。

通常,扩展本机原型的一个很好的替代方法是执行类似于jQuery的操作 - 编写一个包装本机对象的函数,并使用其他方法“扩展”它,但不实际修改对象本身。正如我所说,我认为dataset垫片在这种特殊情况下是一个更好的解决方案,但这是一个有用的方法来了解一般情况。这是一个例子:

function ExtendedDomElement(element) {
    this.element = element;
}

ExtendedDomElement.prototype = {
    constructor: ExtendedDomElement,
    getDataAttr: function(dataname) {
        var element = this.element;

        // IE upto 10 doenst work with dataset, so use the slower 'getAttribute'
        if( typeof element.dataset == 'undefined'){
             return element.getAttribute('data-'+dataname);
        }
        else {
            return element.dataset[dataname];
        }
    }
}

function extendDomElement(element) {
    return new ExtendedDomElement(element);
}

function byId(id) {
    return extendDomElement(document.getElementById(id));
}


var fooElementExtended = byId('foo');
var bar = fooElementExtended.getDataAttr('bar');

答案 2 :(得分:0)

  

这就是我现在所处的位置:

Object.prototype.cms_getDataAttr = function(dataname){
    if (typeof this.dataset == 'undefined')
        return this.getAttribute('data-'+dataname);
    else
        return this.dataset.bigsrc;
};

您应该只展开DOM Element interface,而不是所有Objects

此外,您可能不会编写自己的数据集方法,只需使用existing dataset property shim