JavaScriptオブジェクトのコンストラクタ


回答:


408

プロトタイプを使用する:

function Box(color) // Constructor
{
    this.color = color;
}

Box.prototype.getColor = function()
{
    return this.color;
};

「色」を非表示にする(プライベートメンバー変数に似ている):

function Box(col)
{
   var color = col;

   this.getColor = function()
   {
       return color;
   };
}

使用法:

var blueBox = new Box("blue");
alert(blueBox.getColor()); // will alert blue

var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green

3
@BorisB、はい、そうです-これはBoxオブジェクトのcolorとgetColorを定義します。そうでなければ、通常のスコープで変数を割り当てます。
Nick

4
@Jeachはい、そうです。非表示にする代替スニペットを用意しましたcolor。どちらを使用するかは、主に個人の好み(保護対単純)にあるとお勧めします
Nick

6
@CamiloMartin必ずしも必要ではありませんが、変数を「プライベート」(またはこの場合は名前を付けられない)にすることは、外部コードがクラスの実装の詳細に依存するのを防ぐのに役立つ方法です。クラスのどの要素がパブリック/プライベートであるかを示すだけでも、外部ユーザーに役立ちます。
Nick

49
varプライベート変数を作成します。thisパブリック変数を作成します
EhevuTov

3
@AlanKis(少なくとも一部のJavascriptエンジンでは)スタックトレースは、匿名関数の場合は言及さえしませんFooが、後者の場合Fooは呼び出されていることがわかります。デバッグに非常に役立ちます。
Joachim Isaksson 2013年

248

JavaScriptでのOOPと同様の動作に使用するテンプレートを以下に示します。ご覧のとおり、クロージャーを使用してプライベート(静的およびインスタンスの両方)メンバーをシミュレートできます。何new MyClass()が返されますことに割り当てられた唯一のプロパティを持つオブジェクトであるthisオブジェクトと中prototypeのオブジェクト「クラスです。」

var MyClass = (function () {
    // private static
    var nextId = 1;

    // constructor
    var cls = function () {
        // private
        var id = nextId++;
        var name = 'Unknown';

        // public (this instance only)
        this.get_id = function () { return id; };

        this.get_name = function () { return name; };
        this.set_name = function (value) {
            if (typeof value != 'string')
                throw 'Name must be a string';
            if (value.length < 2 || value.length > 20)
                throw 'Name must be 2-20 characters long.';
            name = value;
        };
    };

    // public static
    cls.get_nextId = function () {
        return nextId;
    };

    // public (shared across instances)
    cls.prototype = {
        announce: function () {
            alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
                  'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
        }
    };

    return cls;
})();

私はこのパターンを使用した継承について尋ねられたので、ここに行きます:

// It's a good idea to have a utility class to wire up inheritance.
function inherit(cls, superCls) {
    // We use an intermediary empty constructor to create an
    // inheritance chain, because using the super class' constructor
    // might have side effects.
    var construct = function () {};
    construct.prototype = superCls.prototype;
    cls.prototype = new construct;
    cls.prototype.constructor = cls;
    cls.super = superCls;
}

var MyChildClass = (function () {
    // constructor
    var cls = function (surName) {
        // Call super constructor on this instance (any arguments
        // to the constructor would go after "this" in call(…)).
        this.constructor.super.call(this);

        // Shadowing instance properties is a little bit less
        // intuitive, but can be done:
        var getName = this.get_name;

        // public (this instance only)
        this.get_name = function () {
            return getName.call(this) + ' ' + surName;
        };
    };
    inherit(cls, MyClass); // <-- important!

    return cls;
})();

そして、それをすべて使用する例:

var bob = new MyClass();
bob.set_name('Bob');
bob.announce(); // id is 1, name shows as "Bob"

var john = new MyChildClass('Doe');
john.set_name('John');
john.announce(); // id is 2, name shows as "John Doe"

alert(john instanceof MyClass); // true

ご覧のように、クラスは互いに正しく相互作用します(それらはからの静的IDを共有しMyClassannounceメソッドは正しいget_nameメソッドを使用しますなど)。

注意すべきことの1つは、インスタンスのプロパティをシャドウする必要があることです。実際には、inherit関数であるすべてのインスタンスプロパティを(を使用してhasOwnProperty)処理し、自動的にsuper_<method name>プロパティを追加できます。これによりthis.super_get_name()、一時的な値に格納してを使用してバインドする代わりにを呼び出すことができますcall

プロトタイプのメソッドについては、上記のことを心配する必要はありません。スーパークラスのプロトタイプメソッドにアクセスする場合は、を呼び出すだけthis.constructor.super.prototype.methodNameです。簡潔にしたい場合は、もちろん便利なプロパティを追加できます。:)


7
cls.prototypeパーツに関するメモ:「インスタンス間で共有」は値を読み取る(を呼び出すannounce)ためだけです。myClassInstance.announce別の値に設定すると、で新しいプロパティが作成myClassInstanceされるため、そのオブジェクトにのみ適用され、クラスの他のインスタンスには適用されません。に割り当ててMyClass.prototype.announceも、すべてのインスタンスに影響します。
マシュークルムリー

1
問題ありません。お役に立ててうれしいです。:)
Blixt 2011

2
ありがとうございました!とても気に入りました!このアプローチでのクラス継承の例を示してください。
Dmitrij Golubev 2012年

2
@ DmitrijGolubev、Brad Dwyer、Nathan C. Tresch:継承を追加しましたが、かなり複雑になっているので、JavaScriptでこのようなハードコアの継承が必要でない限り、通常はより単純なソリューションを使用することをお勧めします(実際には単なる原型言語)。
Blixt

1
あなたはコンストラクタ関数(「クラス」)ではなく、インスタンス上で、それを呼ぶだろうので、それは「公共の静的な」方法だ@guiomie:MyClass.get_nextId()
Blixt

166

あなたのほとんどは、コンストラクタではなくゲッターとセッターの例を示しているようです。つまり、http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)です。

ランチダンはもっと近かったが、この例はjsFiddleでは機能しなかった。

この例では、オブジェクトの作成中にのみ実行されるプライベートコンストラクター関数を作成します。

var color = 'black';

function Box()
{
   // private property
   var color = '';

   // private constructor 
   var __construct = function() {
       alert("Object Created.");
       color = 'green';
   }()

   // getter
   this.getColor = function() {
       return color;
   }

   // setter
   this.setColor = function(data) {
       color = data;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange');

alert(b.getColor()); // should be orange

alert(color); // should be black

パブリックプロパティを割り当てる場合は、コンストラクターを次のように定義できます。

var color = 'black';

function Box()
{
   // public property
   this.color = '';

   // private constructor 
   var __construct = function(that) {
       alert("Object Created.");
       that.color = 'green';
   }(this)

   // getter
   this.getColor = function() {
       return this.color;
   }

   // setter
   this.setColor = function(color) {
       this.color = color;
   }

}

var b = new Box();

alert(b.getColor()); // should be green

b.setColor('orange'); 

alert(b.getColor()); // should be orange

alert(color); // should be black

45
これが一番の答えではないのはなぜですか?Jonだけがパラメータを使用してコンストラクタを作成しました。
ラップ

1
コンストラクターのこのパラダイムを使用して継承の例を取得する方法はありますか?
Nathan C. Tresch

1
@Rap Jonのコンストラクターの例にはBox()関数なのでパラメーターはありません:)。ただし、この例と他の回答の例は、パラメータを受け入れるように簡単に拡張できます。
Alexander Stepaniuk

2
@AndersonGreenでは、Boxにパラメーターを追加し、それを関数パラメーターとしてプライベートコンストラクターに渡すことができます。
Gautham C. 2013

1
「プライベートコンストラクタ」は必要ありません。Box関数で構築を行うだけで、準備は完了です(まだ「プライベート」です)。JavaScriptの「プライベート」は、字句スコープを介してアクセスできることを意味します。メンバーに割り当てる必要はありません。さらに、このコードは間違っています。これはグローバル__construct変数を作成しますが、これはかなり悪いです。varの範囲を制限するために使用する必要があり__constructます。
mattbasta 2013年

23

それでは、「コンストラクタ」プロパティのポイントは何ですか?どこに役立つかわからない、アイデアはありませんか?

コンストラクタープロパティのポイントは、JavaScriptにクラスがあるかのように見せかける方法を提供することです。オブジェクトを作成した後でオブジェクトのコンストラクターを変更することは、便利にできないことの1つです。それは複雑です。

私は数年前にかなり包括的な記事を書きました:http : //joost.zeekat.nl/constructors-considered-mildly-confusing.html


ポイントは、「新しい」キーワードを使用することです。「d = new Drofto()」は空のオブジェクトを作成し、「this」としてバインドされた新しいオブジェクトを使用してDrofto関数を実行します。Drofto関数は何でも自由に返すことができますが、Droftoクラスのメンバーと見なされるものを返すのが通例です。
Juan Lanus 14

16

ここに例:http : //jsfiddle.net/FZ5nC/

このテンプレートを試してください:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Name = Name||{};
Name.Space = Name.Space||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Name.Space.ClassName = function Name_Space_ClassName(){}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Name.Space.ClassName.prototype = {
  v1: null
 ,v2: null
 ,f1: function Name_Space_ClassName_f1(){}
}

//============================================================
// Static Variables
//------------------------------------------------------------
Name.Space.ClassName.staticVar = 0;

//============================================================
// Static Functions
//------------------------------------------------------------
Name.Space.ClassName.staticFunc = function Name_Space_ClassName_staticFunc(){
}
</script>

静的クラスを定義する場合は、名前空間を調整する必要があります。

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
Shape.Rectangle = Shape.Rectangle||{};
// In previous example, Rectangle was defined in the constructor.
</script>

クラスの例:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};

//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Shape.Rectangle = function Shape_Rectangle(width, height, color){
    this.Width = width;
    this.Height = height;
    this.Color = color;
}

//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Shape.Rectangle.prototype = {
  Width: null
 ,Height: null
 ,Color: null
 ,Draw: function Shape_Rectangle_Draw(canvasId, x, y){
    var canvas = document.getElementById(canvasId);
    var context = canvas.getContext("2d");
    context.fillStyle = this.Color;
    context.fillRect(x, y, this.Width, this.Height);
 }
}

//============================================================
// Static Variables
//------------------------------------------------------------
Shape.Rectangle.Sides = 4;

//============================================================
// Static Functions
//------------------------------------------------------------
Shape.Rectangle.CreateSmallBlue = function Shape_Rectangle_CreateSmallBlue(){
    return new Shape.Rectangle(5,8,'#0000ff');
}
Shape.Rectangle.CreateBigRed = function Shape_Rectangle_CreateBigRed(){
    return new Shape.Rectangle(50,25,'#ff0000');
}
</script>

インスタンス化の例:

<canvas id="painting" width="500" height="500"></canvas>
<script>
alert("A rectangle has "+Shape.Rectangle.Sides+" sides.");

var r1 = new Shape.Rectangle(16, 12, "#aa22cc");
r1.Draw("painting",0, 20);

var r2 = Shape.Rectangle.CreateSmallBlue();
r2.Draw("painting", 0, 0);

Shape.Rectangle.CreateBigRed().Draw("painting", 10, 0);
</script>

関数はAB =関数A_B()として定義されています。これは、スクリプトをデバッグしやすくするためです。Chromeの[要素の検査]パネルを開き、次のスクリプトを実行して、デバッグバックトレースを展開します。

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Fail = Fail||{};

//============================================================
// Static Functions
//------------------------------------------------------------
Fail.Test = function Fail_Test(){
    A.Func.That.Does.Not.Exist();
}

Fail.Test();
</script>

例を追加しました。デバッグ出力の改善に関する情報も追加されました。
bitlather 2013年

1
おそらくそれは問題に不必要なレベルの複雑さを追加するためです。わかりやすい名前の間隔と静的クラス宣言のため、投稿で答えを見つけるのは困難です。誤解しないでください。それは良い情報ですが、理解に足を踏み入れようとしている場合は、役立つよりも混乱するでしょう。私はJSの能力が中程度で、あなたがここで何をしているのか、または「コンストラクターの方法」に関連する理由をほとんど理解していません。
Bmo

1
洞察をありがとう、Bmo。長い記事でしたが、それは、明確に定義されたオブジェクトと静的クラスの実装に関連付けられていないコンストラクターの使用を理解していないためです。C ++またはJavaを学ぶときは、コンストラクターを実装する方法とともにクラスを実装する方法を学ぶ必要があります。このJavaScriptの記述方法に出会って以来、Web開発はずっと楽しくなり、共有したかっただけです。見つけやすいようにフィドルを上に移動しました。混乱が解消されることを願っています。
bitlather 2013

1
@Bmo名前空間についての2行で、特に下にあるコンストラクターを見つけるのが難しいと真剣に考えていますか?名前空間を使用した例を提供することは非常に歓迎されます。JavaScript開発コミュニティは名前空間を盲目的に無視するため、名前が衝突したときにエラーを見つけるのが難しくなります。js開発者がインターネット上の投稿からテキストの一部をコピーして、必要な作業と同様のことを行うかどうかを考えるのは悲しいことです。
user3285954 2015年

1
jsとWeb開発一般の主な問題は、開発者のほとんどが、業界が50年以上にわたって作成したすべてのプラクティスを無視し、彼らがajaxコールを実行できるかどうかを考えることです。JavaScriptでよく知られたパターンとプラクティスを使い始めるのに非常に長い年月がかかったことを見て、とても悲しいです。
user3285954 2015年

10

これはコンストラクタです:

function MyClass() {}

あなたがするとき

var myObj = new MyClass();

MyClass が実行され、そのクラスの新しいオブジェクトが返されます。


1
明確に言うalert(valuePassedInAsArgument);と、これが意味するのはクラスの最上位であり、これはインスタンス化ごとに1回実行されるため、クラス全体がコンストラクタ自体になります。
マーティン・ライン

new object is returned of that class-その関数から新しいオブジェクトが返されるようなものではありませんか?
Don Cheadle 2015

javascriptの関数はオブジェクトです
Leo

8

このチュートリアルはとても役に立ちました。このアプローチは、ほとんどのjQueryプラグインで使用されています。

http://www.htmlgoodies.com/html5/tutorials/create-an-object-oriented-javascript-class-constructor.html#fbid=OVYAQL_TDpK

var Class = function(methods) {   
    var klass = function() {    
        this.initialize.apply(this, arguments);          
    };  

    for (var property in methods) { 
       klass.prototype[property] = methods[property];
    }

    if (!klass.prototype.initialize) klass.prototype.initialize = function(){};      

    return klass;    
};

さて、

var Person = Class({ 
    initialize: function(name, age) {
        this.name = name;
        this.age  = age;
    },
    toString: function() {
        return "My name is "+this.name+" and I am "+this.age+" years old.";
    }
}); 

var alice = new Person('Alice', 26);
alert(alice.name); //displays "Alice"
alert(alice.age); //displays "26"
alert(alice.toString()); //displays "My name is Alice and I am 26 years old" in most browsers.
//IE 8 and below display the Object's toString() instead! "[Object object]"

10
人々が使用しているのを見るたびに私はklass
うんざり

8

このパターンは私に役立ちました。このパターンでは、クラスを個別のファイルに作成し、「必要に応じて」アプリ全体にロードします。

// Namespace
// (Creating new if not instantiated yet, otherwise, use existing and just add to it)
var myApp = myApp || {};

// "Package" 
// Similar to how you would establish a package in other languages
(function() {

// "Class"
var MyClass = function(params) {
    this.initialize(params);
}

    // "Private Static" vars 
    //    - Only accessible to functions in this class.
    //    - Doesn't get wiped out when we create a new instance.
    var countInstances = 0;
    var allInstances = [];

    // "Private Static" functions 
    //    - Same as above, but it's a function accessible 
    //      only to other functions in this class.
    function doSomething(){
    }

    // "Public Static" vars
    //    - Everyone has access.
    //    - Doesn't get wiped out when we create a new instance.
    MyClass.counter = 0;

    // "Public Static" functions
    //    - Same as above, but anyone can call this "static method".
    //    - Kinda like a singleton class situation.
    MyClass.foobar = function(){
    }

    // Public properties and methods are built into the "prototype"
    //    - This is how each instance can become unique unto itself.
    //    - Establishing "p" as "local" (Static Private) variable 
    //      simply so we don't have to keep typing "MyClass.prototype" 
    //      for each property and function.
var p = MyClass.prototype;

    // "Public" vars
    p.id = null;
    p.firstname = null;
    p.lastname = null;

    // "Private" vars
    //    - Only used by "this" instance.
    //    - There isn't "true" privacy for each 
    //      instance so we have to fake it. 
    //    - By tradition, we indicate "privacy"  
    //      by prefixing it with an underscore. 
    //    - So technically, anyone can access, but we simply 
    //      don't tell anyone about it (e.g. in your API)
    //      so no one knows about it :)
    p._foo = null;

    p.initialize = function(params){
        this.id = MyClass.counter++;
        this.firstname = params.firstname;
        this.lastname = params.lastname;
        MyClass.counter++;
        countInstances++;
        allInstances.push(this);
    }

    p.doAlert = function(theMessage){
        alert(this.firstname + " " + this.lastname + " said: " + theMessage + ". My id:" + this.id + ".  Total People:" + countInstances + ". First Person:" + allInstances[0].firstname + " " + allInstances[0].lastname);
    }


// Assign class to app
myApp.MyClass = MyClass;

// Close the "Package"
}());

// Usage example:
var bob = new myApp.MyClass({   firstname   :   "bob",
                                lastname    :   "er"
                            });

bob.doAlert("hello there");

これらはインスタンス変数ですが、C ++やJavaのような「プライベート」ではなく、「パブリック」のアクセシビリティがあります。
Potatoswatter

インスタンスに関連しているが、すべてのインスタンスに共通ではないプライベート変数(クラシックな意味で)をどのように作成しますか?
ボブは2013年

Douglas Crockfordのサイトをご覧ください。彼は言語デザイナーの1人であり、第一人者です。私はいつも彼のパターンに従うわけではありませんが、一般にプライベート変数はvarコンストラクター(または関数の引数、またはコンストラクターのような関数)のローカル変数です。
Potatoswatter

先端をありがとう...次のページは私が探していたものを説明します:javascript.crockford.com/private.html
ボブ

ああ、リンクをテストしないでごめんなさい:P
Potatoswatter


6

誰もまだクロージャーを使用していないので、私はJavaScriptクロージャーで何をするかを投稿するでしょう。

var user = function(id) {
  // private properties & methods goes here.
  var someValue;
  function doSomething(data) {
    someValue = data;
  };

  // constructor goes here.
  if (!id) return null;

  // public properties & methods goes here.
  return {
    id: id,
    method: function(params) {
      doSomething(params);
    }
  };
};

このソリューションへのコメントと提案は大歓迎です。:)


1
いくつかのコメント:1)(!id)が安全でない場合のステートメント、0やfalseなどの値はtrueと評価し、nullを返します。未定義またはnullをチェックする場合は、=== nullおよび=== undefinedの方が良いと思います。2)これは、コンストラクターと比較してモジュールパターン(apachelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth)によく似ています。違いは、モジュールが関数からオブジェクトを返すのに対し、コンストラクターはオブジェクトを作成するときです。新しいキーワードと組み合わせると、オブジェクトの代わりに「this」に値を設定することになります。
リッチ

4

上記のニックのサンプルを使用すると、オブジェクト定義の最後のステートメントとしてreturnステートメントを使用して、パラメーターなしでオブジェクトのコンストラクターを作成できます。以下のようにコンストラクター関数を返すと、オブジェクトを作成するたびに__constructでコードが実行されます。

function Box()
{
   var __construct = function() {
       alert("Object Created.");
       this.color = 'green';
   }

  this.color = '';

   this.getColor = function() {
       return this.color;
   }

   __construct();
}

var b = new Box();

1
コンストラクタ関数を返すのではなく、単に呼び出すだけです。
David Conrad

this.getColor();上記の行で使用しようとすると、alert("Object Created.");何も警告されません。「getColor is not defined」のようなエラーが発生します。オブジェクト内の他のメソッドを呼び出せるようにしたい場合は、他のすべてのメソッドの後にそれを定義する必要があります。したがって__construct();、最後の行を呼び出す代わりに、その下に構成を定義し、()その後に配置して強制的に自動実行させます。
thinsoldier 2013年

補正。()__construct定義の最後に追加しても、エラーが発生しました。__construct();エラーを回避するには、元のコードのように独自の行を呼び出す必要がありました。
thinsoldier 2013年

4

多分それは少し簡単になりましたが、以下は私が2017年に今思いついたものです:

class obj {
  constructor(in_shape, in_color){
    this.shape = in_shape;
    this.color = in_color;
  }

  getInfo(){
    return this.shape + ' and ' + this.color;
  }
  setShape(in_shape){
    this.shape = in_shape;
  }
  setColor(in_color){
    this.color = in_color;
  }
}

上記のクラスを使用すると、次のようになります。

var newobj = new obj('square', 'blue');

//Here, we expect to see 'square and blue'
console.log(newobj.getInfo()); 

newobj.setColor('white');
newobj.setShape('sphere');

//Since we've set new color and shape, we expect the following: 'sphere and white'
console.log(newobj.getInfo());

ご覧のとおり、コンストラクターは2つのパラメーターを受け取り、オブジェクトのプロパティを設定します。また、setter関数を使用してオブジェクトの色と形を変更しgetInfo()、これらの変更後に呼び出してもオブジェクトの変更が残っていることを証明します。

少し遅れますが、お役に立てば幸いです。私はこれをmocha単体テストでテストしましたが、うまく機能しています。


3

Typescript -MicroSoftのオープンソースを使用している場合は、次のようになります。

class BankAccount {
 balance: number;
 constructor(initially: number) {
 this.balance = initially;
 }
 deposit(credit: number) {
 this.balance += credit;
 return this.balance;
 }
}

Typescriptを使用すると、javascript構成にコンパイルされるOO構成を「偽造」できます。大規模なプロジェクトを開始する場合は、多くの時間を節約でき、マイルストーン1.0バージョンに到達しました。

http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf

上記のコードは次のように「コンパイル」されます。

var BankAccount = (function () {
    function BankAccount(initially) {
        this.balance = initially;
    }
    BankAccount.prototype.deposit = function (credit) {
        this.balance += credit;
        return this.balance;
    };
    return BankAccount;
})();

私は大規模なプロジェクトに取り組んでおり、TypeScriptが実行中の撮影を提供することを人々に納得させようとしています。それがどうなるか見てみましょう。
wootscootinboogie

@wootscootinboogie 1日で(現在は午前5時30分に終了します)、かなり遠くにあり、とても快適に過ごしています。仕様を一読することを強くお勧めします。本当の骨の折れるものの半分はスキップできますが、少なくとも一度は自分で仕様を読むことをお勧めします。この男のビデオは素晴らしいyoutube.com/user/basaratali/videosです。
がんばろう

1

JavaScriptでは、呼び出しタイプが関数の動作を定義します。

  • 直接呼び出し func()
  • オブジェクトのメソッド呼び出し obj.func()
  • コンストラクターの呼び出しnew func()
  • 間接呼び出しfunc.call()またはfunc.apply()

この関数は、演算子を使用して呼び出すときにコンストラクターとして呼び出されnewます。

function Cat(name) {
   this.name = name;
}
Cat.prototype.getName = function() {
   return this.name;
}

var myCat = new Cat('Sweet'); // Cat function invoked as a constructor

JavaScriptのインスタンスオブジェクトまたはプロトタイプオブジェクトにはconstructor、コンストラクタ関数を参照するプロパティがあります。

Cat.prototype.constructor === Cat // => true
myCat.constructor         === Cat // => true

コンストラクタプロパティについては、この投稿を確認してください。


0

上記のBlixtの優れたテンプレートを使用していると、マルチレベルの継承(MyGrandChildClassがMyChildClassを拡張し、MyClassを拡張する)ではうまく機能しないことがわかりました。したがって、簡単な回避策は次のとおりです。マルチレベルの継承が必要な場合は、次のように定義されたチェーン関数をthis.constructor.super.call(this, surName);使用する代わりにchainSuper(this).call(this, surName);

function chainSuper(cls) {
  if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;
  var depth = cls.__depth;
  var sup = cls.constructor.super;
  while (depth > 1) {
    if (sup.super != undefined) sup = sup.super;
    depth--;
  }
  return sup;
}

0

http://www.jsoops.net/は、JSでのoopに非常に適しています。プライベート、保護、パブリック変数と関数、および継承機能を提供する場合。コード例:

var ClassA = JsOops(function (pri, pro, pub)
{// pri = private, pro = protected, pub = public

    pri.className = "I am A ";

    this.init = function (var1)// constructor
    {
        pri.className += var1;
    }

    pub.getData = function ()
    {
        return "ClassA(Top=" + pro.getClassName() + ", This=" + pri.getClassName()
        + ", ID=" + pro.getClassId() + ")";
    }

    pri.getClassName = function () { return pri.className; }
    pro.getClassName = function () { return pri.className; }
    pro.getClassId = function () { return 1; }
});

var newA = new ClassA("Class");

//***Access public function
console.log(typeof (newA.getData));
// function
console.log(newA.getData());
// ClassA(Top=I am A Class, This=I am A Class, ID=1)

//***You can not access constructor, private and protected function
console.log(typeof (newA.init));            // undefined
console.log(typeof (newA.className));       // undefined
console.log(typeof (newA.pro));             // undefined
console.log(typeof (newA.getClassName));    // undefined

0

ちょうどいくつかの種類を提供するために。ds.oopは、JavaScriptでコンストラクターを使用してクラスを宣言するための優れた方法です。あらゆる種類の継承(c#でもサポートされていない1型を含む)だけでなく、インターフェイスもサポートしています。

var Color = ds.make.class({
    type: 'Color',
    constructor: function (r,g,b) { 
        this.r = r;                     /* now r,g, and b are available to   */
        this.g = g;                     /* other methods in the Color class  */
        this.b = b;                     
    }
});
var red = new Color(255,0,0);   // using the new keyword to instantiate the class

0

ここでは、Javaスクリプトの1つの点に注意する必要があります。これはクラスのない言語ですが、Javaスクリプトの関数を使用してそれを実現できます。これを実現する最も一般的な方法は、Javaスクリプトで関数を作成し、新しい キーワードを使用してオブジェクトを作成し、この キーワードを使用してプロパティとメソッドを定義する必要があります。以下に例を示します。

// Function constructor

   var calculator=function(num1 ,num2){
   this.name="This is function constructor";
   this.mulFunc=function(){
      return num1*num2
   };

};

var objCal=new calculator(10,10);// This is a constructor in java script
alert(objCal.mulFunc());// method call
alert(objCal.name);// property call

//Constructors With Prototypes

var calculator=function(){
   this.name="Constructors With Prototypes";
};

calculator.prototype.mulFunc=function(num1 ,num2){
 return num1*num2;
};
var objCal=new calculator();// This is a constructor in java script
alert(objCal.mulFunc(10,10));// method call
alert(objCal.name); // property call

-2

ほとんどの場合、この情報を渡すメソッドを呼び出す前に、何らかの方法で必要なプロパティを宣言する必要があります。最初にプロパティを設定する必要がない場合は、オブジェクト内でメソッドを呼び出すだけです。おそらくこれを行うには最もきれいな方法ではありませんが、これはまだ機能します。

var objectA = {
    color: ''; 
    callColor : function(){
        console.log(this.color);
    }
    this.callColor(); 
}
var newObject = new objectA(); 
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.