2013-08-06 23 views
13

Çoğu modern tarayıcıda (Chrome, Firefox, IE 9+, Safari, Opera) çalışması gereken bir çevrimdışı HTML5 uygulaması geliştirmeye çalışıyorum. IndexedDB, Safari (henüz) tarafından desteklenmediğinden ve WebSQL kullanımdan kaldırıldığından, kullanıcı tarafından oluşturulan JavaScript nesnelerini ve JSON.stringify()/JSON.parse() nesnelerini yerleştirmek veya çıkarmak için localStorage kullanmaya karar verdim. Ancak, JSON.stringify()'un yöntemleri ele almadığını öğrendim. İşte size basit bir yöntem ile örnek bir nesnedir: Ben (ve daha sonra localStorage koydu) bu nesneyi stringify Eğerjson.stringify nesne yöntemlerini işlemiyor

var myObject = {}; 
    myObject.foo = 'bar'; 
    myObject.someFunction = function() {/*code in this function*/} 

, orada kalacağını bütün myObject.foo değil myObject.someFunction() olduğunu.

//put object into localStorage 
    localStorage.setItem('myObject',JSON.stringify(myObject)); 

    //pull it out of localStorage and set it to myObject 
    myObject = localStorage.getItem('myObject'); 

    //undefined! 
    myObject.someFunction 

Senden emin birçok olasılıkla zaten bunu aramak istediğini bu sınırlama/özellik/biliyor değilim. Geldiğim geçici çözüm, yöntemlerle (myObject = new objectConstructor()) bir nesne oluşturmak, object özelliklerini localStorage ürününden kaldırmak ve bunları oluşturduğum yeni nesneye atamaktır. Bunun bir dolambaçlı yaklaşım olduğunu hissediyorum, ancak JavaScript dünyasında yeniyim, bu yüzden bunu çözdüm. İşte buradaki büyük sorum: Tüm nesnenin (özellikler + yöntemler) localStorage'a dahil edilmesini istiyorum. Bunu nasıl yaparım? Belki bana daha iyi bir algoritma veya belki de bilmediğim başka bir JSON yöntemini gösterebilirseniz, bunu takdir ediyorum.

+4

Fonksiyonlar JSON bulunmayan. Bakınız: http://json.org. –

+0

Spekülasyonları okuduktan sonra düşündüğüm buydu, ama yöntemleri saklayabileceğim herhangi bir yol var mı? Yoksa benim nasıl böyle yaparsın? – user2649759

+0

[JSON.stringify işlevi] 'nin olası bir kopyası (http://stackoverflow.com/questions/6754919/json-stringify-function) – Bergi

cevap

27

Javascript'teki işlevler yalnızca kodlarından daha fazlasıdır. Onlar da kapsam var. Kod dizilmiş olabilir, ancak kapsam olamaz. JSON'un desteklediği değerleri kodlayacak

. Nesneler, diziler, dizeler, sayılar ve boolelan olabilecek değerler içeren nesneler. Başka bir şey yok sayılacak veya hatalar atılacak. JSON'ta işlevler desteklenen bir varlık değildir. JSON yalnızca saf verileri işler, işlevler veri değildir, ancak daha karmaşık semantiklerle davranır. nasıl JSON.stringify() eser değiştirebilir söyledi


. İkinci argüman replacer fonksiyonudur. Yani fonksiyonların strinigification zorlayarak istediğiniz davranışı zorlayacağını:

var obj = { 
    foo: function() { 
    return "I'm a function!"; 
    } 
}; 

var json = JSON.stringify(obj, function(key, value) { 
    if (typeof value === 'function') { 
    return value.toString(); 
    } else { 
    return value; 
    } 
}); 

console.log(json); 
// {"foo":"function() { return \"I'm a function!\" }"} 

Ama sen geri okurken JSON yapar, çünkü fonksiyon dize eval ve geri nesneye sonucu ayarlamak zorunda kalacak işlevleri desteklemiyor. JSON tüm kodlama fonksiyonları


Tüm çok tüylü alabilirsiniz. Bunu yapmak istediğine emin misin? Daha iyi bir yol ...

Belki yerine ham verileri kaydetmek ve sayfada yüklenen sizin JS bir kurucusuna o geçebileceği muhtemelen yoktur. localStorage yalnızca verileri tutuyordu, ancak sayfaya yüklenen kodunuz bu veriler üzerinde çalışacak yöntemleri sağlayacaktır.

// contrived example... 

var MyClass = function(data) { 
    this.firstName = data.firstName; 
    this.lastName = data.lastName; 
} 

MyClass.prototype.getName() { 
    return this.firstName + ' ' + this.lastName; 
} 

localStorage.peopleData = [{ 
    firstName: 'Bob', 
    lastName: 'McDudeFace' 
}]; 

var peopleData = localStorage.peopleData; 

var bob = new MyClass(peopleData[0]); 
bob.getName() // 'Bob McDudeFace' 

Biz localStorage için getName() yöntemi kaydetmek gerekmez. Bu verileri yalnızca bu yöntemi sağlayacak bir kurgana beslememiz gerekiyor.

+1

Tamam, ne dediğini görüyorum. Sadece eksik olduğum bir şey olup olmadığını görmek istedim. Sadece veri depolamak ve bu verileri bir yapıcı işlevine iletmek istiyorum. Bunu temizlediğiniz için teşekkürler! – user2649759

+1

Yanıt kabul edildi. – user2649759

+0

Mükemmel cevap! Tıpkı _contrived example_ açıklığa kavuşturulmalıdır eklemek düşündüm: 'localStorage.peopleData = [{ firstName: 'Bob', lastName: 'McDudeFace' }];' olmalıdır: 'localStorage.peopleData = JSON.stringify ( [{ firstName: 'Bob', velastName: 'McDudeFace' }] ) ' Yani, localStorage'da depolanan nesnelerin _arrayinin bir JSON dizesine dönüştürülmesi gerekir. – DanDan

0

Nesnelerinizi tasvir etmek istiyorsanız, ancak işlevleri varsa, replacer ikinci parametresiyle JSON.stringify() kullanabilirsiniz. Nesneler üzerinde döngüsel bağımlılıkları önlemek için var cache = []'u kullanabilirsiniz.

Projemizde lodash kullanıyoruz. Günlükleri oluşturmak için aşağıdaki işlevi kullanırız. Nesneleri localStorage'a kaydetmek için kullanılabilir.

var stringifyObj = function(obj) { 
 
    var cache = [] 
 
    return JSON.stringify(obj, function(key, value) { 
 
    if (
 
     _.isString(value) || 
 
     _.isNumber(value) || 
 
     _.isBoolean(value) 
 
    ) { 
 
     return value 
 
    } else if (_.isError(value)) { 
 
     return value.stack || '' 
 
    } else if (_.isPlainObject(value) || _.isArray(value)) { 
 
     if (cache.indexOf(value) !== -1) { 
 
     return 
 
     } else { 
 
     // cache each item 
 
     cache.push(value) 
 
     return value 
 
     } 
 
    } 
 
    }) 
 
} 
 

 
// create a circular object 
 
var circularObject = {} 
 
circularObject.circularObject = circularObject 
 

 
// stringify an object 
 
$('body').text(
 
    stringifyObj(
 
    { 
 
     myBooblean: true, 
 
     myString: 'foo', 
 
     myNumber: 1, 
 
     myArray: [1, 2, 3], 
 
     myObject: {}, 
 
     myCircularObject: circularObject, 
 
     myFunction: function() {} 
 
    } 
 
) 
 
)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>

İlgili konular