0

I thought that functions created using .prototype were supposed to be able to access local variables. Here is what I'm talking about:

function obj() {
    var a = "String";

    this.innerPrint = function() {
        document.write("<p>" + a + "</p>");
    };
}

obj.prototype.outerPrint = function() {
    document.write("<p>" + a + "</p>");
};

var inst = new obj();
inst.innerPrint();
inst.outerPrint();

What I thought would happen is that both of these functions would do the same thing. But what actually happened is outerPrint doesn't have access to the variable a. Could someone explain to me how you get locals in a prototype function.

Here is a fiddle running this code: http://jsfiddle.net/Wryte/mxXzg/

By the way, I want to use prototype functions because then each instantiation of the object doesn't have a copy of the function but they each point to the same one.

4

4 回答 4

1

如果您希望a在构造函数完成执行后仍然可以访问您的变量,请将您的代码更改为

function obj() {
    this.a = "String";

    this.innerPrint = function() {
        document.write("<p>" + this.a + "</p>");
    };
}

obj.prototype.outerPrint = function() {
    document.write("<p>" + this.a + "</p>");
};

或者如果您不想提供直接写访问权限,请定义一个 getter:

function obj() {
    var a = "String";
    this.getA = function() {
        return a;
    }
    this.innerPrint = function() {
        document.write("<p>" + a + "</p>");
    };
}

obj.prototype.outerPrint = function() {
    document.write("<p>" + this.getA() + "</p>");
};
于 2012-09-26T13:20:05.130 回答
1

当您声明“a”时,它是在 obj() 函数的词法范围内声明的。所有实例变量也需要原型化,因此它的 instedvar a应该声明为this.a.

于 2012-09-26T13:22:55.173 回答
1

当然不是,您不能从定义在第一个函数之外的另一个函数访问一个函数的本地变量。第二个是否在第一个的原型属性中定义并不重要。函数的每次调用都会obj定义一个的局部a变量,因此您无法避免需要访问它的函数的单独副本。

我假设您实际上要求该变量是本地而不是实例属性,因此一种可能的方法是在您的函数周围只使用一个薄的本地包装器:

function obj() {
    var a = "String";

    this.wrapper = function() { outerPrint.call(this, a); }
    this.innerPrint = function() {
        document.write("<p>" + a + "</p>");
    };
}

function outerPrint(a) {
    document.write("<p>" + a + "</p>");
};

同样,我假设你有一个更复杂的函数来代替outerPrint,所以这样你可以避免重复一个大函数,而代价是重复一个最小的包装器。通过这种方式,您可以保留a变量的私有性,而公共 getter 将允许外部代码检查其值。

更新:在@Bergi 的评论中,我修改了代码以在定义构造outerPrint函数的同一范围内创建一个本地函数。obj不再在原型上,它不会被obj实例直接调用。请注意,所有代码都需要在函数范围内,以避免全局outerPrint函数。

于 2012-09-26T13:25:51.743 回答
0

不,它是一个局部变量。由于名为 的属性,不会绕过范围规则prototype

该变量只能从构造函数中定义的函数访问;因此,他们被称为特权。当然,当这些可以作为公共方法访问时,您可以从外部调用它们,即。

Obj.prototype.outerPrint = function() {
    this.innerPrint();
};
于 2012-09-26T13:27:23.190 回答