Javascriptのに必要な遺産?
-
23-08-2019 - |
質問
I'beenって一部相jsためのいずれかを参照することになり、見るものに混乱させました。
知っていることを呼び出すときは、コンストラクタ関数の新しいキーワードに、新しいオブジェクトへの参照と関数の試作品です。
いることも分かっていることで、このために必要な継承に取り替えてくださの試作品のコンストラクタ関数のインスタンスオブジェクトする、"スーパークラス'.
なかったのでこんどうこれらのコンセプト
function Animal(){}
function Dog(){}
Animal.prototype.run = function(){alert("running...")};
Dog.prototype = new Animal();
Dog.prototype.bark = function(){alert("arf!")};
var fido = new Dog();
fido.bark() //ok
fido.run() //ok
console.log(Dog.prototype) // its an 'Object'
console.log(fido.prototype) // UNDEFINED
console.log(fido.constructor.prototype == Dog.prototype) //this is true
function KillerDog(){};
KillerDog.prototype.deathBite = function(){alert("AAARFFF! *bite*")}
fido.prototype = new KillerDog();
console.log(fido.prototype) // no longer UNDEFINED
fido.deathBite(); // but this doesn't work!
(こに開いているのがfirebugのコンソール)
1)なぜその場合すべての新しいオブジェクトへの参照を作成機能の試作fido.試作は定義されていません?
2)の遺チェーン[obj]->[コンストラクタ]->[試作]で[obj]->[試作]?
3)の試作特性のオブジェクト(fido)え?その場合...なぜ"deathBite'未定義です(最後の部)?
解決
1)なぜ、すべての新しいオブジェクトが含まれている場合 クリエイター関数の参照 プロトタイプは、fido.prototypeです 未定義?
すべての新しいオブジェクトは、構築時にそのコンストラクタ上に存在したプロトタイプへの参照を保持してください。それはコンストラクタ関数自体にあるしかし、この参照を格納するために使用されるプロパティ名がprototype
されていません。いくつかのJavascriptの実装では、他の人が(たとえばMicrosoftのために)ない__proto__
のようないくつかのプロパティ名を経由してこの「隠された」プロパティへのアクセスを許可しません。
> -2)[OBJ]継承鎖であり [コンストラクタ] - > [プロトタイプ]代わり [OBJ] - ?> [プロトタイプ]
はありません。これを見てください: -
function Base() {}
Base.prototype.doThis = function() { alert("First"); }
function Base2() {}
Base2.prototype.doThis = function() { alert("Second"); }
function Derived() {}
Derived.prototype = new Base()
var x = new Derived()
Derived.prototype = new Base2()
x.doThis();
これは、「第一」ではない第二に警告します。継承チェーンは、コンストラクタを介して行った場合、私たちは「第二」を参照してくださいます。オブジェクトが構築されるときに関数プロトタイププロパティに保持されている現在の基準は、そのプロトタイプのオブジェクトに隠れ参照に転送されます。
3)当社の「原型」プロパティであります オブジェクト(FIDO)は、これまでにチェックされていますか?もしそうなら... なぜ「deathBite」未定義(です 最後の部分)?
以前のオブジェクトは、プロパティ名を経由してそのプロトタイプへの参照を保持しません。述べたようにprototype
というプロパティは、特別な意味を持ちません(機能以外の)オブジェクトに割り当てます。
他のヒント
new
でインスタンス化されていたら、あなたは、オブジェクトのプロトタイプを変更することはできません。
あなたの例では、上記のような行
fido.prototype = new KillerDog();
単にオブジェクトprototype
上fido
という名前の新しい属性を作成し、新しいKillerDog
オブジェクトにその属性を設定します。これは、
fido.foo = new KillerDog();
あなたのコードは現状では...
// Doesn't work because objects can't be changed via their constructors
fido.deathBite();
// Does work, because objects can be changed dynamically,
// and Javascript won't complain when you use prototype
//as an object attribute name
fido.prototype.deathBite();
特別prototype
の動作では、コンストラクタはfunction
で呼び出されますnew
sあるJavaScriptでコンストラクタにのみ適用されます。
回答数ご質問:
- オブジェクトの試作性呼び出されることはありません
prototype
.標準使用[[prototype]]
を指定します。Firefoxこの物件の公共下の名前__proto__. - の継承チェーン
[obj]
⇒[prototype object]
.オリジナルの仮定([obj]
⇒[constructor]
⇒[prototype]
)の内容に誤りがあり、簡単に決までの変更constructor
および/またはconstructor.prototype
, 組み合わせれば、どのような方法で呼び出されるように、お[obj]
—するこれらの改造が変わらないものです。 prototype
物件オブジェクトのチェックと使用していません。設定できますので合わせてご利用いただけます。JavaScriptで使用する関数オブジェクトだけのオブジェクト。
を発揮#3では、コードから 道場:
dojo.delegate = dojo._delegate = (function(){
// boodman/crockford delegation w/ cornford optimization
function TMP(){}
return function(obj, props){
TMP.prototype = obj;
var tmp = new TMP();
if(props){
dojo._mixin(tmp, props);
}
return tmp; // Object
}
})();
誰でも参加でき、無料で入場でき活かし、この prototype
にのみ使用に再利用することにより、同じ機能 TMP
すべての委譲オブジェクトの異なるプロトタイプを作製。実際 prototype
割り当て直接のメソッドを呼び出す前に、機能 new
, で変化しないという影響を与えず作成したオブジェクト。
きのオブジェクトを作成配列の私の答え との関係[[試作]]-試作品JavaScript.
私は、継承を行うには良い方法があります、それはすでに回答されています知っているが。ただ、継承のためにコンストラクタを呼び出すことは望ましくありません。望ましくない影響の一つがある。
function Base() {this.a = "A"}
function Child() {this.b = "B"};
Child.prototype = new Base();
これであなたは「」あなたが意図していなかった子供のプロトタイプにプロパティを追加しました。
ここでは正しいやり方だ(私はこれを発明しなかったが、EXT-JSおよびその他のLIBSにはこれを使用)
// This is used to avoid calling a base class's constructor just to setup inheritance.
function SurrogateCtor() {}
/**
* Sets a contructor to inherit from another constructor
*/
function extend(BaseCtor, DerivedCtor) {
// Copy the prototype to the surrogate constructor
SurrogateCtor.prototype = BaseCtor.prototype;
// this sets up the inheritance chain
DerivedCtor.prototype = new SurrogateCtor();
// Fix the constructor property, otherwise it would point to the BaseCtor
DerivedCtor.prototype.constructor = DerivedCtor;
// Might as well add a property to the constructor to
// allow for simpler calling of base class's method
DerivedCtor.superclass = BaseCtor;
}
function Base() {
this.a = "A";
}
Base.prototype.getA = function() {return this.a}
function Derived() {
Derived.superclass.call(this); // No need to reference the base class by name
this.b = "B";
}
extend(Base, Derived);
// Have to set methods on the prototype after the call to extend
// otherwise the prototype is overridden;
Derived.prototype.getB = function(){return this.b};
var obj = new Derived();
さらに簡単な方法は、あなたが呼んで拡張して、プロトタイプにメソッドを追加する必要がないようにあなたが派生クラスのメソッドを指定する場所を拡張するために三番目のパラメータを追加することです。
extend(BaseCtor, DerivedCtor, {
getB: function() {return this.b}
});
そして、あなたは糖衣構文のために行うことができ、他の多くのものがあります。
それについてブログ:ます。http:// JS -bits.blogspot.com/2010/08/javascript-inheritance-done-right.htmlする
注目に値ECMAScript5(最新バージョンのJavaScript言語)までのアクセス内の[プロトタイプについて】●"プロパティのインスタンスによ Object.getPrototypeOf
:
Object.getPrototypeOf(fido) === Dog.prototype