Using an object from a class versus an object literal

An object literal is quick to build and does not need to have the data passed down a constructor or public members to fill an object. An object literal is an efficient way to move data around. You can read a JSON file, receive the data from an Ajax call or from many sources, and cast to the desired type:

ajax.then((response:any)=>{
return response as DataTyped;
};

However, if you have many functions or more complex logic that needs to be encapsulated, a class is more pragmatic. The reason is that using an object literal would require assigning the function on each instance manually. Also, a class can contain a private function that you may not want to expose, provide encapsulation with private/protected and interfaces. An object literal's fields are public and accessible. In the following example, we see data returned from an Ajax call. The expected type is ObjectDefinition, which has a function. The function doesn't come for free like with a class during the initialization. Hence, it must be attached to the object. In that case, we need to refer to a variable that has a function. This can be tedious with complex definitions:

interface ObjectDefinition {
m1: string;
funct1: () => void;
}

let ajax: any;
const funct1 = () => { };

ajax.then((response: any) => {
const r = response as ObjectDefinition;
r.funct1 = funct1;
return r;
});

It is possible to reduce the burden of the previous example by having a function that builds each object literal by attaching the functions. In that case, the function returns the type of the object literal. This function acts as a constructor:

function createObj(m1: string): ObjectDefinitionClass {
return {
m1: m1,
funct1: () => { }
}
}

ajax.then((response: any) => {
const r = response as Model;
return createObj(r.m1);
});

The same code with a class looks like the following code:

class ObjectDefinitionClass implements ObjectDefinition {
public m1: string;
public funct1(): void { }

constructor(param1: string) {
this.m1 = param1;
}
}

ajax.then((response: any) => {
const r = response as ObjectDefinition;
return new ObjectDefinitionClass(r.m1);
});

In that particular case, what can be interesting is to divide the fields from the functions and pass all the fields by an interface in the constructor. Here is a third version using an interface for the variables and the functions:

interface Model {
m1: string;
}

interface Funct {
funct1: () => void;
}

class ObjectDefinitionClass2 implements Model, Funct {
public m1: string;
public funct1(): void { }
constructor(param1: Model) {
this.m1 = param1.m1;
}
}

ajax.then((response: any) => {
const r = response as Model;
return new ObjectDefinitionClass2(r);
});

In terms of testability, a class has the advantage of allowing any of the members to be stubbed easily. Here is a simple example with the Jest library:

const forTesting = new ObjectDefinitionClass("1");
forTesting.funct1 = jest.fn();
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.168.214