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
withenumerable:false
来实现他试图实现的目标我会说,一开始我考虑使用extend函数,然而,我开始四处寻找是否有更好的方法像本机方法一样进行操作,因此我最终选择了Object.defineProperties
,在某些编码之后,它看起来……毫无用处。我想我会继续使用简单的扩展,而不是使用一些不成熟的本地方法。谢谢你的回复。我会接受你的提示和解释。再一次,谢谢。是的,这是真的,我正在寻找一个不那么冗长的方式来做到这一点。事实上,在处理了Object.defineProperties
之后,我现在发现扩展方式更好了。真正地谢谢你的提醒!不客气。你在寻找替代方案吗?如果不是,您可以考虑将答案标记为正确和/或帮助。