LoginSignup
11
11

More than 5 years have passed since last update.

JavaScriptのprototypeを試してみている

Posted at

Qiitaに疑問的なことを書いていいのかわからなかったけど、自分でそのうち調べるという備忘録的な意味も込めて書きます。(Object.createのサポート有無はとりあえずおいておく)

これを書いてる人のレベル

サイ本はまだ読んでません。
JavaScriptのprototypeというものを知ったその日に書いています。
C++やObjctive-Cなどは書けますが、JavaScriptは大層なのは書いたことがありません。

実行環境は、MacのOS X 10.9.4、の

/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc

jsc test.js

とか、そんな感じ。

疑問1

function MySuperClass() {
    this.a = 100;
    this.b = 300;
}

function MySubClass() {
    MySuperClass.call(this);
    this.a = 200;
    this.c = 300;
}

MySubClass.prototype =  Object.create(MySuperClass.prototype);
MySubClass.prototype.constructor = MySubClass;

var mySub = new MySubClass();

というコードがあったとして、

MySubClass.prototype = Object.create(MySuperClass.prototype);

MySubClass.prototype = MySuperClass.prototype;

じゃダメなのか?

もしかして、こう書いてしまうと、後述のMySubClass.prototype.FUNCTION を定義したときに、MySuperClass.prototype のものが上書きされてしまうのかも、と思ったけどそんなことは無かった。(以下がそれを試してみたコード)

function MyObjectCreate( sub, sup ) {
    var F = function() {};
    F.prototype = sup.prototype;
    sub.prototype = new F();
    sub.prototype.constructor = sub;
}

function MySuperClass() {
    this.a = 100;
    this.b = 300;

    MySuperClass.prototype.GetNum = function() {
        return 999;
    }
}

function MySubClass() {
    MySuperClass.call(this);
    this.a = 200;
    this.c = 300;

    MySubClass.prototype.GetNum = function() {
        return 777;
    }
}

MySubClass.prototype = MySuperClass.prototype;
MySubClass.prototype.constructor = MySubClass;

var mySub = new MySubClass();
print( mySub.GetNum() );  // 777

var mySuper = new MySuperClass();
print( mySuper.GetNum() ); // 999

疑問2

上記のコードで、

MySubClass.prototype.constructor = MySubClass;

が無くてもパッと見では同じように動作はする。

ただし、いろんなWebを参考にさせてもらうと、これが無いと MySubClass のコンストラクタ内での this は MySuperClass を指してしまう、らしい。
ということなのだけど、それで困るのがどういう時かわからない。。。

疑問3

function MySuperClass() {
    this.a = 100;
    this.b = 300;
}

MySuperClass.prototype.GetNum = function() {
    return 999;
}

function MySubClass() {
    MySuperClass.call(this);
    this.a = 200;
    this.c = 300;
}

MySubClass.prototype.GetNum = function() {
    return 777;
}

MySubClass.prototype = Object.create(MySuperClass.prototype);
MySubClass.prototype.constructor = MySubClass;

var mySub = new MySubClass();
print( mySub.GetNum() );  //999

mySub.GetNum() は777を返してほしかったけど、999 が返ってくるのは、
MySubClass.prototype = Object.create(MySuperClass.prototype);
によって、MySuperClass.prototype.GetNum が呼び出されるからなのか?
(勘だとたぶんそう)

疑問4

function MySuperClass() {
    this.a = 100;
    this.b = 300;

    MySuperClass.prototype.GetNum = function() {
        return 999;
    }
}

function MySubClass() {
    MySuperClass.call(this);
    this.a = 200;
    this.c = 300;

    MySubClass.prototype.GetNum = function() {
        return 777;
    }
}

MySubClass.prototype = Object.create(MySuperClass.prototype);
MySubClass.prototype.constructor = MySubClass;

var mySub = new MySubClass();
print( mySub.GetNum() );  //777

これだと、777が返ってくるのは、一度 MySuperClassのGetNumが定義されるが、MySubClass のコンストラクタで再度、MySubClass.prototype.GetNum が定義されメソッドが上書きされるからなのか?
(勘だとたぶんそう)

疑問5

上記の疑問4の推定が正しいとすると、メソッドをオーバーライドするときは、

function MyClass() {
    this.a = 100;
    this.b = 300;

}

MyClass.prototype.GetNum = function() {
    return 999;
}

ではなく

function MyClass() {
    this.a = 100;
    this.b = 300;

    MyClass.prototype.GetNum = function() {
        return 999;
    }
}

と、書かないとオーバーライドされないのではないか?
つまり、メソッドのオーバーライドを使いたいときは、後者の書き方で統一しないとダメなのではないか?

疑問6

そもそも、なにかを根本的に勘違いしている。ような気もする。。。


うーん、わからないことだらけ。。。
サイ本読もう。。。

11
11
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
11