在用 JS 编码一段时间后,我决定制作自己的框架。类似于 jQuery 的东西。但是一个非常精简的版本。经过一番谷歌搜索后,我整理了这段代码:
function $elect(id) {
if (window === this) {
return new $elect(id);
}
this.elm = document.getElementById(id);
}
$elect.prototype = {
hide: function () { this.elm.style.display = 'none'; },
show: function () { this.elm.style.display = ''; },
toggle: function ()
{
if (this.elm.style.display !== 'none') {
this.elm.style.display = 'none';
} else {
this.elm.style.display = '';
}
}
};
到目前为止这似乎有效。但我对功能不感兴趣。我想了解其中的逻辑。添加方法部分是可以理解的。虽然没看懂
的功能 if (window === this) {
return new $elect(id);
}
如果我删除它,功能就会中断。因为这是一个 if 语句,所以有 2 个结果。 True
或 false
。所以我尝试删除 if 语句并仅使用 return new $elect(id);
假设 window === this
返回 true
,但是那没有用。然后我认为它可能会返回 false
,所以删除了整个 if 语句。那也没有用。有人可以启发我吗?此代码是否有效?我可能遗漏了一些东西。
刚刚在 jsfiddle 上测试过,它不起作用。虽然它适用于 jsbin o.O
编辑:使用 $elect(id).toggle();
调用它。尽管您可以查看演示。
最佳答案
I want to understand the logic.
$elect
是一个 constructor function应该用 new
keyword 调用(新 $select
)。如果不是 ($elect()
),那会发生什么?没有构造实例,this
keyword将指向全局对象 (window
) - 这是我们不想要的。因此,当它检测到它使用 new
正确调用自身并返回它时,这个片段可以防止这种情况。
If I remove it, function breaks
当你像 $elect(id)
一样调用它时没有守卫,它会添加一个 elm
属性到全局对象(本质上是一个全局变量)并且什么都不返回。尝试对其调用 .toggle()
方法会产生异常 undefined has no method 'toggle'
。
I tried to remove the if statement, assuming
window === this
returns true
好吧,那么你刚刚创建了一个无限递归函数,调用时会导致堆栈溢出异常。
顺便说一句,proper way to guard against new
-less invocation不是与 window
进行比较(全局对象在非浏览器环境中可能具有不同的名称)并假设其他一切正常,而是检查正确的继承。您希望构造函数仅应用于您的“类”的实例,即继承自 $elect.prototype
的对象。例如,当使用 new
调用时,这是有保证的。要进行该检查,您将使用 instanceof
operator :
function $elect(id) {
if (! (this instanceof $elect)) {
return new $elect(id);
}
this.elm = document.getElementById(id);
}
这也使守卫的意图变得明确。
关于javascript - 向对象添加方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18877172/