2013-08-06 2 views
13

대부분의 최신 브라우저 (Chrome, Firefox, IE 9 이상, Safari, Opera)에서 작동해야하는 오프라인 HTML5 응용 프로그램을 개발하려고합니다. Safari에서는 IndexedDB가 지원되지 않고 WebSQL은 더 이상 사용되지 않으므로 localStorage를 사용하여 사용자 생성 JavaScript 객체 및 JSON.stringify()/JSON.parse()을 저장하여 객체를 넣거나 꺼내기로 결정했습니다. 그러나 JSON.stringify()은 메소드를 처리하지 않는다는 것을 알게되었습니다. 다음은 간단한 방법으로 예시 목적 : I는 (이후 로컬 스토리지에 넣어) 오브젝트를 캐릭터 라인 화하면json.stringify가 객체 메소드를 처리하지 않습니다.

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

이 유지되도록 모든 myObject.foo하지 myObject.someFunction()이다.

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

많은 사람들이 이미이 제한 사항/기능/원하는 것을 무엇이든 알고있을 것입니다. 해결 방법은 (myObject = new objectConstructor()) 메서드를 사용하여 개체를 만들고 localStorage에서 개체 속성을 추출한 다음 내가 만든 새 개체에 할당하는 것입니다. 이것이 둥근 방식이라고 생각합니다. 그러나 JavaScript 세계에 익숙하지 않습니다. 그래서 이것이 어떻게 해결 되었습니까. 그래서 여기에 나의 궁금한 점이 있습니다. 전체 객체 (속성 + 메소드)가 localStorage에 포함되기를 바랍니다. 어떻게해야합니까? 아마 더 나은 알고리즘을, 또는 내가 알지 못하는 또 다른 JSON 메서드를 보여줄 수 있다면, 크게 감사하겠습니다.

+4

기능 JSON에 존재하지 않습니다. 참조 : http://json.org. –

+0

그게 사양을 읽은 후에 생각한 것이지만, 그 방법을 저장할 수있는 방법이 있습니까? 아니면 내 방식대로하는거야? – user2649759

+0

[JSON.stringify function]의 가능한 복제본 (http://stackoverflow.com/questions/6754919/json-stringify-function) – Bergi

답변

27

자바 스크립트의 함수는 단순한 코드 이상입니다. 그들은 또한 범위가 있습니다. 코드는 문자열화할 수 있지만 범위를 지정할 수는 없습니다.

JSON.stringify()은 JSON에서 지원하는 값을 인코딩합니다. 객체, 배열, 문자열, 숫자 및 부울 값이 될 수있는 값을 가진 객체입니다. 다른 것은 무시되거나 오류가 발생합니다. 함수는 JSON에서 지원되는 엔티티가 아닙니다. JSON은 순수한 데이터 만 처리하고 함수는 데이터가 아니라 복잡한 의미론을 사용합니다.


그렇다면 JSON.stringify()의 동작 방식을 변경할 수 있다고 했는데요. 두 번째 인수는 replacer 함수입니다. 그래서 당신은 기능의 strinigification 강제로 원하는 동작을 강제로 수 :

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!\" }"} 

을하지만, 당신이 그것을 다시 읽을 때 당신은 JSON 는 않기 때문에, 함수 문자열을 평가 및 다시 개체에 결과를 설정해야 기능을 지원하지 않습니다.


JSON의 모든 인코딩 기능은 모두 털이 많아 질 수 있습니다. 이 작업을 수행 하시겠습니까? 아마도 더 나은 방법이있을 것입니다 ...

아마도 원시 데이터를 저장하고 페이지에로드 된 JS의 생성자로 전달할 수 있습니다. localStorage은 데이터 만 보유하지만 페이지에로드 된 코드는 해당 데이터를 조작하는 메소드를 제공합니다.

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

우리는 localStoragegetName() 방법을 저장할 필요가 없습니다. 우리는 그 메소드를 제공 할 생성자에 그 데이터를 넣기 만하면됩니다.

+1

좋아, 네가 무슨 말하는지 알 겠어. 나는 내가 잃어버린 것이 있는지보기 원했다. 결국 데이터를 저장하고 해당 데이터를 생성자 함수에 전달하게됩니다. 그 문제를 해결해 주셔서 감사합니다! – user2649759

+1

답변 됨 접수 됨. – user2649759

+0

우수 답변! 그냥 내가 _contrived example_ 명확히해야한다는 추가 거라고 생각 : 'localStorage.peopleData = [{ firstName을 '밥', 이 lastName 'McDudeFace' }]' 해야한다 : 'localStorage.peopleData = JSON.stringify ( [{ firstName을 '밥' 이 lastName 'McDudeFace' }] 가)' 즉, localStorage에 저장되는 _ 오브젝트 _은 JSON 문자열로 변환되어야합니다. – DanDan

0

개체를 문자열로 나타내지 만 함수가있는 경우 을 두 번째 매개 변수 replacer과 함께 사용할 수 있습니다. 개체에 순환 종속성을 방지하려면 var cache = []을 사용할 수 있습니다.

우리 프로젝트에서는 lodash을 사용합니다. 다음 함수를 사용하여 로그를 생성합니다. 객체를 localStorage에 저장하는 데 사용할 수 있습니다.

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>

관련 문제