Объект Javascript, узел и нефрит [дубликат]

class A 
{ 
    int x; 
};  

class B 
{ 
    B( ) : x(1), c('a') { } 
    int x; 
    char c; 
};  

int main( ) 
{ 
    A a; 
    B b; 
    a = b;     // b.c == 'a' is "sliced" off
    return 0; 
}
16
задан user2649759 6 August 2013 в 20:40
поделиться

2 ответа

Функции в javascript - это больше, чем просто их код. У них также есть возможности. Код может быть сжат, но область не может.

JSON.stringify() будет кодировать значения, поддерживаемые JSON. Объекты со значениями, которые могут быть объектами, массивами, строками, числами и булевыми. Все остальное будет игнорироваться или бросать ошибки. Функции не поддерживаются в JSON. JSON обрабатывает только чистые данные, функции - это не данные, а поведение с более сложной семантикой.


Это говорит о том, что вы можете изменить способ работы JSON.stringify(). Второй аргумент - функция replacer. Таким образом, вы можете заставить поведение, которое вы хотите, заставляя стригификацию функций:

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'

Нам не нужно сохранять метод getName() для localStorage. Нам просто нужно передать эти данные в конструктор, который предоставит этот метод.

30
ответ дан Alex Wayne 20 August 2018 в 18:18
поделиться
  • 1
    Хорошо, я понимаю, о чем вы говорите. Я просто хотел посмотреть, нет ли чего-то, чего я не видел. Я закончу просто хранение данных и передачу этих данных функции-конструктора. Спасибо, что поняли! – user2649759 6 August 2013 в 21:32
  • 2
    Ответ принят. – user2649759 6 August 2013 в 22:05
  • 3
    Отличный ответ! Просто подумал, что добавлю, что надуманный пример должен быть уточнен: localStorage.peopleData = [{ firstName: 'Bob', lastName: 'McDudeFace' }]; должен быть: localStorage.peopleData = JSON.stringify( [{ firstName: 'Bob', lastName: 'McDudeFace' }] ); То есть, массив объектов , хранящихся в localStorage, должен преобразуется в строку JSON. – DanDan 6 November 2013 в 04:05
  • 4
    Тогда, конечно, должен быть JSON разобран на пути назад ... – DanDan 6 November 2013 в 04:14
  • 5
    Когда я пытаюсь разобрать JSON, у меня есть эта ошибка: myMethod не является функцией; Зачем? – SphynxTech 3 November 2017 в 08:35

Если вы хотите укрепить свои объекты, но у них есть функции, вы можете использовать JSON.stringify() со вторым параметром 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>

0
ответ дан Miguel del Mazo 20 August 2018 в 18:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: