1

コンストラクターを作成した後、コンストラクターにメソッドを追加する方法を理解しようとしています。
以下のコードでは、Personのプロトタイププロパティを使用して、Personの変数にアクセスできる新しいパブリックメソッドを追加することはできません。(プロトタイププロパティにアタッチされた関数は、メイン関数の変数を閉じないでください)。
最初の方法とは異なり、2番目の方法は機能します-Person2.これらは特権メソッドと呼ばれているようです-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が示唆しているように、プロトタイプ関数でそれらにアクセスできるメンバーを作成nameして公開することもできます。age

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

いいえ。通常、2番目のアプローチを使用するかthis._name = name;、コンストラクターで設定して、他のメソッドでそのように参照します。

于 2012-09-11T18:39:31.777 に答える
0

もちろんそうではありません。引数/変数が宣言されたスコープとは異なるスコープで関数が宣言されたため、JSはユーザーがどの変数を使用しているかを認識しません。2番目のクロージャ、またはそれよりも優れている(実際にはさらに悪い)クロージャがあるとします。これは、と呼ばれるグローバル変数です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
};

まず最初に、これはひどいコードですが、要点はわかります。同じ名前の変数を何百も持つことができ、1つのJSが使用する必要がありますが、必ずしも明確ではない場合があります。

プロトタイプにインスタンスクロージャ変数へのアクセスを許可することには、他の意味もあります。たとえば、値を変更すると、そもそもクロージャを持つという点が無効になります。しかし、カントリーマイルによる
最大の問題は次のとおりです。複数のインスタンス!コンストラクターを作成する場合、それを使用して複数のオブジェクトをインスタンス化する可能性があります。それらがすべて同じプロトタイプを共有する場合、それはどのように機能しますか?

FishBasketGordoの例のように、プロトタイプでアクセスする引数/変数をプロパティに割り当てるだけです。

于 2012-09-11T18:36:50.597 に答える