1

私は Javascript の「クラス」を C スタイルで書く傾向があります。

C# (たとえば) では、これを行います。

public class Parent {
    // stuff
}

public class Child : Parent {
    // Protected and public stuff from Parent will be accessible
}

JSでは、例でprotoを使用してこれと同等のものを見つけました

var namespace = namespace || {};

namespace.Parent = function() {

    // Public variables
    self.pubVariable = "I am accessible";

    // Private variables
    var priVariable = "I'm not accessible outside of self";

    // ctor
    function self() {}

    return self;
}


namespace.Child = (function() {
    this.__proto__ = new namespace.Parent();

    // ctor
    function self() {}

    self.init = function() {
        // Prints the pubVariable
        console.log(pubVariable);
    };

    return self;

})($);

// Call it (statically)    
namespace.Child.init();

これは機能しますが、Webkit と Mozilla のみです。これはプロトタイプを使用して何とか達成できることを理解しましたが、方法がわかりません。アドバイスをいただければ幸いです。ありがとう!

4

2 に答える 2

6

親/子クラスの場合、私はこのようなことをします

// your parent class
var Parent = function() {

  // parent constructor
  console.log("parent constructor!");
  
  // some public properties
  this.foo = "foo";
  this.bar = "bar";

  // a private data member
  var secret = "123456";
};

// a parent function
Parent.prototype.something = function() {
  console.log("something!");
}

// your child class
var Child = function() {
  
  // call parent constructor
  Parent.call(this);    
  
  // child constructor
  console.log("child constructor!");

  // override bar
  this.bar = "override!";
};

// the magic!
// child prototype build from parent prototype
Child.prototype = Object.create(Parent.prototype, {constructor: {value: Child}});

使用例

var c = new Child();
c.something();
// => parent constructor!
// => child constructor!
// => something!

c.foo //=> "foo"
c.bar //=> "override!"

「名前空間」を使用している場合、概念は同じです。


編集

あなたのコメントごとに、ここに追加されたデモンストレーションがあります

var Foo = function(){};
Foo.prototype.hello = function(){ return "hello!"; };
var foo = new Foo();

// call our hello method
// this calls foo.__proto__.hello
foo.hello(); //=> "hello!"

// override `hello` method for this instance
foo.hello = function(){ return "こんにちは"; };

// call our hello method again
// this calls foo.hello because it is defined directly on our instance
// (it has a higher precedence in the lookup chain)
foo.hello(); //=> "こんにちは"

// remove the override
delete foo.hello;

// call our hello method again
// this goes back to calling foo.__proto__.hello
foo.hello(); //=> "hello!"

// remove the method prototype
delete Foo.prototype.hello

// call our hello method one last time
// spoiler: it's gone!
foo.hello(); //=> TypeError: Object [object Object] has no method 'hello'

ご覧のとおり、 を使用してインスタンスでメソッドを直接定義すると、この機能が失われますthis.something = function(){};。個人的には、柔軟性が増すため、プロトタイプでメソッドを定義することを好みます。このように、プロトタイプは本当に設計図のように機能します。定義済みのすべての動作が得られます。必要に応じて変更し、いつでもインスタンスごとに元に戻すことができます。


もう一つ

最後の例では、プロトタイプ メソッドとインスタンス メソッドのオーバーライドがありました。元のメソッドも呼び出す方法はありますか? どれどれ!

var Foo = function(){};
Foo.prototype.hello = function(){ return "hello!"; };

var foo = new Foo();
foo.hello = function(){ return "こんにちは!"; }

// call override method
foo.hello(); //=> "こんにちは!"

// call original method
Foo.prototype.hello.call(foo); //=> "hello!"

// japanese just one more time...
foo.hello(); //=> "こんにちは!" 

これも機能しますが、実際に必要になることはありません。このように元のクラスを知る必要がないという利点があると思います:)

// call original method from the instance
foo.__proto__.hello.call(foo); //=> "hello!"

プロトタイプ!

于 2013-06-23T17:39:55.483 に答える