Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/439.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用prototype访问局部变量_Javascript - Fatal编程技术网

Javascript 使用prototype访问局部变量

Javascript 使用prototype访问局部变量,javascript,Javascript,我有一个类,它有一个带有公共setter/getter函数的私有变量: function Circle(rad) { var r = rad; this.radius = function(rad) { if(!arguments.length) return r; r = rad; return this; } } var shape = new Circle(10); console.log( shape.radiu

我有一个类,它有一个带有公共setter/getter函数的私有变量:

function Circle(rad) {
    var r = rad;

    this.radius = function(rad) {
        if(!arguments.length) return r;
        r = rad;
        return this;
    }
}

var shape = new Circle(10);
console.log( shape.radius() ); // 10
shape.r = 50;
console.log( shape.radius() ); // 10

如何使用
Object.prototype
?或者,什么时候我想使用闭包而不是
Object.prototype
?这是我能想到的最接近的,但是正如你所看到的,你可以直接改变属性

function Circle(r) {
    this.r = r;
}

Circle.prototype.radius = function(r) {
    if(!arguments.length) return this.r;
    this.r = r;
    return this;
};

var shape = new Circle(10);
console.log( shape.radius() ); // 10
shape.r = 50;
console.log( shape.radius() ); // 50

如果要使用原型存储对象的属性,则可以从任何引用该对象的代码访问这些属性。做你想做的事是不可能的

许多JS开发人员所做的只是用一个前导下划线命名私有属性,以便其他人知道不要弄乱它,但除了建议之外,它不会给您任何真正的保护

使用闭包法的原因

  • 真正的私人变数,确信没有人会弄乱你的私事
使用原型的原因

  • 使用的内存更少(每个实例都没有闭包)
  • 易于调试(属性在对象本身上可见)
  • 允许猴子修补

读者:请编辑答案,并说明您认为最佳解决方案的原因。

如果您要使用原型存储对象的属性,可以从任何引用该对象的代码中访问这些属性。做你想做的事是不可能的

许多JS开发人员所做的只是用一个前导下划线命名私有属性,以便其他人知道不要弄乱它,但除了建议之外,它不会给您任何真正的保护

使用闭包法的原因

  • 真正的私人变数,确信没有人会弄乱你的私事
使用原型的原因

  • 使用的内存更少(每个实例都没有闭包)
  • 易于调试(属性在对象本身上可见)
  • 允许猴子修补

读者:请编辑答案,并说明您认为最佳解决方案的理由。

我发现您的第一个圆圈非常奇怪。如果你这样写:

        function Circle(rad) {
            var r = rad;

            this.radius = function(rad) {
                if(rad){r = rad;}
                return r;
            }
        }
shape.r = 50;
我想它现在正符合你的意思。r是私有的,radius充当getter/setter函数。 将r设置为这样:

        function Circle(rad) {
            var r = rad;

            this.radius = function(rad) {
                if(rad){r = rad;}
                return r;
            }
        }
shape.r = 50;
没有意义,因为第一个圆没有属性r,它只有一个局部范围的变量r。这应该会引起某种错误


我看不到在第二个版本的Circle中使用prototype的方法,因为prototype链中的函数无法访问在Circle对象中创建的变量。无论如何,在第二个版本中,r是圆的一个属性,而不是函数体中的一个私有范围变量。

我发现你的第一个圆非常奇怪。如果你这样写:

        function Circle(rad) {
            var r = rad;

            this.radius = function(rad) {
                if(rad){r = rad;}
                return r;
            }
        }
shape.r = 50;
我想它现在正符合你的意思。r是私有的,radius充当getter/setter函数。 将r设置为这样:

        function Circle(rad) {
            var r = rad;

            this.radius = function(rad) {
                if(rad){r = rad;}
                return r;
            }
        }
shape.r = 50;
没有意义,因为第一个圆没有属性r,它只有一个局部范围的变量r。这应该会引起某种错误



我看不到在第二个版本的Circle中使用prototype的方法,因为prototype链中的函数无法访问在Circle对象中创建的变量。无论如何,在您的第二个版本中,r是Circle的一个属性,而不是函数体中的一个私有范围变量。

您是否希望能够从外部设置它?我希望它可以通过我定义的公共getter/setter函数访问。我不希望类外的任何人都可以直接公开访问变量。“我如何使用类的原型对象复制它?”我不太理解这个问题。为什么要用一种可能不应该实现的语言特性来复制某个行为?@Wex这不是Java。唯一的答案是“不要再这样做了”,并在“private”字段前面加下划线之类的前缀。(或者像以前一样使用闭包,除非你有理由不这么做。)你,或者你不想从外部设置它吗?我想通过我定义的公共getter/setter函数访问它。我不希望类外的任何人都可以直接公开访问变量。“我如何使用类的原型对象复制它?”我不太理解这个问题。为什么要用一种可能不应该实现的语言特性来复制某个行为?@Wex这不是Java。唯一的答案是“不要再这样做了”,并在“private”字段前面加下划线之类的前缀。(或者像以前一样使用闭包,除非你有理由不这么做。)坚持使用我的第一个版本的代码有什么坏处吗?或者有更好的替代方案吗?缺点是为每个对象创建一个新的闭包,即额外的内存。我不是偏执于私有财产,我用下划线来表示私有财产。如果有人在课外碰它,我就揍他们的头,直到他们学会不碰为止!所以使用Object.prototype比创建闭包更好?我不能说一个比另一个好,我更喜欢prototype方法。我告诉过你好处,你可以做决定。如果你偏执于私有变量,并且认为开发人员不会遵循这种模式,那么你应该使用闭包。如果您信任将要使用代码的人,我将始终使用原型方法,因为它具有灵活性(为了便于调试,检查对象本身的属性要比检查存储在闭包中的属性容易得多。使用原型的另一个原因是允许对类进行猴子修补。这可能是好事,也可能是坏事,所以要明智地使用它。我经常为JS LIB创建自己的修补程序,只有在使用原型appro时才能做到这一点。)啊,你必须明白,如果你做了什么事,你可能会弄坏东西,但这通常比等待一个好