在 Javascript 对象的某个属性中添加对 Javascript 对象的引用是一种不好的做法吗?
Is it a bad practice to add reference to a Javascript object in one of its attributes?
假设我有一个这样的设置。
var Account = function(data) {
this.data = data;
this.domElement = (function(){ code that generates DOM element that will represent this account })();
this.domElement.objectReference = this;
}
Account.prototype = {
show: function() { this.domElement.classList.remove('hidden'); },
hide: function() { this.domElement.classList.add('hidden') }
}
我的问题是关于最后一行:this.domElement.objectReference = this;
这将是一件有用的事情,因为这样我就可以将事件侦听器添加到我的 DOM 元素中,并且仍然可以访问对象本身。 例如,我可以添加会影响我的 DOM 元素的方法,例如 hide() 和 show(),而不必直接使用 CSS 修改 DOM 元素的可见性。
我测试了这段代码,它的工作方式就像我想要的那样,但我很好奇这是否会导致内存泄漏或其他一些不愉快,或者这是否是可以接受的事情?
谢谢!卢卡
我知道@PaulS已经回答了这个问题,但我发现答案违反直觉(不希望从帐户构造函数返回 DOM 元素)并且过于以 DOM 为中心,但同时实现非常简单,所以我不确定该怎么想;)
无论如何,我只是想展示一种不同的方式。您可以将Account
实例存储在映射中,并为它们提供唯一的id
(也许它们已经有一个),然后将该id
作为 DOM 元素上的数据属性存储。最后,您实现一个getById
函数或类似的东西,通过从侦听器id
来检索帐户实例。
这几乎就是jQuery data
的工作方式。
下面是一个示例,其中包含您希望从评论中获取的委派事件。
演示
var Account = (function (accounts, id) {
function Account(data) {
accounts[this._id = ++id] = this;
this.el = createEl.call(this);
}
Account.prototype = {
constructor: Account,
show: function() { this.el.classList.remove('hidden'); },
hide: function() { this.el.classList.add('hidden'); }
};
function createEl() {
var el = this.el = document.createElement('div');
el.className = 'account';
el.innerHTML = el.dataset.accountId = this._id;
return el;
}
Account.getById = function (id) {
return accounts[id];
};
Account.init = function () {
//add delegate listeners
document.addEventListener('click', function (e) {
var target = e.target,
account = Account.getById(target.dataset.accountId);
if (!account) return;
account.hide();
});
};
return Account;
})({}, 0);
//once DOM loaded
Account.init(); //start listening to events
var body = document.body;
body.appendChild(new Account().el);
body.appendChild(new Account().el);
为什么不把domElement
作为一个var
的,并从你的函数中return
它呢?要保留对构造对象的引用(但仅在this
符合预期的情况下),您可以执行if (this instanceof Account) domElement.objectReference = this;
现在,您已经从循环引用中拯救了自己,并且可以访问节点和对象。如果您预计会丢失对 Account 实例的直接引用,但希望在以后某个时间"查找"与其相关的节点时需要它,则这样做会更有帮助。
按要求编码
var Account = function (data) {
var domElement; // var it
this.data = data;
domElement = (function(){/* ... */}()); // use var
if (this instanceof Account)
domElement.objectReference = this; // assign `this`
return domElement;
};
// prototype as before
返回的元素现在是 Node,而不是 Object;因此您可以像这样访问 Account 实例。
var domElement = new Account();
domElement.objectReference.show(); // for example
在我看来,在对象本身内部引用对象没有什么好处。造成这种情况的主要原因是复杂性和晦涩难懂。
如果您稍后在代码中指出您如何使用此domElement.objectReference
,我相信我或其他人将能够在没有此引用的情况下提供解决方案。
- Chrome开发工具(如何知道我在调用哪个javascript对象)
- 循环遍历以数组为值的Javascript对象
- 从ajax请求中获取javascript对象
- 如何从对象的原型方法访问JavaScript对象属性
- 将XML转换为普通的旧JavaScript对象
- 通过引用传递JavaScript对象
- javascript对象操作:根据指定条件选择属性
- Javascript对象类在单击时打开窗口进行颜色选择,并在更改时替换对象背景颜色
- 如何在异步函数中使用javascript对象
- 临时Javascript对象
- 如何在ASP中为用户控件添加Javascript对象网
- 使用数组向下搜索Javascript对象
- Rails将JavaScript对象存储到Model的有效方式
- JavaScript对象不是从原型链继承的
- 如何创建具有默认值的JavaScript对象字段?(AngularJS模型相关)
- SetInterval在javascript对象中表现怪异
- Javascript 对象和 this 关键字
- 如何在不知道关键字的情况下访问javascript对象值
- 在 JavaScript 对象中设置要使用的运算符的属性
- 如何搜索JavaScript对象并更改值