13

これが何百回も尋ねられていることは知っていますが、その概念を理解できないようです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の回答に基づいて、以下は私が学んだことです。

FunctionJavaScript の組み込みオブジェクトの 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)
{
...
}

そのため、関数を作成して new キーワードで呼び出す必要があるプロトタイプ チェーンを作成します。

Function.prototypeすべての関数オブジェクトへの参照prototypeです。

乾杯

4

2 に答える 2

13

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/783743

編集:何が起こっているのかをできるだけ少ない言葉で説明するには:

  1. JavaScript では、プリミティブ値 (ブール値、数値、および文字列)nullundefined.

  2. [[proto]]すべてのオブジェクトには、プログラマーがアクセスできないというプロパティがあります。ただし、ほとんどのエンジンでは、このプロパティを としてアクセスできるようにしてい__proto__ます。

  3. そのようなオブジェクトを作成するとvar o = { a: false, b: "something", ... }、.o.__proto__Object.prototype

  4. そのようなオブジェクトを作成するとvar o = Object.create(something)、.o.__proto__something

  5. そのようなオブジェクトを作成するとvar o = new f(a, b, ...)、.o.__proto__f.prototype

  6. JavaScript がプロパティを見つけられない場合、プロパティをo検索し、プロパティが見つかるかプロト チェーンが終了するまでo.__proto__(この場合、プロパティは です) を検索します。o.__proto__.__proto__nullundefined

  7. 最後に、Object.getPrototypeOf(o)return o.__proto__and not o.prototype-__proto__関数を含むすべてのオブジェクトに存在しますがprototype、関数にのみ存在します。

于 2013-01-27T07:22:48.103 に答える
10

私はあなたが概念を混ぜているかもしれないと思います。最初に古典的なプロトタイプの継承でプロトタイプの概念を把握してみてください。それから、すべての新しいObjectものに取り掛かることができます。

JavaScript では、すべてのオブジェクト (数値、文字列、オブジェクト、関数、配列、正規表現、日付など) には、そのオブジェクトの現在お​​よび将来のすべてのインスタンスにprototype共通するメソッド (関数) のコレクションと考えることができる があります。 .

プロトタイプ チェーンを作成するには、関数を作成し、それを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 がどのように機能するかについての知識があれば、それがどのように機能するかを本当に理解するのに役立ちます。また、古いブラウザーでは機能しません。そのため、インターネット上で正確で豊富な情報を見つけることができる古典的なパターンから始めることをお勧めします。

于 2013-01-27T07:28:36.100 に答える