- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
前段时间我尝试扩展 Object.prototype
... 后来我在控制台中看到来自 jQuery 文件的错误时,我感到很惊讶。我试图找出问题所在,当然我发现扩展 Object.prototype
是一个“邪恶”的信息,“你不应该这样做,因为 JS 是动态语言,你的代码将无法工作soon” 以及 jQuery 现在将 hasOwnProperty
方法添加到它们的 for in
循环中的信息。
因为我不想离开 jQuery,所以我放弃了扩展 Object.prototype
的想法。
到现在为止。我的项目越来越大,我真的很生气,因为我不得不多次重复代码的某些部分。下面是我在我的项目中使用的一些结构:
charts.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;
dashboard.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
&& $(窗口).load
.
我试图为我的问题找到另一种解决方案。我试图用 init
属性创建类 (more you can find here)但是我这个解决方案迫使我向每个文件添加另一个“不必要的”代码片段,并且访问其他文件对象属性也使它变得复杂(到处返回适当的对象等)。正如评论中所建议的那样,我开始阅读有关 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。但是使用安全吗?我没有看到代码可能导致的任何问题,也没有看到它可能导致的任何其他问题。 如果有人告诉我为什么不应该使用此解决方案,我将非常高兴。
我也在尝试了解它是如何工作的细节。理论上,我通过 defineProperty
为 Object.prototype
定义了属性,但没有为其赋值。不知何故,它不会在 jQuery fore in
循环中导致任何错误,为什么?这是否意味着属性 _init
在某些时候或根本没有定义,因为我只定义了它的 getter?
任何帮助将不胜感激:)
最佳答案
不包括 Object.defineProperty(obj, prop, descriptor)
中的描述符JavaScript 将所有 bool 描述符属性默认为 false。即 writable
, enumerable
, 和 configurable
.您的新属性(property)对 for in
是隐藏的迭代器因为你的 _init
属性是 enumerable:false
.
我不是 JQuery 的粉丝所以不会评论关于 JQuery 的原因
向 JavaScript 的基本类型添加属性没有绝对的规则,这取决于您的代码运行的环境。添加到基本类型会将其添加到全局命名空间。如果您的应用程序与第三方脚本共享命名空间,您可能会发生冲突,导致您的代码或第三方代码或两者都失败。
如果您是唯一的代码,那么冲突将不是问题,但是添加到 object.prototype 将对所有使用对象的代码产生额外的开销。
我强烈建议您重新检查是否需要全局 _init。当然,您不会在每次需要新对象时都使用它。我是 JavaScript 数据结构的 add hock 方法的粉丝,并尽量远离正式的 OOP 范例
关于javascript - 使用 jQuery 时扩展 object.prototype 的替代方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30274543/
以下代码,我使用 chrome 浏览器控制台进行了检查: function A(){ this.a='a' } 这是一个构造函数。我已经将一个属性 b 赋给了 A 的原型(prototype)。
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 5年前关闭。 Improve this
关闭。这个问题是opinion-based .它目前不接受答案。 想改进这个问题?更新问题,以便 editing this post 提供事实和引用来回答它. 3年前关闭。 Improve this
我已经开始阅读 The Pragmatic Programmer,我很喜欢并学习堆形式,但我很难理解示踪子弹和原型(prototype)之间的区别。跟踪项目符号是否像拥有应用程序的所有 View 但尚
尽管阅读了 StackOverflow 上的大多数文章,但我现在实际上对原型(prototype)非常困惑。 function Foo() { } Foo.prototype.speak = func
我正在阅读以下代码,并开始想知道 Rectangle.prototype = Object.create(Shape.prototype) 和 Rectangle.prototype = Shape.
我想知道它们之间的区别: childObj.prototype = Object.create(parentObj.prototype) 和 childObj.prototype = parentOb
这个问题在这里已经有了答案: Why wouldn't I use Child.prototype = Parent.Prototype rather than Child.prototype =
在 node.js 中导出原型(prototype)的首选方法是什么?您可以采用两种方法: 导出原型(prototype)本身 function A () { } module.exports = A
我正在学习 JavaScript,发现了两种分配原型(prototype)的方法。 第一个是A.prototype = B.prototype,第二个是A.prototype = new B() 例如
在一些构造函数的定义之后,例如 child ,我见过以下两种形式: Child.prototype = Parent.prototype; 或 Child.prototype = new Parent
我正在阅读一本关于 OOP javascript 的书,但被其中一个示例卡住了。 在示例代码的第一个版本中,Shape 的一个新实例构造函数被创建并且 toString方法被调用。 toString方
这个问题在这里已经有了答案: What should I connect to the child prototype property in JavaScript (2 个答案) 关闭 8 年前。
在进行原型(prototype)设计时,您在多大程度上放弃了最佳实践来支持代码和修复黑客攻击?当然,代码并不打算在完整的生产环境中保留。 补充:我正在研究一个用 Python 制作的相当大的半工作原型
我正在尝试使用 Prototype 更新隐藏表单字段的值。表单域: 我正在尝试使用原型(prototype)更新值: var additionalVal = ',2'; var itemId = $
我正在阅读How to Make a Javascript Library我发现了作者所说的一个观点: function _() { //Some obects and var
我想用一个新函数扩展“Number”类型,因此我必须定义一个原型(prototype)。当我想到这一点时,我得到了一堆问题: Number 是否既继承了 Object.prototype 又继承了 F
这里好像有区别... 假设我们有 function MyConstructor() {} MyConstructor 的[[Prototype]] 是Function.prototype,不是 MyC
有人建议 Derived.prototype = Object.create(Base.prototype); 优于 Derived.prototype = new Base(); (如 this S
我是一名优秀的程序员,十分优秀!