4
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;

上記のコードが何をしているのか誰か教えてもらえますか?

4

2 に答える 2

4

それを分解しましょう:

Object.prototype

これにより、Object変数のプロトタイプであるJavaScriptオブジェクトが得られます。プロトタイプとは何ですか?イェフダ・カッツの優れたブログ投稿から引用させてください(一読する価値があります):

オブジェクトのキーを検索しようとしても見つからない場合、JavaScriptはプロトタイプでそのキーを検索します。null値が表示されるまで、「プロトタイプチェーン」に従います。その場合、undefinedを返します。

次に、次のようになります。

Object.prototype.toString

これにより、のプロトタイプのtoString関数が返されます。ObjectJavaScript関数は、そのcall関数を使用して呼び出すことができます。次にいくつかの例を示します。

Object.prototype.toString.call("foo")  # => "[object String]"
Object.prototype.toString.call(5)      # => "[object Number]"

つまり、基本的には単なる汎用のtoString関数であり、引数として指定したものをすべて説明する文字列を返しますcall。これらの例では、引数はオブジェクト自体であるため、オブジェクトとして自分自身を説明する文字列を返すことに注意してください。合格したらどうなりwindow.HTMLElementますか?

Object.prototype.toString.call(window.HTMLElement)  # => "[object HTMLElementConstructor]"

これで、サブ文字列を含む文字列が返されていることがわかります。これは"Constructor"、HTML要素を構成するオブジェクトである可能性が高いことを意味します。最後に、完全な表現を理解できます。

Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor')  # => 19

"Constructor"は部分文字列なので、> 0である19を返します。したがって、基本的に、この式は、サフィックス「コンストラクタ」を使用して自分自身を識別indexOfするかどうかをチェックするように見えます。これは、ブラウザの識別チェックの一種である可能性があります。window.HTMLElement

(注:これを書いている間、SafariのWeb Inspectorコンソールを使用してこれらの式の評価をテストしましたが、このようなテストにはChromeまたは他のブラウザーのコンソールを使用することもできます。)

于 2013-03-18T06:56:58.280 に答える
2
  • Objectjavascript の (ほぼ) すべての型が継承されるクラス (コンストラクター) です。
  • Object.prototypeほとんどすべてのオブジェクトのプロトタイプ チェーンに含まれるオブジェクトです。
  • Object.prototype.toStringオーバーライドしないオブジェクトで呼び出されるメソッドです。
  • .callは、関数で呼び出されると、最初の引数をコンテキストとして関数を呼び出します。func.call(a)に似ていa.func=func; a.func()ます。違いは whileundefined.toString()が でありTypeErrorObject.prototype.toString.call(undefined)完全に正常に動作することです。
  • HTMLElementHTML 要素の継承元のクラスです。ただし、これは仕様では要求されておらず、HTML 要素にプロトタイプがなく、HTMLElementコンストラクターが存在しない Internet Explorer には当てはまりません。windowはブラウザ環境のグローバル オブジェクトであるため、ローカル変数によってシャドウされていない場合と存在する場合window.HTMLElementは同じです。存在しない場合、読み取りはwhile を返します。HTMLElement HTMLElementReferenceErrorwindow.HTMLElementundefined
  • したがって、Object.prototype.toString.call(window.HTMLElement)IEHTMLElement.toString() 動作し、右のtoString. 常に を返しますString
  • indexOf-1部分文字列の最初の出現を検索し、部分文字列が存在しない場合に返す文字列関数です。.indexOf('Constructor') > 0は、文字列に が含まれていて、それで始まっていないかどうかを確認します"Constructor"

そのため、このメソッドは on で呼び出されたときにtoString含まれているかどうかを判断します。仕様では、次のことが義務付けられています。"Constructor"HTMLElement

...
4) class を O の [[Class]] 内部プロパティの値とします。
5) 3 つの文字列 "[object "、class、および "]" を連結した結果である文字列値を返します。

したがって、これは が であるかどうかをチェックしHTMLElementます。[[class]]Constructor

最後に、チェック結果が変数に割り当てられますisSafari。これは、どの環境でこれが当てはまるかを示しています。このコードの作成者は、戻り値が"Constructor"Safari、すべてのバージョンの Safari、および Safari のみに含まれていることを前提としています。

参考までに、Chrome では をObject.prototype.toString.call(HTMLElement)返します"[object Function]"

于 2013-03-18T07:07:49.463 に答える