2013-07-03 1 views
5

Sto provando a definire una funzione non numerabile toJSON su un oggetto prototipo senza molta fortuna. Spero in qualcosa di simile a ECMAScript 5 toJSON:JS funzione non enumerabile

Object.defineProperty(obj, prop, { enumerable: false }); 

Tuttavia, questo lo definisce come una proprietà che non può essere letta come un metodo.

speravo di essere in grado di definire la funzione in modo non numerabile, come avevo intenzione di definire i prototipi di tutti i tipi primitivi (String, Number, Boolean, Array e Object), in modo che io può ricorsivamente applicare la funzione attraverso oggetti complessi.

L'obiettivo finale qui è quello di poter JSONify un modello/collezione Backbone con raccolte annidate ricorsivamente.

Credo che in totale Ho due domande principali:

  1. E 'possibile definire una funzione non enumerabile su un prototipo? Se é cosi, come?
  2. C'è un modo migliore per JSONify modelli Backbone nidificati?
+0

Un metodo per definizione * è * una proprietà di un oggetto. Stai disegnando una distinzione che non esiste. Se vuoi che non sia enumerabile, allora ovviamente stai enumerando le proprietà di un oggetto. –

+0

Sì, tuttavia mi piacerebbe che fosse una proprietà non enumerabile, nello stesso modo in cui Object.defineProperty non è enumerabile. cioè, non viene iterato quando si usa 'for (x in obj)' –

+0

Right. Ancora una volta, un metodo è una proprietà di un oggetto che fa riferimento a una funzione. Il codice che hai è quello che useresti per rendere la proprietà non enumerabile. –

risposta

13

Non capisco, perché non è possibile accedervi come metodo?

var foo = {}; 

Object.defineProperty(foo, 'bar', { 
    enumerable: false, 
    value: function() {console.log('foo.bar\'d!');} 
}); 

foo.bar(); // foo.bar'd! 

Se si voleva che sul prototipo, è facile come

Object.defineProperty(foo.prototype, /* etc */); 

o anche direttamente in Object.create

foo.prototype = Object.create(null, { 
    'bar': {value: function() {/* ... */}} 
}); 

Tuttavia, a meno che non si sta creando istanze di foo, si non sarà mostrare se si tenta di foo.bar e solo essere visibile come foo.prototype.bar.

Se foo ha il proprio prototipo (ad esempio foo = Object.create({})), si può ottenere con Object.getPrototypeOf, aggiungere la proprietà a questo e poi foo.bar potrebbe funzionare anche se non è un caso.

var proto = Object.getPrototypeOf(foo); // get prototype 
Object.defineProperty(proto, /* etc */); 

È possibile vedere visibility of enumerable vs non-enumerable properties here.

+0

Fantastico, grazie!Il problema era che stavo usando 'get' invece di' value', che non ero in grado di accedere come funzione. –

+0

_get_ richiama _function_ senza passare alcun argomento, quindi fa finta che la proprietà sia uguale al 'return' della funzione, quindi si stava facendo' SJON() (args) 'quando si voleva fare' SJON (args) ' –

+0

Okay . Un'ultima domanda se non ti dispiace; questo approccio causerà alcuni degli stessi problemi dell'estensione del prototipo Object con una funzione enumerabile? –

1

Paul S. ha ragione circa la necessità di impostare la definizione di proprietà della value invece di una get, ma volevo aggiungere che non è necessario passare enumerable: false, perché falsa è l'impostazione predefinita per tale opzione in Object.defineProperty() La risposta può essere semplificato a:

var foo = {};  

Object.defineProperty(foo, 'bar', { 
    value: function(){ console.log('calling bar!'); } 
}); 

foo.bar(); 
+0

Grazie, l'ho incluso solo esplicitamente per chiarirlo nella domanda, ma è una buona nota che non è effettivamente necessario. –