3

I am playing with ES6 classes and to better manage an array property of the class, I replaced the array with an object and added all the array-related functions (get, add, remove, etc) along with an array sub-property:

class MyClass {
constructor () {
    this.date_created = new Date()
}
posts = {
    items: [],
    get: () => {
        return this.posts.items
    },
    add: (value) => this.posts.items.unshift(value),
    remove: (index) => this.posts.items.splice(index, 1)
}
}

So it got me thinking: is there a way to setup that posts object to return the items array by default? i.e. through: MyClass.posts I thought I could trick it with the get() but didn't work.

xon52
  • 696
  • 4
  • 12
  • This doesn’t look like ES6. TypeScript? Also, no. You could put properties on the array itself, but that’s bad form. – Ry- Jun 05 '18 at 01:26
  • Avoid using arrow functions in classes. They lack scope. If you define a method in a class using an arrow function, it'll have no way to reference `this`. Unless of course the function does not reference the instance in any way, but at that point, why not just turn it into a stand alone function? – Eddie D Jun 05 '18 at 01:28
  • And it is ES6. Type script requires explicit data type declarations. – Eddie D Jun 05 '18 at 01:29
  • @EddieDelRio, good point. Was just being lazy with a mock up. – xon52 Jun 05 '18 at 01:31

2 Answers2

2

If you want to keep the actual array hidden and untouchable except through the methods, it has to be declared in the constructor. Any function that alters it has to be declared in the constructor as well. If that item is to be publicly accessible, it has to be attached to this.

class Post extends Array
{
  add(val)
  {
    this.unshift(val);
  }
  remove()
  {
    this.shift();
  }
}

class MyClass 
{
  constructor() 
  {
    this.date_created = new Date()
    
    this.post = new Post();
  }
}
let x = new MyClass();
console.log(x.post);
x.post.add(2);
console.log(x.post);
Eddie D
  • 1,120
  • 7
  • 16
  • It's not so much about hiding the array, more about getting those add/remove functions out of the class's context and into the variable context... Not sure what the terms are. Instead of `MyClass.addPost` I want to know if I can have MyClass.post.add() while still being able to have a default value returned for MyClass.post I am beginning to think it's not possible, but thought I'd ask. – xon52 Jun 05 '18 at 01:48
  • So you want the same value no matter what instance of the class right? There's a way to do that. – Eddie D Jun 05 '18 at 01:49
  • sounded like static variable? https://stackoverflow.com/questions/1535631/static-variables-in-javascript – Isaac Jun 05 '18 at 01:53
  • No, not static. The array is instance dependent. – xon52 Jun 05 '18 at 01:56
  • @EddieDelRio `return this._posts` returns an empty object rather than items. Not to mention my goal of being able to have [instance].posts.add() wouldn't be achieved... – xon52 Jun 05 '18 at 02:05
  • 1
    Figured out a way to do it by extending the Array class. – Eddie D Jun 05 '18 at 02:06
  • Lemme know if that works. Kind of a hack, but it'll do the job ;D – Eddie D Jun 05 '18 at 02:08
  • @EddieDelRio great idea. I am getting an error in my code that add is not a function of posts, but as yours clearly works, I think this is answered and the issue is in my code. – xon52 Jun 05 '18 at 02:24
0

class MyClass {
  constructor() {
    this.post = [];
  }
  
  get post() {
   return [1,2,3]
  }
  
  set post(val) {
  
 }
}

let someClass = new MyClass();

console.log(someClass.post)

I believe the correct syntax is something as above. your getter and setter is pointing to post, where post is only a variable/key of MyClass, hence your getter and setter should be at MyClass level

Isaac
  • 12,042
  • 16
  • 52
  • 116
  • Thanks for your reply. I know I can do this, and I know what you replied is the normal way, but I am/was trying to put all my functions within that `post` object rather than having potentially a hundred functions for that one class (which will have about 20 similar objects to `post`). – xon52 Jun 05 '18 at 01:41