これは何百回も聞かれていることは知っていましたが、prototype
の概念を理解できないようです。
これが私のサンプルスクリプトです
var config = {
writable: true,
enumerable: true,
configurable: true
};
var defineProperty = function(obj, name, value) {
config.value = value;
Object.defineProperty(obj, name, config);
}
var man= Object.create(null);
defineProperty(man, 'sex', "male");
var person = Object.create(man);
person.greet = function (person) {
return this.name + ': Why, hello there, ' + person + '.'
}
var p=Object.getPrototypeOf(person);
alert(p.sex);//shows male
person.prototype.age=13;//why there is a error said the prototype is undefined? I thought it supposed be man object...
var child=function(){}
child.prototype.color="red";//why this line doesn't show error? both child and person are an object .
alert(child.prototype.color);//shows red
var ch=Object.getPrototypeOf(child);
alert(ch.color);//why it is undefined? it is supposed red.
あなたが私にいくつかの助けを与えることができることを願っています...ありがとう。
更新:
Elclanrsの回答に基づいて、皆さんの親切な助けに感謝します。以下は私が学んだことです。
Function
は、javascriptの組み込みオブジェクトの1つです。 3つのフォーマット作成関数オブジェクトは同じです。
var function_name = new Function(arg1, arg2, ..., argN, function_body)
function function_name(arg1, arg2, ..., argN)
{
...
}
var function_name=function(arg1, arg2, ..., argN)
{
...
}
したがって、プロトタイプチェーンを作成するには、関数を作成してから、新しいキーワードを使用して呼び出す必要があります。
Function.prototype
は、すべての関数オブジェクトprototype
への参照です。
乾杯
コンセプトを混ぜているのではないかと思います。最初に、古典的なプロトタイプの継承を使用してプロトタイプの概念を把握してみてください。そうすれば、すべての新しいObject
に取り掛かることができます。
JavaScriptでは、すべてのオブジェクト(数値、文字列、オブジェクト、関数、配列、正規表現、日付など)にはprototype
があり、これは-に共通のメソッド(関数)のコレクションと考えることができます。 allそのオブジェクトの現在および将来のインスタンス。
プロトタイプチェーンを作成するには、関数を作成し、それをnew
キーワードで呼び出して、コンストラクターであることを指定する必要があります。コンストラクターは、オブジェクトの新しいインスタンスを構築するために必要なパラメーターを受け取るメイン関数と考えることができます。
これを念頭に置いて、ネイティブオブジェクトを拡張したり、独自の新しいプロトタイプチェーンを作成したりできます。これはクラスの概念に似ていますが、実際にははるかに強力です。
あなたの例と同様に、次のようなプロトタイプチェーンを書くことができます。
// Very basic helper to extend prototypes of objects
// I'm attaching this method to the Function prototype
// so it'll be available for every function
Function.prototype.inherits = function(parent) {
this.prototype = Object.create(parent.prototype);
}
// Person constructor
function Person(name, age, sex) {
// Common to all Persons
this.name = name;
this.age = age;
this.sex = sex;
}
Person.prototype = {
// common to all Persons
say: function(words) {
return this.name +'says: '+ words;
}
};
// Student constructor
function Student(name, age, sex, school) {
// Set the variables on the parent object Person
// using Student as a context.
// This is similar to what other laguanges call 'super'
Person.call(this, name, age, sex);
this.school = school; // unique to Student
}
Student.inherits(Person); // inherit the prototype of Person
var mike = new Student('Mike', 25, 'male', 'Downtown'); // create new student
console.log(mike.say('hello world')); //=> "Mike says: hello world"
新しいバージョンのJavaScript(EcmaScriptを読む)では、オブジェクトを処理して拡張するための新しい方法が追加されました。しかし、それは古典的なプロトタイプの継承とは少し異なり、より複雑に見えます。JSがどのように機能するかについての知識があれば、それがどのように機能するかを本当に理解するのに役立ちます。さらに、古いブラウザーでは機能しません。そのため、インターネット上で正確で豊富な情報を見つけることができる古典的なパターンから始めることをお勧めします。
prototype
プロパティは関数にのみ存在し、person
は関数ではありません。 object
です。
何が起こっているのか:
_var man = Object.create(null); // man (object) -> null
man.sex = "male";
var person = Object.create(man); // person (object) -> man (object) -> null
person.greet = function () { ... };
var p = Object.getPrototypeOf(person); // man (object) -> null
alert(p.sex); // p is the same object as man
person.prototype.age = 13; // person doesn't have a prototype
var child = function () {}; // child (function) -> Function.prototype
// -> Object.prototype -> null
child.prototype.color = "red"; // child has a prototype
var ch = Object.getPrototypeOf(child); // Function.prototype
alert(ch.color); // ch is not the same as color.prototype
// ch is Function.prototype
_
詳細については、この回答を読むことをお勧めします: https://stackoverflow.com/a/8096017/78374
編集:何が起こっているのかをできるだけ少ない言葉で説明するには:
JavaScriptのすべては、プリミティブ値(ブール値、数値、文字列)、およびnull
とundefined
を除くオブジェクトです。
すべてのオブジェクトには、プログラマーがアクセスできない_[[proto]]
_というプロパティがあります。ただし、ほとんどのエンジンでは、このプロパティに___proto__
_としてアクセスできます。
_var o = { a: false, b: "something", ... }
_のようなオブジェクトを作成すると、_o.__proto__
_は_Object.prototype
_になります。
var o = Object.create(something)
のようなオブジェクトを作成すると、_o.__proto__
_はsomething
になります。
var o = new f(a, b, ...)
のようなオブジェクトを作成すると、_o.__proto__
_は_f.prototype
_になります。
JavaScriptがo
でプロパティを見つけることができない場合、JavaScriptは_o.__proto__
_でプロパティを検索し、次に_o.__proto__.__proto__
_などを検索して、プロパティが見つかるか、プロトチェーンがnull
(この場合、プロパティはundefined
です)。
最後に、Object.getPrototypeOf(o)
は_o.__proto__
_を返しますが_o.prototype
_は返しません-___proto__
_は関数を含むすべてのオブジェクトに存在しますが、prototype
は関数にのみ存在します。