前段时间我试图扩展Object.prototype
......当后来我在控制台中看到来自 jQuery 文件的错误时,我感到很惊讶。我试图找出问题所在,当然我发现扩展Object.prototype
是“邪恶”的信息,“你不应该这样做,因为 JS 是动态语言,你的代码不会很快工作”以及 jQuery 现在将添加hasOwnProperty
方法的信息到他们的for in
循环。
因为我不想离开 jQuery,所以我放弃了扩展Object.prototype
.
直到现在。我的项目越来越大,我真的很生气,因为我必须多次重复代码的某些部分。以下是我在项目中使用的一些结构:
图表.js:
CHARTS = {
_init: function () {
this.monthlyChart();
/*
*
* more propertys goes here
*
*/
return this;
},
monthlyChart: function () {
//create my chart
return {
update: function () {
// update chart
}
};
}()
/*
*
* more propertys goes here
*
*/
}._init;
仪表板.js
NAVBAR = {
_init: function () {
/*
*
* more propertys goes here
*
*/
return this;
},
doSomething: function(){
$(document).ready(function(){
$('.myButton').on('click', function(){
var data = [];
// calling property from charts.js
CHARTS.monthlyChart.update(data);
});
});
}
}._init
正如我提到的,项目现在真的很大——它有 40 多个 js 文件,其中一些有几千行代码。_init
我每次都必须重复部分真的很烦人,还有很多功能我必须重复$(document).ready
&& $(window).load
。
我试图为我的问题找到另一种解决方案。我尝试创建具有init
属性的类(您可以在此处找到更多),但我这个解决方案迫使我向每个文件添加另一个“不必要”的代码片段,并且访问其他文件对象属性也使其变得复杂(在任何地方返回适当的对象等)。正如评论中所建议的,我开始阅读 JS 中的 getter 和 setter。
毕竟我创造了这样的东西:
//Auto initialization
if (typeof $document === 'undefined') {
var $document = $(document),
$window = $(window),
$body = $('body');
}
Object.defineProperty(Object.prototype, '_init', {
get: function () {
// if object has no property named `_init`
if (!this.hasOwnProperty('_init')) {
for (var key in this) {
// checking if name of property does starts from '_' and if it is function
if (this.hasOwnProperty(key) && key[0] === '_' && typeof this[key] === 'function') {
if (key.indexOf('_ready_') > -1) {
//add function to document ready if property name starts from '_ready_'
$document.ready(this[key].bind(this));
} else if (key.indexOf('_load_') > -1) {
//add function to window load if property name starts from '_load_'
$window.load(this[key].bind(this));
} else {
// else execute function now
this[key].bind(this)();
}
}
}
return this;
}
}
});
和我的对象:
var DASHBOARD = {
_runMe: function(){
},
_ready_runMeOnReady: function(){
},
_load_runMeOnLoad: function(){
},
iAmAString: ''
}._init
这个解决方案似乎适用于 jQuery。但是使用起来安全吗?我没有看到代码可能导致的任何问题,也没有看到它可能导致的任何进一步问题。如果有人告诉我为什么我不应该使用这个解决方案,我会非常高兴。
此外,我正在尝试详细了解它的工作原理。Object.prototype
从理论上讲,我为by定义了属性defineProperty
,但没有为其赋值。不知何故,它不会在 jQueryfore in
循环中导致任何错误,为什么?这是否意味着_init
在某些时候或根本没有定义属性,因为我只定义了它的 getter?
任何帮助将不胜感激 :)