Javascript 对Object.defineProperties函数感到困惑

Javascript 对Object.defineProperties函数感到困惑,javascript,function,Javascript,Function,因此,我有一个名为hasClass的元素原型函数 Element.prototype.hasClass = function (className) { if (className && typeof className === "string") { if (this.classList) { return this.classList.contains(className); }

因此,我有一个名为
hasClass
的元素原型函数

Element.prototype.hasClass = function (className) 
{
    if  (className && typeof className === "string") 
    {
        if (this.classList) 
        {
            return this.classList.contains(className);
        } 
        else
        {
            return new RegExp(className).test("" + this.className + "");
        }
    }    
};
现在,因为我必须定义多个函数,代码会变得非常混乱,所以我想,为什么不使用
Object.defineProperties
function;与函数相同的函数:

Object.defineProperties(Element.prototype, {
    "hasClass": {
        get: function (className) 
        {
            if (className && typeof className === "string")
            {
                if (this.classList)
                {
                    return this.classList.contains(className);
                }
                else
                {
                    return new RegExp(className).test("" + this.className + "");
                }
            }
        }
    }
});
第一个函数正常工作。 但是,当使用
对象定义相同的函数时,defineProperties
我的Firefox控制台开始发出垃圾邮件:
类型错误:$test.hasClass不是函数(其中
$test
是使用选择器选择的元素)。此错误在使用普通函数的第一个示例时不会出现,而在使用lattest函数时会出现

所以问题是。为什么它会抛出这样的错误,而它不应该抛出这样的错误

哦,是的,有趣的是,当我在控制台.log中使用第二个函数时,像这样:

Object.defineProperties(Element.prototype, {
    "hasClass": {
        get: function (className) 
        {
            /*if (className && typeof className === "string")
            {
                if (this.classList)
                {
                    return this.classList.contains(className);
                }
                else
                {
                    return new RegExp(className).test("" + this.className + "");
                }
            }*/
            console.log( "HI");
        }
    }
});
extend1(Element.prototype, {
    hasClass: function (className) {
        /* the body */
    },

    methodFoo: function (arg1, arg2) {},

    methodBar: function () {},
});
然后控制台说:


我很困惑。

对象。defineProperty
对象。defineProperties
并不意味着用参数定义getter函数。在您的情况下,只需按照第一个示例中的操作即可(或者查看下面的,请参见编辑)

您可以将Object.defineProperty理解为“截获”普通set/get操作的一种方式,但在获取或设置属性的代码中,您看不到与“public”属性的区别

obj.abc = 'value';    // <-- set function called
console.log(obj.abc); // <-- get function called
现在您可以像这样扩展您的原型:

Object.defineProperties(Element.prototype, {
    "hasClass": {
        get: function (className) 
        {
            /*if (className && typeof className === "string")
            {
                if (this.classList)
                {
                    return this.classList.contains(className);
                }
                else
                {
                    return new RegExp(className).test("" + this.className + "");
                }
            }*/
            console.log( "HI");
        }
    }
});
extend1(Element.prototype, {
    hasClass: function (className) {
        /* the body */
    },

    methodFoo: function (arg1, arg2) {},

    methodBar: function () {},
});

我认为,对于方法来说,这是一种比使用
Object.defineProperty
更好的方法。对于不动产定义,采用
对象。defineProperty

您错误地使用了属性
get
您应该使用
value
,否则
hasClass
将是
get
函数返回的

值替换
获取

Object.defineProperties(Element.prototype, {
    "hasClass": {
        value: function (className) 
        {
            /*if (className && typeof className === "string")
            {
                if (this.classList)
                {
                    return this.classList.contains(className);
                }
                else
                {
                    return new RegExp(className).test("" + this.className + "");
                }
            }*/
            console.log( "HI");
        }
    }
});


问题:在您的版本中,
hasClass
的值将是未定义的,因为您没有从get函数返回任何内容。最后一条语句是
console.log(“HI”)如果您放置
返回{}在那之后,
hasClass=={}

不要将其作为函数调用。你不将其作为函数调用是什么意思?好的,现在我明白了。获取变量的返回值,但我将其称为函数,因此我必须在这里搜索某些替代项。除了get和set…我不知道…似乎我必须使用第一个函数示例…哇,谢谢。当我用value替换get时,它不起作用。谢谢@user3595905您可能还想将
可枚举:false
可写:true
设置为与本机方法{IMHO}完全相同。这是对
对象的错误使用。defineProperty
。上述
hasClass
的语义与典型属性不同。因此,这个答案只是一个解决办法,不会出现
TypeError
,但它不会产生好的JavaScript。{/IMHO}@hgoebl我回答了这个问题,但是,如果OP没有使用
enumerable:false
,那么这是毫无意义的,但是他应该使用Object.defineProperty
with
enumerable:false
来实现他试图实现的目标我会说,一开始我考虑使用extend函数,然而,我开始四处寻找是否有更好的方法像本机方法一样进行操作,因此我最终选择了
Object.defineProperties
,在某些编码之后,它看起来……毫无用处。我想我会继续使用简单的扩展,而不是使用一些不成熟的本地方法。谢谢你的回复。我会接受你的提示和解释。再一次,谢谢。是的,这是真的,我正在寻找一个不那么冗长的方式来做到这一点。事实上,在处理了
Object.defineProperties
之后,我现在发现扩展方式更好了。真正地谢谢你的提醒!不客气。你在寻找替代方案吗?如果不是,您可以考虑将答案标记为正确和/或帮助。