7

以下のコード スニペットは、O'Reilly による「Javascript Web アプリケーション」からのものです。その中で、著者は、特に何か他のものを返さない限り、new通常、キーワードを使用するとthisコンテキストが返されると説明しています.

var Class = function(){
    var klass = function(){
        this.init.apply(this, arguments);
    };
    klass.prototype.init = function(){};
    return klass;
};

var Person = new Class;

Person.prototype.init = function(){
    // Called on Person instantiation
};

// Usage:
var person = new Person;

私はこれに従っていません。ここで戻るとは何をしklassますか?の場合var Person = new Class、新しいクラス オブジェクトを取得するのではなく、クラスを作成できる何らかの関数を取得しますか? 文面からそう読み取れますが、ややこしいです。

4

4 に答える 4

7

彼が行くところに着く前に、最初のステップは得ることthisです。

this通常、指摘できることが3つあります。オブジェクトのプロパティである関数がある場合:

var Bob = {
    name : "Bob",
    say  : function () { console.log(this.name); }
};

Bob.say(); // "Bob"

この場合、thisプロパティを所有しているオブジェクトを指します(関数が呼び出された瞬間に、1ドット先にあるものは何でも)

var say = Bob.say; // passing the function to a variable
var Sam = { name : "Sam" };
Sam.say = Bob.say; // passing the function to an object's property

say(); // undefined -- not what you were expecting
Sam.say(); // "Sam"

したがってthis、最後の可能な秒で決定されます。

関数には、オブジェクトのような独自のプロパティもあります。
これらのうちの2つはとと呼ばれる関数で.callあり.apply、関数を実行できますが、関数に正確に何thisであるかを伝えます。

say();それ自体ではどのように機能しなかったか覚えていますか?

var say = Bob.say;
say.call(Bob); // "Bob" -- hooray!

の次の部分thisは、オブジェクト指向言語で最も慣れている部分です。thisと一緒に使用しnewて、クラスの新しいインスタンスを作成します。

var Person = function (name) {
    this.name = name;
    this.say = function () { console.log(this.name); };
};

var bob = new Person("Bob");
bob.say(); // "Bob"

基本的に、このコンストラクター関数(またはコンストラクターはJSで特別ではないため、任意の関数)の内部では、関数newは呼び出されたかどうかを確認することから始まります。
そうであった場合はthis、オブジェクトの一部であるかどうかに関係なく、新しいオブジェクトに設定します。

var Creatures = {};
Creatures.Person = Person;

Creatures.Person("Bob"); // `this` === Creatures
Creatures.name; // "Bob" -- whoops
var bob = new Creatures.Person("Bob");
bob.say(); // "Bob", yay!

if (new) { this = {}; }つまり、関数が関数の上部で言っているようなものです。

私は3つの可能性があると言いました。
3つ目は、がオブジェクトではなく(call / applyを介して、またはオブジェクトのプロパティとして)、新しいオブジェクトの作成に使用されなかっthis === window
た関数を使用する場合、を指すことです。 そのため、以前は単独では機能しませんでした。同等です。thisnewthiswindow
say();window.say();

少し戻ってnew-new他のいくつかのことをします。
つまり、オブジェクトのコンストラクターの値を設定します。

var bob = new Person();
bob instanceof Person;  // true

また、そのコンストラクターから作成されたprototypeオブジェクトに、すべてのインスタンスが共有するオブジェクトへのアクセスを提供します。

では、Class/Klassの内部で何が起こっているかを見てみましょう。オブジェクト
を作成しています。関数 の内部(ので)。 次に、新しい「コンストラクター」関数を作成しています。 new Class();
Classthis = {};new
klass

次に、プロトタイプ化されinitた関数を設定します。これは.apply、新しいものに設定しますthis(でklass、新しいインスタンスが呼び出されたとき)。

次に、クラスを返します。

klassは、実際には、新しいクラスを作成するときに呼び出しているものです。

そして、クラスの新しいオブジェクトを呼び出すと、klassが実行されます。

newそれがandthis.callandに役立つことを願っていますClass/klass

于 2013-01-14T07:45:17.693 に答える
3

JavaScript では、newキーワードは暗黙的に を返しますthis

あなたが持っfunction Foo () {}て適用するnew Fooと、フードの下でjavascriptがこれを行いfunction Foo () { return this; }ます。new彼は、別のオブジェクト (klass オブジェクト) を明示的に返すことで、javascript の動作を上書きしています。

この例を見てください。

function Foo () { this.name = "foo"; };

function Bar () {
    return new Foo; 
};

var bar = new Bar;  // bar is now a Foo, because of the explicit return.

bar.name //=> 'foo'

それに従うことができれば、彼がしていることに従うことができます。

と言うとvar Person = new Class、実際には関数を返して変数(ポインタ)klassに格納しています。Person

于 2013-01-14T07:41:38.070 に答える
1

著者の論理に従ってください:

newキーワードを使用すると、特に何か他のものを返さない限りthis、通常はコンテキスト が返されます

彼/彼女が正しければ、次のコード:

var Class = function(){
    var klass = function(){
        this.init.apply(this, arguments);
    };
    klass.prototype.init = function(){};
    return klass;
};

「クラス」クラスを定義しません。代わりに、インスタンスnewを返す代わりに、 ed 時にメソッド ( )の実行が保証されるプライベートに定義されたクラスを返す「ベース」を定義します。newinit()this.init.apply(this)

その方法で、いつ

var Person = new Class;

という名前の新しいクラスを作成しています。これは、内部でPerson定義されている制約と動作 (存在する場合) に従います ( 「実際の」OOP では/のように見えます)。klassClassextendinherit

したがって、次のコード

Person.prototype.init = function(){
// Called on Person instantiation
};

実際にはclass の「コンストラクター」を定義していPersonます。

編集

昨日は適切な言葉や文章が思いつかなくてごめんなさい。表現が苦手です。

OOP に慣れている場合は、がインターフェイス/抽象/仮想クラスであり、インスタンスを作成する代わりに、内部で非公開/仮想的に定義された動作を拡張/継承/実装していることを想像できます。Classnew ClassClass

JS の抽象/仮想関数の方法のklass.prototype.init=function(){};ようなものであり、組み合わせるthis.init.apply(this)ことで、5 つのレベルでコンストラクターを想像することができます。

于 2013-01-14T07:47:30.560 に答える