Javascript object syntax that I can't recognize - javascript

I have this code snipet:
proxy('http://my-custom-api-endpoint.com', {
proxyReqOptDecorator(options) {
options.headers['x-forwarded-host'] = 'localhost:3000'
return options
}
})
It is a call to a function named proxy, the first argument is a string, but the second argument has a syntax than I can't recognize:
{
functionName(args) {
// statements
}
}
Can someone explain that syntax please?

Its a shorthand method in Object Initializer to create a property whose value is a function.
// Shorthand method names (ES2015)
let o = {
property(parameters) {}
}
//Before
let o = {
property: function(parameters) {}
}
This syntax is also sued in classes to declare class methods.
class Animal {
speak() {
return this;
}
static eat() {
return this;
}
}class Animal {
speak() {
return this;
}
eat() {
return this;
}
}

Related

Composition Pattern in Javascript with Classes but without Mixins?

Is the following a valid strategy for implementing the composition pattern in Javascript? I want to use classes instead of constructor functions or plain objects, and I know that Mixins are not best practice. One concern is that in this approach, the methods added to Person objects are not attached to the prototype and therefore each require memory allocation. Thanks!
class Person {
name;
constructor(name) {
this.name = name;
}
}
function fly() {
return {
fly() {
console.log(`${this.name} can fly!`);
},
};
}
function swim() {
return {
swim() {
console.log(`${this.name} can swim!`);
},
};
}
function makeFlyingPerson(name) {
return Object.assign(new Person(name), fly());
}
function makeSwimmingPerson(name) {
return Object.assign(new Person(name), swim());
}
...the methods added to Person objects are not attached to the prototype and therefore each require memory allocation
True, but it's a trivial amount, the cost of one property per method per object (to hold the function reference for the method). Properties aren't nothing, but they aren't large. For the avoidance of doubt: The function object is reused by all instances, not copied.
There's no reason for fly and swim to be functions, though (at least, none that's apparent from the question), just use the objects directly:
class Person {
name;
constructor(name) {
this.name = name;
}
}
const flyMethods = {
fly() {
console.log(`${this.name} can fly!`);
},
};
const swimMethods = {
swim() {
console.log(`${this.name} can swim!`);
},
};
function makeFlyingPerson(name) {
return Object.assign(new Person(name), flyMethods);
}
function makeSwimmingPerson(name) {
return Object.assign(new Person(name), swimMethods);
}
Note that this is still using mixins, though (both your original and the above).
Unless you're going to reuse fly/flyMethods and swim/swimMethods with other classes than Person, though, using extends would seem simpler and would give you prototypical method reuse:
class FlyingPerson extends Person {
fly() {
// ...
}
}
If you are reusing fly/flyMethods, etc., with multiple classes, another option is to have factory-building functions that create a prototype from the various sets of methods and then reuse it:
class Person {
name;
constructor(name) {
this.name = name;
}
}
const flyMethods = {
fly() {
console.log(`${this.name} can fly!`);
},
};
const swimMethods = {
swim() {
console.log(`${this.name} can swim!`);
},
};
function extendWith(cls, name, ...mixins) {
// We use the wrapper object so that the class constructor's name is assigned from `name`
const obj = {
[name]: class extends cls {
}
};
Object.assign(obj[name].prototype, ...mixins);
return obj[name];
}
const FlyingPerson = extendWith(Person, "FlyingPerson", flyMethods);
const SwimmingPerson = extendWith(Person, "SwimmingPerson", swimMethods);
const FlyingSwimmingPerson = extendWith(Person, "FlyingSwimmingPerson", flyMethods, swimMethods);
const joe = new FlyingSwimmingPerson("Joe");
joe.fly();
joe.swim();
class Animal {
name;
type;
constructor(name, type) {
this.name = name;
this.type = type;
}
}
const FlyingSwimmingAnimal = extendWith(Animal, "FlyingSwimmingAnimal", flyMethods, swimMethods);
console.log(FlyingSwimmingAnimal.name); // FlyingSwimmingAnimal
const splippery = new FlyingSwimmingAnimal("Slippery");
splippery.fly();
splippery.swim();

How to call class this in object?

I have a class testClass and in testClass there is a getter called testGetter and a public object called testObject. In testObject I have a function nestedFunction which attempts to call testGetter but cannot as the scope for this is in the testObject. How could I call the getter (or any function) from the object?
class testClass {
get testGetter() {
return "test"
}
testObject = {
nestedFunction : function(){
console.log(this)
return this.testGetter
}
}
constructor()
{
console.log(this.testObject.nestedFunction())
}
}
new testClass()
Output:
{ nestedFunction: [Function: nestedFunction] }
undefined
Classic use case of arrow functions.
class testClass {
get testGetter() {
return "test"
}
testObject = {
nestedFunction: () => {
console.log(this)
return this.testGetter
}
}
constructor() {
console.log(this.testObject.nestedFunction())
}
}
new testClass()

Typescript property decorator - Need help to understand how the following happens?

I was just experimenting with Typescript property decorators. But, I could not understand the behavior of the following code :
function dec(hasRole: boolean) {
return function (target: any, propertyName: string) {
let val = target[propertyName];
Object.defineProperty(target, propertyName, {
get() { return val; },
set(value) { val = hasRole; }
});
}
}
class Hey {
age: number;
#dec(true)
hasRole: boolean = false;
constructor(age: number) {
this.age = age;
}
}
let ob = new Hey(22);
console.log(ob);
//Actual Output:
age: 22
hasRole: true
__proto__:
constructor: class Hey
hasRole: true
get hasRole: ƒ get()
set hasRole: ƒ set(value)
__proto__: Object
The result I expected was:
1. OwnProperty -> hasRole = false
2. Prototype property -> hasRole = true.
As 'target' in decorator argument provides the constructor function for static members or prototype of the class for instance members.
Could someone explain me this functionality ?
In order to understand it clearly you should take a look at the transpiled version
function dec(hasRole) {
return function (target, propertyName) {
let val = target[propertyName];
Object.defineProperty(target, propertyName, {
get() { return val; },
set(value) { val = hasRole; }
});
};
}
class Hey {
constructor(age) {
this.hasRole = false;
this.age = age;
}
}
__decorate([
dec(true)
], Hey.prototype, "hasRole", void 0);
let ob = new Hey(22);
console.log(ob);
From the code above it should be clear that class is decorated first and only then a new instance is created
It means that at the time constructor is being executed hasRole is already defined in Prototype hence assigning this.hasRole to anything doesn't have any effect: it's always assigned to hasRole parameter in decorator(which is true)

how to create methods in methods in es6 class

Good day,
I dont know if am can explain this well for you to help but i will like to use a an ES6 class to create an object that can be called like this.
var = varaibles
obj = objects
obj.var
obj.var.method
obj.var.var.method
obj.method.var
and so on.
I can only do one step
obj.var && obj.method
i will kind appreciate if one can help me here thanks
this is what i have done
class Table extends someClass {
constructor() {
super();
this.column = {
sort: () => {
console.log("firing");
},
resize: () => {
console.log("firing");
}
};
this.cells = {
edit: () => {
console.log("firing");
}
};
}
myMethods() {
//BLAH
}
}
From what I understood, here is my solution.
If I return a object full of methods, I can use that object as I like.
class someClass {
// this is a parent method
Parent() {
console.log(`From a Parent`)
}
// a getter that returns an object
get parentWithChild() {
return {
child() {
console.log(`From a Child`)
}
}
}
// a function that returns an object
Methods() {
return {
child() {
console.log(`From a Child`)
}
}
}
}
const cool = new someClass();
cool.Parent(); // From a Parent
cool.parentWithChild.child(); // From a Child
cool.Methods().child(); // From a Child
You can use similar pattern on the extended class too.

How to prevent function overriding in es6?

Here is my way I usually use to prevent to override name property.
let _name = Symbol('name');
class Cat {
constructor(name) {
this[_name] = name;
}
set name(newName) {
return this[_name];
}
get name() {
return this[_name];
}
}
// default name
let cat = new Cat('Hermione');
// new name
cat.name = 'Voldermort';
// testing
console.log(cat.name);
My idea: Saving the value of name property to another variable.
But if I have multiple class properties, like this:
that would be wasting to create a lot of variables for saving.
let _Min = Symbol('Min'), _Max = Symbol('Max'); // and so on
Is there another way to achieve this goal? Thank you!
In order to be read-only, the property should have no set accessor:
class Foo {
get bar() {
return 'bar';
}
}
If the property is supposed to be defined on construction, the descriptor can be defined too:
class Cat {
constructor(name) {
Object.defineProperty(this, name, {
get: () => name,
configurable: true
});
}
}
Or
class Cat {
constructor(name) {
Object.defineProperty(this, name, {
value: name,
writable: false,
configurable: true
});
}
}
Try following examples, which may solve your problem
Example 1:
class A {
a = () => {
console.log('A#a');
}
}
class B extends A {
// this will throw error as
// Class 'A' defines instance member property 'a', but extended class 'B'
// defines it as instance member function.
a() {
console.log('B#a')
}
}
new B().a()
/**
Error: Class 'A' defines instance member property 'a', but extended class 'B'
defines it as instance member function.
*/
Example 2:
class Renderer {
constructor(args) {
Object.defineProperty(this, 'render', {
writable: false,
configurable: true,
value: () {
return this.childRender();
}
});
}
childRender() {
throw Error('render() is already instance of Renderer. Did you mean? childRender()');
}
// do not define methodName() here
}
class Draw extends Renderer {
render() {
console.log('DrawB#render');
}
}
new Draw().render()
/**
VM1597:13 Uncaught Error: render() is already instance of Renderer. Did you mean? childRender()
at Drawee.childRender (<anonymous>:13:11)
at Drawee.value (<anonymous>:7:22)
at <anonymous>:25:14
*/
I hope this helps 🙂

Categories

Resources