I have been looking for an answer on here but i couldn't find any, but anyway my question is how to get an array in a method that has been declared and initialised in an other method but in the same class. I'll make it a bit more clear by demonstrating what i want to achieve and what i have tried so far.
Javascript:
class SomeClass {
method1() {
var array = new array();
//its actually a 2d array and it is being initialised here but for simplicity this isn't
//necessary in the example.
}
method2() {
// --> Here i want to access the array and it's contents.
//I have tried this:
this.array;
//and
array;
}
}
but i got "cannot ready property of undefined" when i tried this.array;
You have to declare the array as an element of the Class, not inside a method, for that, you can use a constructor.
In this link you can see more information.
Here is an example:
class SomeClass {
constructor(someValue) {
// Initialize array or any other atribute
this.arr = new Array(someValue);
}
method1() {
console.log(this.arr);
}
method2() {
console.log(this.arr);
}
}
var instance = new SomeClass('data');
instance.method1();
instance.method2();
The array which is declared in method1 will only be available in that function. There is no way to access local variables of a function in some other function.
The solution could be to use the array as property of instance of class
class SomeClass {
constructor(){
this.array = []
}
method1() {
console.log(this.array);
}
method2() {
console.log(this.array)
}
}
const obj = new SomeClass();
obj.method1();
obj.method2();
Okay so you are making a major mistake, Your concepts of OOP are at stake.
To access array as a property/ instance of a class , You need to declare a constructor it within the class. Somewhat like this
class SomeClass {
constructor(){
this.array = new Array();
}
yourMethod1(){
console.log(this.array); /// You cann access it here and manipulate
}
yourMethod2(){
console.log(this.array); // You can accesss here too and do the same
}
}
Later on you can create an instance of your class like this and access the methods and do whatsoever
let a = new SomeClass();
a.yourMethod1();
a.yourMethod2();
Related
Let's say I have a Class with a method like:
class MyClass {
importantMethod() {
... //any code here
}
}
And let's say I have 10/20/more instances of the Class like:
const inst1 = new MyClass();
const inst2 = new MyClass();
const inst3 = new MyClass();
.... //and more instances here
Is there a way to execute importantMethod() on each instance in a more elegant way than:
inst1.importantMethod()
inst2.importantMethod()
inst3.importantMethod()
.... //and for all the instances
Use forEach
[inst1 , inst2 , inst3].forEach( (item)=> item.importantMethod() )
I assume you want to be able to run a function (at any time, and possibly many times) on all instances of a class that happen to exist at any given moment. YOu could do this by simulating a "private static" list of instances of the class. Each instance gets added to the list on the class's constructor call, and you can supply a function that will iterate over this list:
let MyClass;
{
// this is only visible to functions inside the block
let myClassInstances = [];
MyClass = class {
constructor() {
myClassInstances.push(this);
}
importantMethod() {
console.log(this);
}
}
MyClass.runImportantMethodOnAll = function() {
myClassInstances.forEach(inst=>inst.importantMethod());
}
};
You could use this like:
let x = new MyClass();
let y = new MyClass();
MyClass.runImportantMethodOnAll();
There is no need to attach the runImportantMethodOnAll to MyClass, either. You could store it anywhere.
I think that you have 2 options:
If this can be run on initialization and throws no errors etc and is safe you can run it in the constructor and thus every time there is a new instance it will call it... Not the best practice but possible....
Do something like
const instances = [];
for (let i=0; i<20; i++) {
const classInstance = new MyClass();
classInstance.ImportantFunction();
instance.push(classInstance);
}
This is also sort of a hack but it might make the code a bit cleaner if you have a lot of instances...
If you care about naming the instance then you can change the array in example above to an object and actually put every instance with a named key in the object and then it would be easier to access the instances.
That's from my knowledge at least, I'm not familiar with any "hooks" on class instantiation unfortunately.
Not sure if my question is worded properly. But basically I have a class, but I want to write a new method for it. Say my class looks like this:
class MyClass {
constructor () {
this.someProperty = []
this.someMethod = this.someMethod.bind(this)
}
function someMethod () {
// do something
}
}
Now, because I don't have direct access to this class, I am going to create a new method using prototype
MyClass.prototype.myNewMethod = function (params) {
// do something else
// how to access someProperty? And to the bind to MyClass?
}
But now say I want to access someProperty and also want to do the bind on this new method. How can I do that?
As a matter of fact is my method creation even correct to begin with? Anyway, what I want is for it to have the same access to the this inside the class. How can I do this?
I didn't understand what you want to do but so you can access it:
class MyClass {
constructor () {
this.someProperty = [];
}
someMethod = function() {
console.log(this.someProperty);
}
}
var cc = new MyClass();
cc.someMethod();
I'm building an angular application and I have a class that I'm defining within another ts file. I'm trying to get a property that is defined by the constructor but I'm within an object that is in another object. Normally I would use the "this" keyword but it is referring to the object I am in and not the parent class.
here is the use of the class:
var devList = new DateList(dates)
here is a simplified version of the DateList class:
export class DateList {
date
constructor(input){
this.date = input
}
devs = {
bluegreen: {
dates: this.date.bluegreen //<-----------I believe "this" in this
// case refers to bluegreen,
// how do I get it to refer
// to this instance of the
// DateList class?
}
}
}
EDIT
I'm a beginner to programing so I don't understand what a function has to do with an object, inside of another object. can anyone explain how to fix the issue, and how the issue applies to functions?
Setting class attributes happens before the constructor, so this.date is undefined when you are declaring the class attribute 'devs'. Move setting 'devs' inside the constructor and it will work:
export class DateList {
private date: any;
public devs: Object;
constructor(input: Object){
this.date = input
this.devs = {
bluegreen: {
dates: this.date.bluegreen
}
}
}
}
let dateList: DateList = new DateList({
bluegreen: 'bluegreen_val'
});
console.log(dateList.devs);
I'm creating methods inside a constructor, to work with private values - this seems to be the suggested pattern to create private properties and limit the access to them.
Now I inherit from that class and within the constructor of the derived class I create another method, trying to access that. Unfortunately I get an exception TypeError: ... is not a function.
What to do? I can use the constructor as exactly that and just create a new object, but that would not be related to its classes and copying all the properties of the class and the super class etc. seems quite annoying and not like the right way. So again, what to do?
Here is an example:
class ClassA {
constructor() {
this.getValue = () => "private value";
}
}
class ClassB extends ClassA {
constructor() {
super();
this.getValue = () => `${super.getValue()}, second private value`;
}
}
const a = new ClassA();
const b = new ClassB();
console.log(`a.getValue = ${a.getValue()}`);
console.log(`b.getValue = ${b.getValue()}`);
Fiddle Check the console. The outcome I'd expect is "private value, second private value".
If someone can give me a hint, or a not super shitty workaround, I'd appreciate that.
Thanks, fea
super refers to the classes prototype. As your methods are not prototype methods but instance methods, it will unfortunately not work. However you could store the original function reference in a variable:
const orig = this.getValue.bind(this);
this.getValue = () => `${orig()}, second private value`;
However i personally rather like the _ pattern:
class ClassA {
constructor() {
this._private = "test";
}
getValue(){ return this._private; }
}
class ClassB extends ClassA {
constructor() {
super();
}
getValue(){
return `${super.getValue()}, second private value`;
}
}
Working to understand the new ES6 syntax. If I have a class like the Outlayer library that is not written in ES6 but want to extend it with an ES6 class how would that look? The key extension point is _getItemLayoutPosition
I tried something like this.
export let MyGrid = Outlayer.create('AnyGrid', {});
MyGrid._getItemLayoutPosition = function() {
// this does not get called
}
If I do new MyGrid(element)
My extended _getItemLayoutPosition never gets called.
So then I thought maybe I need to extend the class
export class AnyGrid extends Outlayer {
_getItemLayoutPosition(item) {
return {
x: 0,
y: 0
}
}
}
This gives an error Type 'typeof 'Outlayer'' is not a constructor function type.
What is the proper way to extend this class so that I can override the _getItemLayoutPosition method?
Since Outlayer.create actually creates a function that inherits from Outlayer you have to add the method on the prototype instead of the function itself
export let MyGrid = Outlayer.create('AnyGrid', {});
MyGrid.prototype._getItemLayoutPosition = function() {
// this does not get called
}
Note that the function returned when you call Outlayer.create has additional properties i.e. is not the same as creating a class that inherits from Outlayer
Please try the following:
// AnyGrid- subclass
function AnyGrid() {
Outlayer.apply(this, arguments); // call super constructor.
}
// subclass extends superclass
AnyGrid.prototype = Object.create(Outlayer.prototype);
AnyGrid.prototype.constructor = AnyGrid;
//Add/Override the method
AnyGrid.prototype._getItemLayoutPosition = function() {
// this does not get called
}
Don't forget to export AnyGrid.