1

我试图弄清楚在创建构造函数后如何向构造函数添加方法。
在下面的代码中,我不能使用 Person 的原型属性来添加一个可以访问 Person 变量的新公共方法。(是否附加到原型属性的函数不关闭主函数中的变量)。
与第一种方式不同,第二种方式有效 - Person 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"
4

3 回答 3

4

不,它们没有对构造函数 vars 的封闭。它们在不同的范围内。

// 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函数副本。

正如@Chuck 建议的那样,您还可以制作nameage公开成员,您可以在原型函数中访问它们:

function Person(name, age) {
    this.name = name;
    this.age = age;
}

Person.prototype.details = function(){ 
    return "name: " + this.name + ", age: " + this.age;
};
于 2012-09-11T18:35:20.537 回答
1

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

于 2012-09-11T18:39:31.777 回答
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 必须使用,可能并不总是很清楚。

让原型访问实例闭包变量也有其他含义:例如,您可以更改它们的值,这首先破坏了拥有闭包的意义。
但是一个国家英里最大的问题是:多个实例!如果您创建一个构造函数,您很可能会用它实例化超过 1 个对象。如果它们都共享相同的原型,那将如何工作?

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

于 2012-09-11T18:36:50.597 回答