Node.js泄漏for..in循环

我正在使用一个自定义的对象处理库(对于考试,不能使用我不编程人员的东西,即JS.class),这往往会打破function的范围。

文件base.js

/** * Module internals */ function _add() { var obj_out = arguments[0]; for (var i=1; i < arguments.length; i++) { var arg = arguments[i]; for(prop in arg) { obj_out[prop] = arg[prop]; } }; return obj_out; } function _merge() { var obj_out = {}; for (var i=1; i < arguments.length; i++) { var arg = arguments[i]; for(prop in arg) { obj_out[prop] = arg[prop]; } }; return obj_out; } function _args(args) { return Array.prototype.slice.call(args, 0); } function _filterProps(items, re) { console.log("Items: ", items); var obj_out = {}; console.log("Before: ", obj_out); var keys = []; for(var key in items) { keys.push(key); } console.log("Keys: ", keys); for (var i=0; i < keys.length; i++) { var key = keys[i]; if(!re.test(key)){ obj_out[key] = items[key]; console.log("Step: ", obj_out); } } console.log("After: ", obj_out); return obj_out; } /** * Class declaration * Usage: { $extends: <classe parente> $include: [<modules>] $new: <constructeur> $static: <methodes statiques> $methods: <methodes> } */ exports.Class = function(items) { var base = !items["$extends"] ? Object.prototype : items["$extends"].prototype; var incs = !items["$include"]? [] : items["$include"]; var stat = !items["$static"] ? {} : items["$static"]; var meth = !items["$methods"] ? {} : items["$methods"]; var cons = !items["$new"] ? function(){} : items["$new"]; var left = _filterProps(items, /^\$/); var cls = function() { console.log("Constructor"); console.log(arguments); cons.apply(this, _args(arguments)); }; cls = _add(cls, stat); cls.prototype = base; for (var i=0; i < incs.length; i++) { _add(cls.prototype, incs[i]); }; _add(cls.prototype, left); _add(cls.prototype, meth); return cls; } 

文件test.js

 Base = require('./base'); var SomeClass = Base.Class({ $new: function() { console.log("new"); }, foo: function() { console.log("foo"); }, }); var OtherClass = Base.Class({ $new: function() { console.log("new"); }, bar: function() { console.log("bar"); } }); console.log("SomeClass: ", SomeClass.prototype); console.log("OtherClass: ", OtherClass.prototype); 

“node test.js”的输出

 Items: { '$new': [Function], foo: [Function] } Before: {} Keys: [ '$new', 'foo' ] Step: { foo: [Function] } After: { foo: [Function] } Items: { '$new': [Function], bar: [Function] } Before: {} Keys: [ '$new', 'bar', 'foo' ] Step: { bar: [Function] } Step: { bar: [Function], foo: [Function] } After: { bar: [Function], foo: [Function] } SomeClass: { foo: [Function], bar: [Function] } OtherClass: { foo: [Function], bar: [Function] } 

_filterProps函数倾向于在其“for..in”循环中保留一些值,我不知道为什么。 而我有点失落,因为JavaScript不是我的特长。

我的节点版本在Max OSX 10.6上是v0.5.8-pre

编辑

非常感谢Zack Bloom和他发现隐藏的bug的能力,我发现我忘了复制“Object.prototype”对象,以便引用它。

谢谢,JD

看起来你正在扩展Object.prototype,这将改变所有的对象。

 base = Object.prototype cls.prototype = base _add(cls.prototype, ...) 

即使在循环声明中,你也必须声明你使用的variables,否则他们将变成全局variables。 比如改变一下

 for(prop in arg) { obj_out[prop] = arg[prop]; } 

类似的东西

 for(var prop in arg) { obj_out[prop] = arg[prop]; } 

编辑:其实,你的问题是一个不同的,但它仍然是在你的代码中的问题。