Php 共享局部变量的JavaScript对象

Php 共享局部变量的JavaScript对象,php,javascript,jquery,Php,Javascript,Jquery,所以我在一些JavaScript代码中有一个bug,这让我有些疯狂。我一直在努力模仿JavaScript中的经典继承(我知道,我知道,我在这里读到的一半帖子都说不要将JavaScript扭曲成这样一个框架,但我的应用程序需要有一个客户端继承机制,映射到我的服务器端php代码的继承结构)。最重要的是,看起来一切正常。下面是我用来扩展类的函数: Function.prototype.inheritsFrom = function(parentClass) { //:: Ordinary Classe

所以我在一些JavaScript代码中有一个bug,这让我有些疯狂。我一直在努力模仿JavaScript中的经典继承(我知道,我知道,我在这里读到的一半帖子都说不要将JavaScript扭曲成这样一个框架,但我的应用程序需要有一个客户端继承机制,映射到我的服务器端php代码的继承结构)。最重要的是,看起来一切正常。下面是我用来扩展类的函数:

Function.prototype.inheritsFrom = function(parentClass) {
//:: Ordinary Classes
if (parentClass.constructor == Function) {
    this.prototype             = new parentClass();
    this.prototype.constructor = this;
    this.prototype.parent      = parentClass.prototype;

//:: Abstract Classes
} else {
    this.prototype             = parentClass;
    this.prototype.constructor = this;
    this.prototype.parent      = parentClass;
}
return this;
}
不是我自己的作品,我在网上找到的,但效果很好。我只需要添加一个“super”函数来搜索原型链中的父方法;上述代码中的父构造并非在所有情况下都有效

在任何情况下,当我一直在消除代码中的一些错误时,我发现我的基本“类”中的一个方法正在为从其所有子类创建的所有实例访问/修改相同的变量。换句话说,每当一个实例修改这个变量时,这个变量应该是其对象上下文的局部变量,实际上它修改了在所有实例之间共享的某个变量。下面是基类:

    function DataManipulatorControl() {
    //|| Private Members ||//

    var that = this;



    //|| Properties ||//

    //|| Root ID
    this.rootID = function(value) {
        if (value !== undefined) {
            if (_root_id !== null) {
                alert('@ ' + _root_id);
                $('#' + _root_id).prop('js_object', null);
            }
            _root_id = value;
            $('#' + _root_id).prop('js_object', this);
        }
        return _root_id;
    }
    var _root_id = null;

    // other properties/methods
}



//|| Class: DataManipulatorContainerControl
function DataManipulatorContainerControl() {
    //|| Private Members ||//

    var that = this;


    // subclass properties/methods
}
DataManipulatorContainerControl.inheritsFrom(DataManipulatorControl);
正如我提到的,当我创建这些原型的新实例时,我发现更改一个实例的rootID将更改所有实例的rootID。我的第一个想法是,我忘记了某个地方有一个“var”,我的函数正在访问全局上下文。但情况似乎并非如此,所以我的下一个想法是,它使用了原型的局部变量。不过,这对我来说也没有多大意义,因为原型构造函数调用的局部变量不应该在其外部访问,除非由已经在其作用域中的方法访问。当然,rootID()函数的作用域中确实包含它,但我的印象是,它将使用调用对象的对象上下文而不是原型来运行

所以,我很困惑。任何关于这个问题的线索都会引起人们的感激之情

编辑:PRB提供的这篇文章描述了一个解决方案,它干净地解决了这个问题——主要是。本文指出,您还需要从子类构造函数中调用父类的构造函数来正确初始化所有内容。因此,所有方法都是新创建的,闭包中有自己版本的父类局部变量

这种方法似乎有一个缺点(除了在每个实例中重复功能的效率问题)。如果有人试图从原型链调用“重写”函数来实现超级功能,那么这个问题将再次出现。与以前一样,原型是单个对象的实例,尝试调用其函数版本将导致它们尝试访问其实例的局部变量


不过,除了将所有数据公开之外,这仍然是我见过的最好的解决方案:-)。

使用这一行可能是问题所在:

this.prototype             = new parentClass();

这意味着该函数的所有实例共享由parentClass()定义的相同内存blob。这就是为什么当你改变其中一个的值时,它会影响所有的值。

好的,所以我在吃晚饭的时候一直在考虑这个问题,我想我可能已经掌握了发生的事情。我认为由于对象上下文的变化,我混淆了函数可用的变量,因为闭包,我混淆了函数可用的变量

正如PRB指出的,我的rootID()函数总是从实例化的原型访问内存块_root_id被创建为我的基类的构造函数的局部变量,因此,当该基类被实例化为原型时,所有使用原型函数的子类都将从构造函数中创建的一个变量读取/写入

因此,虽然这是创建原型的有效方法,但使用构造函数的局部变量隐藏对象的数据在子类中无法正常工作。相反,我需要读取/写入“this”中的变量,以便它随着对象上下文的变化而变化。如果有人知道更好的方法来处理这个问题-一个遵守数据隐藏的方法,请随时发表评论;与我一起工作的许多开发人员都毫不犹豫地直接访问数据成员,而不是通过访问器。使代码难以维护:-/

无论如何,感谢PRB的澄清!
~Nate

Hmm,我尝试删除“new”,将函数本身设置为原型,但随后它找不到rootID函数(这是有意义的,因为class函数对象没有获得成员函数,而通过调用class函数构造的对象会获得成员函数)。我认为对于原型继承,它不是使用原型的成员,而是使用调用对象的上下文吗?下面是对您看到的效果的一种解释:。还没有通读所有内容-2分钟谷歌。当您将原型设置为对新对象的引用时,任何实例都将共享相同的引用。哈哈!太棒了。他引用的不正确的那篇文章正是我从中获得继承函数的那篇文章。谢谢我现在要看完那篇文章:-)