附加到prototype属性的函数没有闭包

时间:2012-09-11 18:32:47

标签: javascript

我试图找出在创建构造函数后如何向构造函数添加方法 在下面的代码中,我不能使用Person的prototype属性来添加一个可以访问Person的vars的新公共方法。 (附加到prototype属性的函数是否不会靠近main函数中的vars) 与第一种方式不同,第二种方式起作用 - 人2.似乎这些被称为特权方法 - http://www.crockford.com/javascript/private.html

function Person(name, age){}
Person.prototype.details = function(){ 
    return "name: "+name+", age: "+age;
};

function Person2(name, age){
 this.details = function(){ 
    return "name: "+name+", age: "+age;};
}

var per1 = new Person("jim", 22);
var per2 = new Person2("jack", 28);

per1.details();
//=> ReferenceError: age is not defined
per2.details();
//=> "name: jack, age: 28"

3 个答案:

答案 0 :(得分:4)

不,它们没有构造函数变量的闭包。它们的范围不同。

// This function is in one scope.
function Person(name, age) {
}

// This statement is in the parent scope, which 
// doesn't have access to child scopes.
Person.prototype.details = function(){ 
    return "name: "+name+", age: "+age;
};

这就是“公共”功能在JavaScript中的工作方式。您可以通过在构造函数中定义details来使function Person(name, age) { this.details = function() { return "name: "+name+", age: "+age; }; } 成为特权函数:

Person

当然,这意味着details的每个实例都会获得它自己的name函数副本。

你也可以像@Chuck建议的那样,制作agefunction Person(name, age) { this.name = name; this.age = age; } Person.prototype.details = function(){ return "name: " + this.name + ", age: " + this.age; }; 个公共成员,你可以在原型函数中访问它们:

{{1}}

答案 1 :(得分:1)

没有。通常,您要么使用第二种方法,要么在构造函数中设置this._name = name;,并在另一种方法中以这种方式引用它。

答案 2 :(得分:0)

当然不是,函数是在一个范围内声明的,与声明参数/变量的范围不同,所以JS不会知道你所关注的变量。假设您有第二个闭包,或者更好(实际上更差):一个名为name的全局变量。 JS选哪一个?

以下是您的示例:

function MyObject(name)
{
    var localVar = 'foobar';
    this.evilMethod = (function(localVar)
    {
        return function()
        {
            console.log('localVar = '+localVar);//=== name
        };
    })(name);
    this.badMethod = function()
    {
        console.log('localVar = '+ localVar);// === 'foobar'
    };
}
var name = 'Global Name';
var anotherClosure = (function(name)
{
    var localVar = name.toLowerCase();
    return function()
    {
        console.log(name);
        console.log(localVar);
    }
})('Bobby');
MyObject.prototype.closureVars = function()
{
    console.log(name);//Global name
    console.log(localVar);//undefined
};

现在首先关闭:这是一个糟糕的代码,但你明白了:你可以拥有数百个具有相同名称的变量,一个JS必须使用,可能并不总是很清楚。

给原型访问实例闭包变量也有其他含义:例如,你可以改变它们的值,这首先打破了关闭的点。
但是,一个国家里程的最大问题是:多个实例!如果你创建了一个构造函数,那么你将要用它来实例化多个对象。 如果它们共享相同的原型,它将如何工作?

只需将原型中要访问的参数/变量分配给属性,例如FishBasketGordo的示例