隐藏属性到console.log或utils.inspect

我正在与sails.js waterline orm合作。 现在这不是一个特别的问题,但是我必须放置一些上下文,所以当你创build一个logging时,你会得到一个创build了数据的对象。 如果logging有关联的其他logging(集合),它具有与返回对象中的相关的键,但是这些键是getter / setter,即使这些相关对象没有数据存在。

我已经简化了一些事情来揭露主要观点。

这是我的用户模型:

var User = { attributes: status: {type:'string'} images: { collection: 'Image' } } 

让我猜,我执行一个用户模型,有一个图像集合相关的创build查询。 userRecord是查询返回的内容。 如果我console.log这个出来它显示了与模型本身相关的属性,但没有关联的logging,即使密钥实际上在那里,你可以访问它,但是不能看到console.log或utils.inspec即使设置显示隐藏到真实。

 console.log(userRecord) 

这是什么得到返回

 { name: 'zaggen'} 

这是应该返回的

 { name: 'zaggen', images: [{ path: 'some-path/img.png' }] } 

我可以像这样访问隐藏的属性:

 console.log(userRecord.images[0].path) // outputs some-path/img.png 

这怎么可能?据我所知,没有办法将信息隐藏到节点中的console.log中,除了可能在__proto__对象中定义属性,但在这种情况下它们不是。

find这个之后,我还没有发现任何东西,也很奇怪,所以我认为这可能是一个很好的问题。 这将有助于我的工作过程,如果我可以console.log这个信息,并获得所有的数据,现在我可以使用lodash和调用克隆或默认和我得到的对象,因为它应该。

据我所知,有没有办法隐藏信息到节点console.log,除了可能当在proto对象中定义的属性

这在ES5中不再是真实的。 在ES3中是这样的。

请注意,即使在原始的JavaScript中,对象和函数也具有像.__proto__.constructor.prototype这样的隐藏属性。 这就像一些本地JavaScript对象具有这些神奇的function(如如何设置innerHTML可以调用HTML编译器)。 ES5通过Object.defineproperty公开了所有的魔法。

console.log()隐藏属性的特定function是enumerable 。 在属性上设置为false会使其隐藏起来,不再需要.hasOwnProperty() ):

 var foo = {a:1} Object.defineProperty(foo,'b',{ enumerable: false, // hide it from for..in value: 2 }) console.log(foo); // prints out {a:1} console.log(foo.b); // prints out 2 

还有其他一些有用的function,比如getters和setter(允许你模仿像.innerHTML这样的属性,当你写入时调用一个函数)和writable (允许你创build一个属性为只读的)。 有关详细信息,请参阅完整文档: https : //developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

Sails使用水线,这是模型定义的地方。 如果你看看它的源代码,你会看到:

https://github.com/balderdashy/waterline/blob/77fe3a9b9a9b12110a6ba079a84e5cd43a4369db/lib/waterline/model/lib/model.js#L57-L75

 /** * Log output * @return {String} output when this model is util.inspect()ed * (usually with console.log()) */ Object.defineProperty(this, 'inspect', { enumerable: false, configurable: false, writable: false, value: function() { var output; try { output = self.toObject(); } catch (e) {} return output ? util.inspect(output) : self; } }); 

所以他们重写console.log输出到self.toObject() 。 这是他们的内部方法之一,可以为您输出的所有内容负责。 例如:

 // Don't run toJSON on records that were not populated if (!self.proto._properties || !self.proto._properties.joins) return; 

要么:

 if (!this.proto._properties.showJoins) return; 

我注意到在他们的集成testing中,他们在创build模型时将{ showJoins: true }作为第二个参数。 我在文档中找不到任何内容,但也许你可以试试?

https://github.com/balderdashy/waterline/blob/48dc007b69a133169651aeb422fa3a61c3c6802c/test/integration/model/save.js#L150