0

プログラマーの皆さん、こんにちは。JavaScriptの学習を始めました。この構文は純粋な魔術です、誰かが明確にすることができます:

function CleanPet(){
    alert("The pet is now clean!");
}

CleanPet.Description="Dirty Business";

私が読んでいる資料では、JavaScriptでは関数は他のオブジェクトと同じであると説明していますが、関数にプロパティをアタッチすると、実際には宣言していないため、静的であるということですか?

助けてくれてありがとう、IN

4

4 に答える 4

3

varオブジェクトのプロパティは、変数の場合のように使用するという形式的な意味で「宣言」されていません。既存のオブジェクトを指定すると、(質問のCleanPetように)プロパティを割り当てて、プロパティがまだ存在しない場合は作成するか、プロパティがすでに存在する場合は上書きすることができます。CleanPet.DescriptionDescription

まだ設定していないオブジェクトプロパティにアクセスしようとすることも「合法」です。たとえば、CleanPet.SomeOtherProperty結果の値はになりますundefined。(エラーではありませんが、CleanPet実際にはオブジェクトであると想定しています。isまたはthenの場合CleanPetnullエラーundefinedCleanPet.SomeOtherProperty発生します。)

したがって、特に関数に関しては、関数宣言は次のようになります。

 function CleanPet { /* some code */ }

...たまたま関数である単一のオブジェクトを宣言します。つまり、関数として呼び出すことができますがCleanPet()、プロパティを割り当てる機能など、「通常の」オブジェクトの動作は引き続き得られます。

JavaScript関数は、new:で呼び出された場合、オブジェクトコンストラクターでもあります。

var cleanPet1 = new CleanPet();

その場合、JSは、を呼び出すたびに新しいオブジェクト(インスタンス)を作成しますnew CleanPet()が、結果のインスタンスのプロパティではなく、コンストラクターのプロパティであるため、経由でCleanPet.Descriptionプロパティにアクセスすることはできません。その意味で、そうです、プロパティは「静的」です。cleanPet1.Descriptionnew

于 2013-01-27T04:58:49.620 に答える
1

はい、関数/クラスのプロパティは静的です

MyClass.Description = "Dirty Business";

MyClass.staticFn = function() {

};

MyClass = function() {
  this.var = "test";
};

MyClass.prototype.instanceFn = function() {

};


// To call an instance function
obj = new MyClass();
obj.instanceFn();

// To call a static function
MyClass.staticFunction();

// Or to access a static property
alert(MyClass.Description)
于 2013-01-27T04:58:38.777 に答える
1

javascriptの関数はオブジェクトであり、プロパティを持つことができます。

例のようにプロパティを関数に割り当てると、その関数オブジェクトに新しいプロパティが作成され、関数自体と同じスコープの変数のように動作しますが、プロパティのスコープは関数名のみであるため、グローバル名前空間を汚染しません。

これを行う理由はいくつかあります。

  1. 関数の呼び出しから別の呼び出しまでその値を維持するグローバル変数が必要です。
  2. この新しい変数のグローバル名前空間を汚染したくない。
  3. 関連する関数に関連付けられたグローバル変数をカプセル化するというアイデアが好きです。
  4. 関数を実行するたびに静的宣言または定数宣言が再評価されないように、コードを最適化する必要があります。

あなたの例では、4つすべての利点がわかります。

于 2013-01-27T05:02:02.927 に答える
1

JavaScriptとC++の比較

JavaScriptは、Selfのような典型的なオブジェクト指向言語です。ただし、JavaScriptの構文はC /C++から借用しています。これは、古典的なオブジェクト指向のバックグラウンドから来たほとんどのプログラマーを混乱させるものです。

1.公的および私的財産

次のC++プログラムについて考えてみます。

#include <iostream>

using namespace std;

class Rectangle {
    int height;
    int width;

    public:

    Rectangle(int height, int width) {
        this.height = height;
        this.width = width;
    }

    int area() {
        return height * width;
    }
}

int main() {
    Rectangle rectangle(3, 7);
    cout << rectangle.area() << endl;
    return 0;
}

これにより、次のように1対1でJavaScriptに変換されます。

main();

function Rectangle(height, width) {
    this.area = function () {
        return height * width;
    };
}

function main() {
    var rectangle = new Rectangle(3, 7);
    console.log(rectangle.area());
    return 0;
}

ここで注意すべきことがいくつかあります。

  1. 関数mainは、宣言される前に呼び出されました。これが可能なのは、宣言が引き上げられているためです。前方宣言は必要ありません。
  2. Squareクラス」(ahem、「コンストラクター関数」)は単純で小さいです。
  3. パブリックプロパティ(または関数)は、が指すオブジェクトに追加されthisます。
  4. それ以外はすべてプライベートです(クロージャを介してのみアクセスできます)。

2.共有パブリックプロパティ

C ++では、インライン関数のみがクラス本体内で定義されます。他のすべての関数は外部で定義する必要があります。ただし、通常、すべての関数(インライン関数を含む)は外部で定義されます。

#include <iostream>

using namespace std;

class Rectangle {
    public:

    int height;
    int width;

    Rectangle(int height, int width);
    int area();
}

Rectangle::Rectangle(int height, int width) {
    this.height = height;
    this.width = width;
}

int Rectangle::area() {
    return this.height * this.width;
}

int main() {
    Rectangle rectangle(3, 7);
    cout << rectangle.area() << endl;
    return 0;
}

prototypeJavaScriptでは、コンストラクター関数のに共有メソッドを追加します(共有プロパティを作成しないでください) 。これは、上記のC++プログラムに似ています。そうすることの利点は、JavaScriptがコンストラクター関数のインスタンスごとに新しいメソッドを作成しないことです。

main();

function Rectangle(height, width) {
    this.height = height;
    this.width = width;
}

Rectangle.prototype.area = function () {
    return this.height * this.width;
};

function main() {
    var rectangle = new Rectangle(3, 7);
    console.log(rectangle.area());
    return 0;
}

クラス内でプロパティとメソッドを宣言する必要がないため、JavaSctiptバージョンは実際には小さくなっています。

3.パブリック静的プロパティ

C ++では、クラスの静的プロパティとメソッドを宣言できます。これは、クラスをオブジェクトとして使用するようなものです。関数をオブジェクトとして使用することもできます。それらはファンクターと呼ばれます:

#include <iostream>

using namespace std;

class Rectangle {
    public:

    int height;
    int width;

    static Rectangle fromSquare(int side);
    Rectangle(int height, int width);
    int area();
}

static Rectangle Rectangle::fromSquare(int side) {
    return new Rectangle(side, side);
}

Rectangle::Rectangle(int height, int width) {
    this.height = height;
    this.width = width;
}

int Rectangle::area() {
    return this.height * this.width;
}

int main() {
    Rectangle square = Rectangle.fromSquare(5);
    cout << square.area() << endl;
    return 0;
}

関数はJavaScriptのオブジェクトであるため、(関数のように)プロパティを追加するだけです。これらの関数がコンストラクターとして使用される場合、関数のプロパティは静的プロパティと呼ばれます。

main();

Rectangle.fromSquare = function (side) {
    return new Rectangle(side, side);
};

function Rectangle(height, width) {
    this.height = height;
    this.width = width;
}

Rectangle.prototype.area = function () {
    return this.height * this.width;
};

function main() {
    var square = Rectangle.fromSquare(5);
    console.log(square.area());
    return 0;
}

それでおしまい。JavaScriptとC++の同じコードのサイズの違いをご覧ください。どの構文が純粋な魔術であるかを決定します。=)

4.結論

JavaScriptでOOPに苦労している場合は、https ://github.com/javascript/augmentのように、役立つ古典的なオブジェクト指向ライブラリがたくさんあります。

于 2013-01-27T05:55:23.890 に答える