How to store a complex object javascript - javascript

I have a complex object of this type:
class Person {
constructor(name, age, country) {
this.name = name;
this.age = age;
this.country = country;
}
setName(name) {
if (name !== null) this.name = name;
}
setAge(age) {
if (age !== null) this.age = age;
}
setCountry(country) {
if (country !== null) this.country = country;
}
getName() {
return this.name;
}
// ...
}
let person = new Person('Paul', 27, 'Haïti'); // needs to save this Object
console.log(person);
So I would like to know if anyone has an idea on how I can store this Object so that I can access it the next time I open the browser. localStorage doesn't work.

localStorage does work - you just need to use it properly
I added a toJSON method on the class - this returns an array with the constructor parameter values in the right order
class Person {
constructor(name, age, country) {
this.name = name;
this.age = age;
this.country = country;
}
toJSON() {
return [this.name, this.age, this.country];
}
setName(name) {
if (name !== null) this.name = name;
}
setAge(age) {
if (age !== null) this.age = age;
}
setCountry(country) {
if (country !== null) this.country = country;
}
getName() {
return this.name;
}
}
To save
const person = new Person("John", 23, "Aussie");
localStorage.setItem('test', JSON.stringify(person));
To load
const revivedPerson = new Person(...JSON.parse(localStorage.getItem('test')));
You don't have to make the toJSON method, but it makes for simple code (if you never need to JSON.stringify an instance of Person)

I'd add a static method to the class, that can take a plain object and return an instance of the class in return. You can use Object.create and Object.assign for that.
Demo:
class Person {
constructor(name, age, country) {
this.name = name;
this.age = age;
this.country = country;
}
static from(obj) {
return Object.assign(Object.create(this.prototype), obj);
}
getName() {
return this.name;
}
// ...
}
// Demo
let person = new Person('Paul', 27, 'Haïti');
let serialised = JSON.stringify(person);
// ... write/read serialised to/from localStorage ...
// and then:
let person2 = Person.from(JSON.parse(serialised));
console.log(person2.getName());

Related

Create dynamic prototype like jquery function chain

I try to create a dynamic prototype like jQuery and able to function chain, but I got error without use new and inside of function, return this object correct?
(function() {
var peopleDynamicProto = function(name, age, state) {
this.name = name;
this.age = age;
this.state = state;
if (typeof this.printPerson !== 'function') {
peopleDynamicProto.prototype.printPerson = function() {
console.log(this.name + ',' + this.age + ',' + this.state);
return this;
};
}
if (!this.hasOwnProperty('gender')) {
peopleDynamicProto.prototype.gender = 'male';
return this;
}
}
window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();
//var person1 = new peopleDynamicProto('john', 23,'CA');
//person1.printPerson();
peopleDynamicProto('john', 23, 'CA').printPerson(); //got error
Anyone know where is the problem?
You have to use "new" if you want to create a new object based off a prototype.
I am not sure what you are trying to do exactly, and why you are trying to create the prototype dynamically. I'm not going to say 100% sure, but I don't think jQuery does that (plus it looks like a very bad practice).
If you're trying to do something like jQuery, where your class is chainable and can be chained as (new peopleDynamicProto(...)).print() or peopleDynamicProto(...).print(), then you can do something like this:
function peopleDynamicProto(name) {
if (this instanceof peopleDynamicProto) {
/* initialize attributes here */
this.name = name;
} else {
return new peopleDynamicProto(name);
}
}
peopleDynamicProto.prototype.printPerson = function() {
console.log( this.name );
return this;
}
Now you should be able call it in both ways:
peopleDynamicProto('john').printPerson();
(new peopleDynamicProto('john')).printPerson();
If you don't care about supporting both ways, then you can just return an object, e.g.:
function peopleDynamicProto(name) {
return {
name: name,
printPerson = function() {
console.log( this.name );
return this;
}
};
}
peopleDynamicProto('John').printPerson();
(There are other ways of doing that)
I think the reason why you are getting such an error is because what you are returning here is a function not an object but you are trying to access a property of an object.
For eg,
If you write as:
**
var myFun = function(){
this.message = "TEST";
}
**
you cannot access myFUN.message because here myFun is a function not an object of this function constructor.
To access its property, you need to do something like
(new myFun()).message;
Similarly in you case what you return is "peopleDynamicProto" which is a function only, not an object of this function constructor.
To access method printPerson (which is a member), you need to create an instance of peopleDynamicProto and access its member
I guess you missed the new operator- see this for reference
The new operator creates an instance of a user-defined object type or
of one of the built-in object types that has a constructor function.
See demo below:
(function() {
var peopleDynamicProto = function(name, age, state) {
this.name = name;
this.age = age;
this.state = state;
if (typeof this.printPerson !== 'function') {
peopleDynamicProto.prototype.printPerson = function() {
console.log(this.name + ',' + this.age + ',' + this.state);
return this;
};
}
if (!this.hasOwnProperty('gender')) {
peopleDynamicProto.prototype.gender = 'male';
return this;
}
}
window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();
var person1 = new peopleDynamicProto('john', 23,'CA');
person1.printPerson();
new peopleDynamicProto('john', 23, 'CA').printPerson(); //got error
you cant create prototype inside contructor. see this explanation
defining-prototype-methods-inside-the-constructor
use this keyword instead of prototype:
(function(){
var peopleDynamicProto = function(name, age, state){
this.name = name;
this.age = age;
this.state = state;
this.printPerson = function(){
console.log( this.name + ',' + this.age + ',' + this.state );
return this;
}
if( !this.hasOwnProperty('gender') ){
peopleDynamicProto.prototype.gender = 'male';
return this;
}
}
window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();
peopleDynamicProto('john', 23,'CA').printPerson();
or use prototype outside constructor(this is better since function object not recreated each time object created)
(function(){
var peopleDynamicProto = function(name, age, state){
this.name = name;
this.age = age;
this.state = state;
if( !this.hasOwnProperty('gender') ){
peopleDynamicProto.prototype.gender = 'male';
return this;
}
}
if( typeof this.printPerson !== 'function' ){
peopleDynamicProto.prototype.printPerson = function(){
console.log( this.name + ',' + this.age + ',' + this.state );
return this;
};
}
window.peopleDynamicProto = peopleDynamicProto;
return peopleDynamicProto;
})();

Why isn't this anonymous function returning?

I know this is complete purposeless code I'm just experimenting with anonymous functions with code I have already written and had at hand. I can't figure out though why it array isn't returning?
(function() {
function Employee(name, age, pay) {
this.name = name;
this.age = age;
this.pay = pay || 800;
}
function Manager(name, age, pay) {
Employee.call(this, name, age, pay);
this.reports = [];
}
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.addReport = function(report) {
this.reports.push(report);
}
function Cashier(name, age, pay) {
Employee.call(this, name, age, pay);
}
Cashier.prototype = Object.create(Employee.prototype);
var ary = [Cashier, Manager];
return ary;
}());
...why it array isn't returning?
It is. You're just not doing anything with that return value; see *** comment on first line:
var result = (function() { // ****
function Employee(name, age, pay) {
this.name = name;
this.age = age;
this.pay = pay || 800;
}
function Manager(name, age, pay) {
Employee.call(this, name, age, pay);
this.reports = [];
}
Manager.prototype = Object.create(Employee.prototype);
Manager.prototype.addReport = function(report) {
this.reports.push(report);
}
function Cashier(name, age, pay) {
Employee.call(this, name, age, pay);
}
Cashier.prototype = Object.create(Employee.prototype);
var ary = [Cashier, Manager];
return ary;
}());
console.log(result);
Actually, this code is returning two constructor function objects. Try running it on your console :-

Creating a Class Method

function Person(firstName = "John", lastName = 'Doe', age = 0, gender = 'Male') {
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.gender = gender;
this.sayFullName = function() {
return this.firstName + " " + this.lastName
};
}
Person.prototype.greetExtraTerrestrials = function(raceName) {
return `Welcome to Planet Earth ${raceName}`;
};
What is wrong with this code? Doesn't it create a class method called greetExtraTerrestrials?
Don't place that function on prototype, place that on Class itself like
Person.greetExtraTerrestrials = function(raceName) {
return `Welcome to Planet Earth ${raceName}`;
};
and call it like
Person.greetExtraTerrestrials('ABC');
You can do both! The difference in
class Person(...) {
...
}
Person.myFunction = function(val) { // This is a public function
return val;
}
Person.prototype.myFunction = function(val) { // This is a private function
return val;
}
is how you access it.
Access the public function :
var r = Person.myFunction("Hello!");
console.log(r);
Access the private function:
var person1 = new Person(...);
var r = person1.myFunction("Hello!");
console.log(r);
See also this question.
Actually it works, but firstly you need to create an instance of Person to be able call its methods. For example:
var john = new Person("John");
console.log(john.greetExtraTerrestrials("predator"));

JavaScript OOP: Uncaught TypeError: is not a function

Have trouble with object creation. Console says that something wrong in the last line. Please tell how it should be, I more familar with Java, so this is little bit confusing for me.
var dog = {
name:"Dog",
age:"11",
getName : function() {
alert(this.name);
}
}
function Dog(name, age) {
this.name = name;
this.age = age;
}
var d1 = new Dog("Rex", 8);
d1.getName();
Your dog is just a simple Object literal,
that means that your getName is bound to it, not to your Dog class.
You can make that function a method of Dog instead:
/*var dog = {
name:"Dog",
age:"11",
getName : function() {
alert(this.name);
}
}*/
function Dog(name, age) {
this.name = name;
this.age = age;
}
Dog.prototype.getName = function() {
console.log( this.name );
}
var d1 = new Dog("Rex", 8);
d1.getName(); // "Rex"
Here's a variant that uses your settings "defaults"
function Dog() {
this.name = "Dog"; // Default name
this.age = 11; // Default age
}
Dog.prototype.getName = function() {
console.log( this.name );
}
var d1 = new Dog();
d1.name = "Rex"; // Override default name
d1.getName(); // "Rex"
You can use class with syntaxic sugar to properly create objects in ES6.
In your exemple that would write like this :
'use strict';
class Dog{
constructor(name, age){
this.name = name;
this.age = age;
}
getName(){
console.log(this.name);
}
}
let doggy = new Dog("krypto", 125);
doggy.getName();
Traditional OO in JavaScript
function Dog(name, age) {
this.name = name || "Dog";// if the name is not given, it defaults to "Dog"
this.age = age || "11";
}
Dog.prototype.getName = function() {
alert(this.name);
}
var d1 = new Dog("Rex", 8);
d1.getName();
More Explicit OO in JavaScript
function createDog(name, age) {
// create a new dog and return it
var dog = {
name: name || "Dog",// if the name is not given, it defaults to "Dog"
age: age || "11"
};
return dog;
}
createDog.getName = function(dog) {
// explicit dog as 1st parameter
alert(dog.name);
}
//createDog is a normal function that returns something, no "new" needed
var d1 = createDog("Rex", 8);
createDog.getName(d1);

How to put functionality into abstract function in JavaScript

I am trying to make it so that I can have some methods in a JavaScript object be inheritable by a child class, but I don't want to allow the parent class to be instantiated. Here is some code that I wrote to illustrate this:
/**
* Shows how basic abstraction works with JavaScript
*/
//Define the person object with a first name, last name, and an age
function Person(firstName, lastName, age) {
//Make it so that this object cannot be instantiated by identifying its constructor
if(this.constructor === Person) {
throw new Error("Can't instantiate an abstract class of type Person!");
}
//Assign instance variables
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
//Create simple get methods
this.getName = function(){
return this.firstName + " " + this.lastName;
}
this.getFirstName = function() {
return this.firstName;
}
this.getLastName = function() {
return this.lastName;
}
this.getAge = function() {
return this.age;
}
}
//Define the student constructor
function Student(firstName, lastName, age, subject) {
//Assign the instance variables including the new subject variable
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.subject = subject;
//Add a new function to get the subject from Student
this.getSubject = function() {
return this.subject;
}
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
//Testing the inheritance
var joe = new Student("Joe", "Shmo", 33, "Computer Science");
console.log("First Name: " + joe.getFirstName()); //The getFirstName() function is defined in the superclass
console.log("Subject: " + joe.getSubject()); //The getSubject() function is defined in the subclass
With this code I get an error when trying to call getFirstName on the Student object joe. It seems that it would be very useful to have getFirstName be inheritable by the subclass.
I really want to be able to define the getName function in the parent class so that I can then just have that functionality inherited by the subclasses such as Student. Is there any way to do that? I would really appreciate any help!
You need to define your methods in the Person prototype, not in an instance of Person. That way they will be copied when you do Object.create(Person.prototype):
/**
* Shows how basic abstraction works with JavaScript
*/
//Define the person object with a first name, last name, and an age
function Person(firstName, lastName, age) {
//Make it so that this object cannot be instantiated by identifying its constructor
if(this.constructor === Person) {
throw new Error("Can't instantiate an abstract class of type Person!");
}
//Assign instance variables
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
}
Person.prototype.getName = function(){
return this.firstName + " " + this.lastName;
}
Person.prototype.getFirstName = function() {
return this.firstName;
}
Person.prototype.getLastName = function() {
return this.lastName;
}
Person.prototype.getAge = function() {
return this.age;
}
//Define the student constructor
function Student(firstName, lastName, age, subject) {
//Assign the instance variables including the new subject variable
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.subject = subject;
//Add a new function to get the subject from Student
this.getSubject = function() {
return this.subject;
}
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
//Testing the inheritance
var joe = new Student("Joe", "Shmo", 33, "Computer Science");
console.log("First Name: " + joe.getFirstName()); //The getFirstName() function is defined in the superclass
console.log("Subject: " + joe.getSubject()); //The getSubject() function is defined in the subclass

Categories

Resources