1

I wanted to rearrange my Code to OOP, but I am not able to figure out my errors here, especially since they appear correct according to different Tutorials and examples. I suppose I misunderstand something of JS´s, object-instantiation and Call stack.

I will provide some examples, which I don´t understand.

What I want here is to do some operations on an Array and then get it to an other class.

https://jsfiddle.net/8g22nj8y/1/

<script>
$(document).ready(function() {
    var p = new Parser();
    p.init();
    p.getArray();
    p.getArray2();
    p.get3();
}</script>

function Parser() {

var myArray = [];
this.myArray2 = [];
thisReference = this;
  this.myArray3=[];

return {
    init: function () {
        alert("huhu");
        this.parse2();
        parse();
    },
    getArray: function () {
        alert(thisReference.myArray2.length);

    },
    getArray2: function () {
        alert(myArray);
    }
}

function parse() {
    var arr = [1, 2, 3];
    myArray.push(arr);
    myArray2.push(arr);

 for(var i =0;i<10;i++){
       a=[];
        a.push(i);
        thisReference.myArray3.push(a);
    }

}}Parser.prototype.parse2 = function () {
var arr = [1, 2, 3];
myArray.push(arr);
this.myArray2.push(arr);};

Independent how I run it, it always says that this.parse2() is not a function. When I am only using parse(), it says that myArray2 is undefined, althought it´s clearly there - just as "class variable". If I change myArray2 in parse() to thisReference.myArray2 it´s working.

Why? I thought an inner Function - which parse() clearly is, is able to grab all the variable in the outer function - in this case Parser(). When I am now using myArray3 either if it´s used with thisReference or with this. "it is not defined". If I call parse2 with thisReference it´s working, but then "myArray is not defined", yes it´s an local variable but it´s in the same class and if I call parse() I am able to use it without problems.

Furthermore:

simplified: https://jsfiddle.net/Lzaudhxw/1/

    function Syntax(){
   var mine = new Lex();
   myRef=this;
   }
   Class1.prototype.foo=function(){
       myRef.mine.setFunc(5);
       myRef.mine.publicFunc();}


function Lex(){
   this.x, this.h=1;
    return{
       publicFunc: function(param){
         this.h;
         this.x;
        },
        setFunc: function(x){
         this.x=x;
      }
}

Initially I set h to be 1. If I now instantiiate Syntax and call from that the publicFunc from Lex both are undefined. But if I run foo() from Syntax and call the publicFunc again, x is set to the value and h is undefined. Why is it not possible to predefine an varriable (in this case h) like that and then use it?

EDIT to Jan´s Answer:

I read in many Tutorials and some production code that you should store "this" into an variable. Why should myRef point to anything else than the Syntax Object? :O Why is myRef not an variable of Syntax? Does it have to be this.myRef? Ahh right, var means local, so mine is only accessiable in the constructor?!

I didn´t wanted to init "x", only define it. Ahh with return{} I am creating a new class/object, then it´s clear that this. does not point to the above vars. But to introduce an myRef=this should do the job, right?

...So, it´s wiser to use prototype to add functions instead of an inner function?

  • As a side note, you're technically doing "functional" programming. That's fine. You're improving your code ability, and you're going to get much better code as a result. Javascript is prototypical and doesn't support object oriented programming. However, many many programmers get sloppy with the theory behind the term and call it object oriented when they mean they're dividing code into objects, using functions, and all that jazz. Object oriented concepts: http://www.c4learn.com/cplusplus/cpp-pillars-of-oop/ OOP is still important for you because it's a good way of thinking about problems. – Palu Macil Aug 16 '15 at 01:54
  • @PaluMacil Javascript is fundamentally most certainly object oriented, just not in the same way as for example C-variants. Javascript just does things very, very differently. And because of that you shouldn't really try to program the same way that you would a C-variant application but rather use the strengths of Javascript (the combination of OOP and functional programming that you mention) to its advantage. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript – Jan Aug 16 '15 at 02:50
  • There might be a slim majority that would agree with you (I say this because Wikipedia seems to state quite strongly that it's OO), but in order to use inheritance, you sacrifice encapsulation (great SO answer covering this here: http://stackoverflow.com/questions/107464/is-javascript-object-oriented), and to me that is a blatant violation of the basic definition of OO. It's not a language flaw. The way JavaScript works isn't inferior, but I do believe people should realize that prototypes are different because otherwise they'll write poor OO code when they learn Python, C#, or PHP etc. – Palu Macil Aug 16 '15 at 03:23
  • Whether it's a flaw or not, it's certainly a limitation. Now if that makes or breaks it being OOP I guess is up to your definition of OOP... I agree that peeps absolutely should realize it's different and play to its strengths rather than attempting to do what other languages do, because that's when things start becoming hairy and confusing. There's absolutely concepts to be learnt from all languages that are worth bringing over, just, you know, learn how each language SHOULD be used too. – Jan Aug 16 '15 at 12:07
  • Yes, I knew that JS is not an OOP Language like Java. It´s prototyped and uses Closures. But in order to structure my Code better I wanted to use that "Pseudo OOP". But it has some really strange differences, especially since some stuff looks correct (well, more or less...) for Java OOP. And Yes, Java !=JS – user3320354 Aug 16 '15 at 19:33
  • It's not "pseudo" OOP, just not the same OOP as Java or C. Nor the same syntax for many things. So it would be better to treat it as an entirely different language when learning it. Instead of thinking "I recognize this", look up how it actually works, bit by bit. The documentation is a great help, and many of your questions have likely been answered already on SO. – Jan Aug 16 '15 at 20:36
  • Main points of interest: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects – Jan Aug 16 '15 at 20:38

1 Answers1

2

Yeah you've got a bunchload of JS concepts wrong. I suggest you read the documentation. Tried adding a few explanations.

function Syntax(){
    // Since you're returning a new  object from "Lex" straight away, there's 
    // little point of using "new" here
    var mine = new Lex();
    // Why store "this" here? "this" will be accessible from your prototype 
    // methods pointing to your object instance... Provided you use "new Syntax()",
    // Otherwise "myRef" will (probably) point to the global object.
    myRef=this;
}

// Where's "Class1"? You don't have a Class1 function anywhere. You probably mean "Syntax"
Class1.prototype.foo=function() {
    // "myRef" is not a property of "Syntax", so it wouldn't be accessible here.
    // Furthermore, "mine" is declared as a variable above, so it wouldn't be 
    // accessible in this manner even if "myRef" pointed to "this" (which it doesn't).
    myRef.mine.setFunc(5);
    myRef.mine.publicFunc();
}

function Lex(){
    // This is a correct property declaration of h. You're not setting the 
    // value of x here though, just calling it. Javascript allows "trying" 
    // to call ANY property of ANY object without giving neither a compilation
    // nor runtime error, so calling the undefined "this.x" here is valid.
    // It just won't do anything.
    this.x, this.h=1;
    // Here you return a new object straight off, so the below "this" will point  
    // to the object below, not the "Lex" object defined above. So your above
    // defined "this.h" will not be used, it's a property of a different object.
    return {
        publicFunc: function(param){
            this.h;
            this.x;
        },
        setFunc: function(x){
            this.x=x;
        }
    }
 // You're missing a closing bracket here.

What you're probably trying to do would look something like this with correct Javascript syntax

function Syntax(){
    this.mine = Lex();
}
Syntax.prototype.foo=function() {
    this.mine.setFunc(5);
    this.mine.publicFunc();
}

function Lex() {
    return {
        h:1,
        publicFunc: function(){
            console.log(this.h);
            console.log(this.x);
        },
        setFunc: function(x){
            this.x=x;
        }
    }
}

var s = new Syntax();
s.foo();

But returning an object from Lex would be pretty impractical in most cases. So what you really REALLY want to do is probably

function Syntax(){
    this.mine = new Lex();
}
Syntax.prototype.foo = function() {
    this.mine.setFunc(5);
    this.mine.publicFunc();
}

function Lex() {
    this.h = 1;
}
Lex.prototype = {
    publicFunc: function(){
        console.log(this.h);
        console.log(this.x);
    },
    setFunc: function(x){
        this.x=x;
    }
};

var s = new Syntax();
s.foo();
Jan
  • 5,192
  • 3
  • 24
  • 44
  • Thanks for the detailed answer. I already read many documentations but there is just something I can´t understand in JS.....And I have some further questions to your answer. – user3320354 Aug 16 '15 at 19:34
  • @user3320354 If you have more questions, ask a new question. Feel free to point me in the direction of it and I can have a look. Most likely, your questions already have answers on SO though if you use the search. Also, when you say "many documentations" I wonder if you understand what I meant. Did you read all of MDN and EcmaScript 5 and 6 or what do you mean by "many"? See the links I posted as a comment to your question and note that these are all just *parts* of the *same* documentation and just a tip on where to *start* reading the MDN documentation. – Jan Aug 20 '15 at 00:02
  • Actually there weren't that many questions (but you still shouldn't edit your question with new questions. It's been answered already). *"var means local, so mine is only accessiable in the constructor?!"* Yes. *"I didn´t wanted to init "x", only define it"* As I said, you don't need to "define" object properties. You can try to call any property and JS won't fail, it will just return the value `undefined`. If you want it to NOT return undefined, set its value. *"So, it´s wiser to use prototype to add functions instead of an inner function?"* Depends. You should look up the difference. – Jan Aug 20 '15 at 01:30
  • @user3320354 And here you can see for example how this has been asked many, many times on SO already http://stackoverflow.com/questions/4508313/advantages-of-using-prototype-vs-defining-methods-straight-in-the-constructor – Jan Aug 20 '15 at 01:30