Javascript OOP和类问题

Javascript OOP and Classes Problems

本文关键字:问题 OOP Javascript      更新时间:2023-09-26

我想重新安排我的代码面向对象,但我不能找出我的错误在这里,特别是因为他们似乎是正确的根据不同的教程和例子。我想我误解了JS的一些东西,对象实例化和调用堆栈。

我将提供一些我不理解的例子。

我想在这里对数组做一些操作,然后把它放到另一个类中。

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);};

不管我如何运行它,它总是说this.parse2()不是一个函数。当我只使用parse()时,它说myArray2是未定义的,尽管它清楚地存在-就像"类变量"一样。如果我在parse()中将myArray2改为thisReference。

为什么?我认为内部函数- parse()显然是,能够捕获外部函数中的所有变量-在这种情况下是Parser()。当我现在使用myArray3,如果它使用thisReference或这个。"它没有定义"。如果我用thisReference调用parse2,它是工作的,但是"myArray未定义",是的,它是一个局部变量,但它在同一个类中,如果我调用parse(),我可以使用它没有问题。

此外:

简化: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;
      }
}

一开始我设h为1。如果我现在实例化语法并从中调用Lex中的publicFunc,则两者都是未定义的。但是,如果我从语法中运行foo()并再次调用publicFunc,则x被设置为值,h未定义。为什么不可能像那样预定义一个变量(在本例中是h)然后使用它呢?

编辑到Jan的回答:

我在许多教程和一些产品代码中读到,你应该将"this"存储到一个变量中。为什么myRef应该指向语法对象以外的任何东西?:阿为什么myRef不是语法变量?一定是这个。myref吗?啊,对了,var的意思是局部的,所以我的只能在构造函数中访问?!

我不想初始化"x",只定义它。啊,用return{}我正在创建一个新的类/对象,那么很明显,这。不指向上述变量。但是引入myRef=这个就可以了,对吧?

…所以,它是明智的使用原型添加函数,而不是内部函数?

是的,你有一堆错误的JS概念。我建议你阅读文档。试着添加一些解释。

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.

你可能想要做的是像这样使用正确的Javascript语法

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();

但是在大多数情况下,从Lex返回一个对象是非常不切实际的。所以你真正想做的可能是

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();