7

前に「JavaScript ライブラリを作成する」方法を読んでいたときに、髪を引きちぎりたくなるようなコードに出くわしました。

これが私の脳を結び目にしたコードです:

if (window === this) {
    return new _(id);
}

_(id) は、このコードが含まれている関数名です。自分で調べる必要がある場合は、残りのコードを次に示します。

function _(id) {

// About object is returned if there is no 'id' parameter
var about = {
    Version: 0.5,
    Author: "Michael Jasper",
    Created: "Fall 2010",
    Updated: "23 November 2011"
};

if (id) {

    // Avoid clobbering the window scope:
    // return a new _ object if we're in the wrong scope
    if (window === this) {
        return new _(id);
    }

    // We're in the correct object scope:
    // Init our element object and return the object
    this.e = document.getElementById(id);
    return this;
  } else {
    // No 'id' parameter was given, return the 'about' object
    return about;
  }
};

「return new function」はこれまで見たことがありませんが、それがどのように機能するかを理解したいと思っています。

他のコード:

_.prototype = {
  hide: function () {
          this.e.style.display = 'none';
          return this;
  }

  show: function () {
           this.e.style.display = 'inherit';
           return this;
  }
};

このコードが _ オブジェクトに新しいメソッドを追加することは知っていますが、なぜ「これを返す」のでしょうか? なしで試してみましたが、うまくいきました。

最後に、記事へのリンクはhttp://www.mikedoesweb.com/2012/creating-your-own-javascript-library/です。

4

2 に答える 2

16

コードの最初のビットは、本質的に「コンストラクター」関数がどのように呼び出されたかを検出しようとしています...

JavaScript では、次の 2 つの方法で関数を使用してオブジェクトを作成できます。

function _(id) {
    this.someProperty = "stuff";
    //Do more stuff to "this"
    return this;
}

//in this scenario, the "this" object will be the window object
var myObject = _(id);
console.log(window.someProperty); //outputs "stuff";
console.log(myObject.someProperty); //outputs "stuff";

//in this scenario, the "this" object is what get's actually returned...
var myObject = new _(id);
console.log(window.someProperty); //outputs "undefined"
console.log(myObject.someProperty); //outputs "stuff"

したがって、

if (window === this) {
    return new _(id);
}

newキーワードなしで誤ってコンストラクターを呼び出さないようにするためです。windowオブジェクトに割り当てるプロパティはすぐに名前空間に割り当てられるため、これは悪いことです...これは悪いことです。


2 番目の質問については、作成者はreturn this;各メソッドの最後に流暢なインターフェイス デザイン パターンとして a を使用しています。

これにより、便利で見栄えの良いオブジェクト操作が可能になります。これの一般的な例はjQueryで、メソッドを1つのオブジェクトに連鎖させることができます...

$(".some-css-selector").click(function() { 
    ... do something to the selected objects during the "click" event
}).keyup(function() {
    ... do something to the same objects during the "keyup" event
});

編集: 以下の W3Geek のコメントに応じて、もう少し追加情報:

Douglas Crockford の本 "Javascript: The Good Parts" から (JS を始めようとしているなら、完全に良い読み物です... 70 ページほどしかありませんが、どれも読む価値があります)。


Javascript のnew演算子は、オペランドのプロトタイプ メンバーから継承する新しいオブジェクトを作成し、オペランドを呼び出して、新しいオブジェクトを にバインドしますthis。これにより、オペランド (コンストラクター関数の方がよい) は、新しいオブジェクトがリクエスターに返される前にカスタマイズする機会が与えられます。

`new 演算子を使用するのを忘れると、代わりに通常の関数呼び出しが行われ、これは new オブジェクトではなくグローバル オブジェクトにバインドされます。つまり、関数が新しいメンバーを初期化しようとすると、グローバル変数が上書きされます。それは非常に悪いことです。

...

コンストラクターは、newプレフィックスと共に使用するように設計された関数です。newプレフィックスは、関数のプロトタイプに基づいて新しいオブジェクトを作成し、そのオブジェクトを関数の暗黙のパラメーターにバインドしますthisnewプレフィックスの使用を怠ると、新しいオブジェクトは作成thisされず、グローバル オブジェクトにバインドされます。これは重大な間違いです。


于 2012-06-15T04:38:10.767 に答える
6

return thisメソッド呼び出しをチェーンする機能を提供します。など、本当にクールで便利なことができます_.show().hide()。:)

于 2012-06-15T04:24:56.543 に答える