7

私は実際にCrockfordのJavascriptを研究しています:良い部分です。私はJavaScriptを初めて使用するため、このコードがどのように機能するかを理解するのに苦労しています。

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

これが私が思うことです:

メソッド(オブジェクト内の関数)であるthisため、オブジェクトを指しFunctionますが、メソッド内からアクセスできるので、なぜオブジェクトを返す必要があるのでしょうか。私が正しい場合、thisこれは参照であり、ローカルコピーではないため、次のようになります。

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
};

同様に機能するはずです。

反対側から、JavaScriptでは、returnステートメントのない関数が戻りundefined、それをに割り当てますFunction.prototype.method

質問

戻る意味は何thisですか?


実例#1

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};
var add = function(a, b) {
    return a+b;
};

Function.method('add', add);
var f = function() {};

print(f.add(1,2));

Number.method('integer', function () {
        return Math[this < 0 ? 'ceil' : 'floor'](this);
        });

print((-10/3).integer());

出力:

-3 3


実施例#2

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
};

var add = function(a, b) {
    return a+b;
};

Function.method('add', add);
var f = function() {};

print(f.add(1,2));

Number.method('integer', function () {
        return Math[this < 0 ? 'ceil' : 'floor'](this);
        });

print((-10/3).integer());

出力:

-3 3

4

3 に答える 3

5

私は今日の午後、この質問をダグラス・クロックフォードにメールで送りました。彼の返事は次のとおりです。

F.method(a).method(b).method(c)

私は冗談ではありません。彼が書いたのはこれだけだった。

とにかく、彼の(不可解な)答えの私の個人的な解釈はチェーンメソッドの作成です:

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this; //This returns the same Function object into the chain below
};

var add = function (a, b) { return a+b; };
var sub = function (a, b) { return a-b; };
var mul = function (a, b) { return a*b; };
var div = function (a, b) { return a/b; };

Function.method('add', add).method('sub', sub).method('mul', mul).method('div', div);

つまり、一度に1行を使用して新しいメソッドを作成する代わりに、チェーン内の次のメソッドを前のオブジェクトの戻りオブジェクトに再適用するFunctionことができます。

この例では、チェーンは左から右に移動します

|Function|--method-->|add|--returns-->|Function|--method-->|sub|--returns-->|Function|--method-->|mul|--returns-->|Function|--method-->|div|-->returns-->|Function|
于 2011-02-11T20:37:55.787 に答える
5

説明させてください。私はその本を読んでいませんでしたが、ダグラス・クロックフォードのJavaScriptのClassical Inheritanceの記事には、Function.prototype.methodに関するその例に関連する重要な文が1つあります。

これを返します。値を返す必要のないメソッドを作成する場合、通常はこれを返すようにします。カスケードスタイルのプログラミングが可能です。

実際、私はその用語に精通していません。よく知られている用語は「FluentInterface」または「MethodChaining」だと思います。そのwikiページを読んでください。さまざまな言語の例があるので、理解できます。

PS。@Gianluca Bargelliは、Function.prototype.methodをこのように使用する例を提供するのが少し速かったので、回答には投稿しません。

アドオン:例の観点からどのように使用できるか:

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
}

Number.method('integer', function () {  // you add 'integer' method
        return Math[this < 0 ? 'ceil' : 'floor'](this);
        })
      .method('square', function () {  // you add 'square' method with help of chaining
        return this * this;
        });

console.info( (-10/3).integer().square() ); // <- again chaining in action

ご覧のとおり、integer()はNumberオブジェクトを返すため、次のように記述する代わりに、別のメソッドを呼び出すことができます。

var a = (-10/3).integer();
console.info( a.square() ); 

そして、それを使用する私の方法についてのいくつかの言葉、ほとんどの場合、私は「各メソッド-インデント付きの新しい行、私にとってこの方法はより読みやすい」と書くことを好みます。

Function.method('add', add)
        .method('sub', sub)
        .method('mul', mul)
        .method('div', div);

このようにして、どこから始めたかがわかり、「改行/インデント」は、そのオブジェクトをまだ変更していることを示します。長い行と比較してください:

Function.method('add', add).method('sub', sub).method('mul', mul).method('div', div);

または典型的なアプローチ:

Function.method('add', add);
Function.method('sub', sub);
Function.method('mul', mul);
Function.method('div', div);

ADDON2:通常、Javaコードなどのエンティティを操作するときは、このアプローチ(Fluentインターフェイスパターン)を使用します。

public class Person {
  private String name;
  private int age;
  ..

  public String getName() {
    return this.name;
  }

  public Person setName( String newName ) {
    this.name = newName;
    return this;
  }

  public int getAge() {
    return this.age;
  }

  public Person setAge( int newAge ) {
    this.age = newAge;
    return this;
  }

  ..
}

Personそれは私が簡単な方法でオブジェクトを構築することを可能にします:

Person person = new Person().setName("Leo").setAge(20);

一部の人々はそれを少し異なって、彼らはset/getに新しい種類のメソッドを追加し、それを呼び出しますwith

public class Person {
  private String name;
  private int age;
  ..

  public String getName() {
    return this.name;
  }

  public void setName( String newName ) {
    this.name = newName;
  }

  public Person withName( String newName ) {
    this.setName( newName ); // or this.name = newName; up to you
    return this;
  }

  public int getAge() {
    return this.age;
  }

  public void setAge( int newAge ) {
    this.age = newAge;
  }

  public Person withAge( int newAge ) {
    this.setAge( newAge ); // or this.age = newAge; up to you
    return this;
  }
  ..
}

これで、前の例は次のようになります。

Person person = new Person().withName("Leo").withAge(20);

このように、setメソッドの意味を変更しません(つまり、拡張しないので、ほとんどの開発者が期待するように機能します...少なくとも人々はそのsetメソッドが何かを返すことを期待していません;))。これらの特別な方法の興味深い点の1つは、自己文書化を失う可能性がありますが、使用すると読みやすさが向上します(たとえば、Person作成の場合のように、withName私たちが何をしているのかを正確に伝えることができます。

続きを読む:
FluentInterface-マーティンファウラーによるそのパターンの説明
PHPでのFluent Interfaces
The Weekly Source Code 14-Fluent Interface Edition-私は短くて、長所と短所(および他のリソースへのリンク)を見るのに十分です

于 2011-02-11T20:38:42.980 に答える
0

何を聞いているのか正確にはわかりませんが、何も返さないと、Function.prototype.methodに何も割り当てられません。魔女は、その文を役に立たなくしますね。

于 2011-02-11T10:26:59.870 に答える