【undersscoreソースの解読】JavaScriptでは、2つの要素が「同じ」かどうかを判断します.
4965 ワード
Why under score
最近はundersscore.jsのソースコードを見始めました.undersscore.jsのソースコードの解読を2016年の計画に入れました.
いくつかの有名な枠组みのソースコードを読むと、まるでみんなと対话するように、多くのことを学ぶことができます.なぜアンダースコアですか?最も主要な原因はアンダースコアが短くて精悍(約1.5 k行)で、100以上の有用な方法を実装しています.結合度が低く、一つ一つの方法で読むのに適しています.ビルのようなJavaScript初心者に適しています.そこから、void 0をundefinedの代わりに使って、undefinedを書き換えるなどのテクニックを身につけるだけでなく、変数型の判断や関数の節流や関数の手ぶれなど、よく使われる方法を学ぶことができます.また、多くのブラウザに対応するhackを学ぶことができます.また、作者の全体的な設計構想やAPI設計の原理(後方互換性)を学ぶことができます.
その後、スレ主は一連の文章を書いて、皆さんとソースの読み取りで学んだ知識を共有します. undersscore-1.8.3ソース解読プロジェクトの住所https://github.com/hanzichi/underscore-analysis undersscore-1.8.3ソースの全文コメントhttps://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/underscore-1.8.3-analysis.js undersscore-1.8.3ソース解読シリーズの文章https://github.com/hanzichi/underscore-analysis/issues いらっしゃいませ.(興味があれば、star&watchを歓迎します.)あなたの注目はビルの続けて書く動力です.
_.isequal
本文はJavaScriptの中でどのように二つのパラメータが「同じ」であるかを判断するか、すなわちunderscoreのソースコードの中の_.isequal方法この方法はunderscoreのソースコードの中で最も複雑な方法を実現すると言ってもいいです.
では、私が言っている「同じ」とはどういう意味ですか?栗を例に挙げると、
じゃ、これはどうデザインしますか?isEqual関数は?私達はundersscoreのソースコードに従って、一歩ずつその実現を見にきます.後の文では、比較した二つのパラメータはaとbと仮定します.
まず、
この部分のコードはこのように表してもいいです.
aとbの中にnullかundefinedがあれば、特別に判定して、比較を続けなくてもいいです.ソースの実現:
ok、続けます.これからはaとbのタイプによって判断します.もしタイプが違ったら、引き続き判断する必要がありません.変数の種類はどうやって取得しますか?そうです.不思議な
もしタイプがRegExpとStringなら、aとbをそれぞれ文字列に変えて比較できます.
そして、aとbがともにDateタイプまたはBooleanタイプであれば、
プログラムは続いて行って、私達は引き続き見て、まだ2種類の重要なタイプがあるようですが、判断していませんか?そう、ArayとObject!undersscoreはこれを再帰的な方法で展開して比較する.
やはり栗を挙げましょう.例を挙げると直感的です.
a,bを以下のように仮定する.
それとも上記の例で、私達はそれを三回に分けて比較して、それぞれ三つのkeyのvalueの値が同じかどうかを比較します.loveCityというkeyのvalueについては、そのvalueはまた配列であるため、このvalueを比較関数に導入し、この比較の結果、最後の比較結果を判断します.再帰はこのようにして、大きなものを一つずつ小さく分解し、小さな結果によって大きな結果をまとめます.
最後にコード位置を与えます.についてisEqualメソッドのソースコードは、みんなが参照することができます.https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/src/underscore-1.8.3.js#L1094-L 1190
最近はundersscore.jsのソースコードを見始めました.undersscore.jsのソースコードの解読を2016年の計画に入れました.
いくつかの有名な枠组みのソースコードを読むと、まるでみんなと対话するように、多くのことを学ぶことができます.なぜアンダースコアですか?最も主要な原因はアンダースコアが短くて精悍(約1.5 k行)で、100以上の有用な方法を実装しています.結合度が低く、一つ一つの方法で読むのに適しています.ビルのようなJavaScript初心者に適しています.そこから、void 0をundefinedの代わりに使って、undefinedを書き換えるなどのテクニックを身につけるだけでなく、変数型の判断や関数の節流や関数の手ぶれなど、よく使われる方法を学ぶことができます.また、多くのブラウザに対応するhackを学ぶことができます.また、作者の全体的な設計構想やAPI設計の原理(後方互換性)を学ぶことができます.
その後、スレ主は一連の文章を書いて、皆さんとソースの読み取りで学んだ知識を共有します.
_.isequal
本文はJavaScriptの中でどのように二つのパラメータが「同じ」であるかを判断するか、すなわちunderscoreのソースコードの中の_.isequal方法この方法はunderscoreのソースコードの中で最も複雑な方法を実現すると言ってもいいです.
では、私が言っている「同じ」とはどういう意味ですか?栗を例に挙げると、
1
とnew Number(1)
はequalとされ、[1]
と[1]
はequalとされています.もちろん、2つの参照は同じ対象です.じゃ、これはどうデザインしますか?isEqual関数は?私達はundersscoreのソースコードに従って、一歩ずつその実現を見にきます.後の文では、比較した二つのパラメータはaとbと仮定します.
まず、
a === b
と判断します.trueの場合は、aとbは基本タイプです.2つの基本タイプの値は同じです.2つは2つの参照タイプです.つまり、参照タイプの参照は同じです.a === b
がtrueなら、aとbはequalということですか?実は99%の場合は、0と0というスペシャリストcaseも考慮しなければなりません.0 === -0
はtrueです.0と-0はunequalとされています.原因は、参照できます.http://wiki.ecmascript.org/doku.php?id=harmony:egal. この部分のコードはこのように表してもいいです.
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
// a === b
// `0 === -0` special case
// 0 -0
//
if (a === b) return a !== 0 || 1 / a === 1 / b;
次の場合はa !== b
の場合です.aとbの中にnullかundefinedがあれば、特別に判定して、比較を続けなくてもいいです.ソースの実現:
// A strict comparison is necessary because `null == undefined`.
// a b null( undefined)
// a === b
if (a == null || b == null) return a === b;
個人的にはここに書いたのが少し余分だと思います.上の判断でフィルタリングしますので、a==bはfalseに戻ります.ok、続けます.これからはaとbのタイプによって判断します.もしタイプが違ったら、引き続き判断する必要がありません.変数の種類はどうやって取得しますか?そうです.不思議な
Object.prototype.toString.call
です.もしタイプがRegExpとStringなら、aとbをそれぞれ文字列に変えて比較できます.
var a = /a/;
var b = new RegExp("a");
console.log(_.isEqual(a, b)); // => true
実はアンダースコアの内部ではこう判断されています.var a = /a/;
var b = new RegExp("a");
var _a = '' + a; // => /a/
var _b = '' + b; // => /a/
console.log(_a === _b); // => true
Numberタイプなら?ここにまたspecial caseがあります.つまりNaNです.ここではNaNはNaNと同じだけで、他のNumberタイプとはunequalであると規定している.ここでは引用の種類を基本のタイプに変えます.次のコードを見てください.var a = new Number(1);
console.log(+a); // 1
そうです.+
を追加すれば解決されます.他のものは分かりにくくないです.全部注釈に入っています.// `NaN`s are equivalent, but non-reflexive.
// Object(NaN) is equivalent to NaN
// +a !== +a
// a NaN
// b NaN
if (+a !== +a) return +b !== +b;
// An `egal` comparison is performed for other numeric values.
// NaN
// 0
// +a Number()
// a 0, 1 / +a === 1 / b
// +a === +b
return +a === 0 ? 1 / +a === 1 / b : +a === +b;
// a Number
// NaN special number
// NaN NaN equal
次にDateとBooleanの二つのタイプを見ます.Numberタイプと同様に、+
を基本タイプの数字に変換することもできます.次のコードを見てくださいvar a = new Date();
var b = true;
var c = new Boolean(false);
console.log(+a); // 1464180857222
console.log(+b); // 1
console.log(+c); // 0
とても簡単です.実は+new Date()(または+new Dateとも書くことができます.)は現在の時間と1970年1月1日0時のミリ秒数(milisecond)を取得しています.タイムスタンプはこのデータを1000で割って、つまり秒数です.canvasでアニメを作る時、私はよく+new Dateをタイムスタンプとして使います.そして、aとbがともにDateタイプまたはBooleanタイプであれば、
+a === +b
を使ってequalかどうかを判断することができます.プログラムは続いて行って、私達は引き続き見て、まだ2種類の重要なタイプがあるようですが、判断していませんか?そう、ArayとObject!undersscoreはこれを再帰的な方法で展開して比較する.
やはり栗を挙げましょう.例を挙げると直感的です.
a,bを以下のように仮定する.
var a = {name: "hanzichi", loveCity: [{cityName: "hangzhou", province: "zhenjiang"}], age: 30};
var b = {name: "hanzichi", loveCity: [{cityName: "hangzhou", province: "zhenjiang"}], age: 25};
まずa、bは対象で、それぞれキーの値を比較してもいいです.もしキーの値が違うと(或いはキーの値がaとbに対して一つもないということです)、aとb unequalです.行列なら?一つの元素を比較します.配列はオブジェクトをネストすることができますので、オブジェクトのvalueは配列かもしれません.それとも上記の例で、私達はそれを三回に分けて比較して、それぞれ三つのkeyのvalueの値が同じかどうかを比較します.loveCityというkeyのvalueについては、そのvalueはまた配列であるため、このvalueを比較関数に導入し、この比較の結果、最後の比較結果を判断します.再帰はこのようにして、大きなものを一つずつ小さく分解し、小さな結果によって大きな結果をまとめます.
最後にコード位置を与えます.についてisEqualメソッドのソースコードは、みんなが参照することができます.https://github.com/hanzichi/underscore-analysis/blob/master/underscore-1.8.3.js/src/underscore-1.8.3.js#L1094-L 1190