2015-08-15 23 views
4

我正在使用sails.js waterline orm。現在這不是一個特別的問題,但是我必須放置一些上下文,所以當你創建一個記錄時,你會得到一個包含所創建數據的對象。如果記錄具有其他關聯的記錄(集合),則它具有與返回對象中的關鍵字相關的鍵,但這些鍵是getter/setter,即使這些相關對象沒有數據。隱藏屬性到console.log或utils.inspect

我簡化了幾件事情,以揭露主要觀點。

這是我的用戶模型:

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

讓assumme,我上的用戶模型,有關聯的圖像集合執行創建查詢。 userRecord是查詢返回的內容。 如果我console.log這出它顯示了與模型本身 相關的屬性,但沒有關聯的記錄,即使密鑰實際存在,您可以 訪問它,但對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__對象中定義屬性時,但在這種情況下,它們不是。

搜索後,我還沒有找到任何東西,它的很奇怪,所以我認爲這可能是一個很好的問題。它會幫助我的工作過程,如果我可以console.log這個信息並獲取所有的數據,現在我可以使用lodash並調用克隆或默認值,我得到它應該的對象。

回答

3

據我所知是沒有辦法隱藏在節點的console.log信息,也許除了當屬性在原定義對象

這在ES5中不再適用。這在ES3中是真實的。

請注意,即使在原始的javascript中,對象和函數也有隱藏的屬性,如.__proto__.constructor.prototype?這就像一些本地JavaScript對象具有這些神奇功能(如設置innerHTML可以調用HTML編譯器)。 ES5通過Object.defineproperty展示了所有的魔法。

的具體功能,隱藏屬性從console.log()enumerable。將其設置爲false的屬性使得它從for..in(無需.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 

還有一些其他有用的功能,如getter和setter(允許你模擬像.innerHTML調用一個函數時的屬性你寫信給它)和writable(允許你使屬性爲只讀)。有關詳細信息,請參閱完整文檔:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

+0

我知道將enumerable設置爲false可以將屬性從for中隱藏起來,但將其從console.log?隱藏起來,哇,這對我來說是新的,所以我只是進行了檢查,以確保它隱藏起來節點,它仍然顯示在鉻控制檯這是奇怪的,但因爲我問的node.js這個答案是正確的。 – Zagen

+0

@Zagen:console.log是非標準的。它可能在ES7中被標準化。不同的實現可能會以不同的方式實現,因此不同環境下的console.log行爲會有所不同。但是對於大多數實現來說,實現它的最明顯的方法是使用for..in。 – slebetman

4

風帆使用水線,這是定義模型的地方。如果你看一下它的源代碼,你看到這個:

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()。這是他們的internal methods之一,它可以處理您輸出的所有內容。例如:

// 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; 

我在他們的集成測試發現,他們在創建模型時通過{ showJoins: true }作爲第二個參數。我在文檔中找不到任何關於它的信息,但也許你可以嘗試一下嗎?

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

+0

確實它們似乎覆蓋了檢查時會顯示的檢查屬性,並且我在猜測self.toObject()將相關集合屬性設置爲非枚舉類型,例如@slebetman說明這些屬性如何隱藏到節點控制檯。感謝您的回答:) – Zagen

+0

你嘗試過傳遞'showJoins:true'嗎?它是否使它們在'console.log'中顯示? – Robbie

+0

沒有,讓我稍後試試,我會報告你回來:) – Zagen