JavaScriptタイプの場合、単純に要約することができます。強くタイプされた言語と比較して、それは弱い(ゆるい)タイプの言語です。基本的なタイプと参照タイプがあり、違いは、スタックメモリに固定スペースが存在し、実装場所へのポインターが固定スペースなしでスタックメモリに保存され、実装場所へのポインターがスタックメモリに保存されます。
市場に出回っている多くの本には、話すスペースがたくさんあります。この記事では、いくつかの側面について説明します。これにより、JavaScript、特にJavaScriptの種類を簡単に理解する必要がある場合があります。まだ理解していない場合は、JavaScriptに関する本を手に入れて、もう一度読むことができます。
1。基本型と参照タイプ
1。基本タイプ:未定義/null/boolean/number/string
2。参照タイプ:オブジェクト/配列/function/date/regexp/error/map/set…
参照タイプが列挙されていないのはなぜですか?あなたはそれについて多くを知っているだけなので、少なくとも記事で私はこれらについて十分であることについて話しました。他のものはめったに使用されない可能性があり、マップやセットのようなものでさえ、すべてのブラウザーによってサポートされていません。
2。JavaScriptタイプの判断
JavaScriptには、タイプを決定するために使用できる2つの演算子があります。それらはタイプとインスタンスですが、円は非常に小さく、それはあまり得意ではなく、信頼できないことで有名です。いくつかの状況も正しいですが、多くの場合、それらは信頼できません。それを見てください、そしてあなたは知っているでしょう:
コードコピーは次のとおりです。
//信頼できるとき:
typeof 'sofish' //文字列
new String( 'sofish')instanceof string // true
//信頼できない場合:
typeof [] //オブジェクト
typeof null //オブジェクト
文字列の「ソフィッシュ」インスタンス// false
ええと、多くの初心者JavaScriptプログラマーが誓うかもしれません。ほとんどの人は、JSを使用する必要がある場合、jQueryなどのライブラリをすでに持っています。それらはすべてそれらをカプセル化しているため、タイプを簡単に検出できます。もちろん、実際には、「JavaScriptではすべてがオブジェクトである」という文は、多くのドキュメントで述べたように、実際にはNANとInfinityの単なるグローバルな属性であるため、検出するのは面倒ではありません。あなたはおそらく知っています。しかし、「オブジェクト」は私たちを助けることができます:
コードコピーは次のとおりです。
/*オブジェクトタイプを検出します
* @param:obj {javascriptオブジェクト}
* @param:Type {string} jsタイプ名から始まる大文字
* @return:{boolean}
*/
関数は(obj、type){
return object.prototype.tostring.call(obj).slice(8、-1)=== type;
}
このようにして、IS関数を使用してタイプの判断を解決するのに役立ちます。この単純な関数には適切な互換性があり、プロジェクトで使用できます。状況は次のようです:
コードコピーは次のとおりです。
is( 'sofish'、 'string')// true
IS(null、 'null')// true
is(new set()、 'set')// true
3。JavaScriptタイプ変換
JavaScriptでは、変数のタイプ(プロパティ)を変更できます。あなたが見る最も一般的なことは、文字列と数の間の変換です。 1 + '2'を12に変える方法は?ここで +演算子を理解する必要があります。これは数学演算子であり、JavaScriptの弦楽式ハイフンでもあります。したがって、初心者はしばしば興味深い現象を見るでしょう。 +サインを使用する場合、計算が望むものではない場合がありますが、 - 記号を使用すると、いつでも「正しい」答えを得ることができます。
コードコピーは次のとおりです。
1 + '2' // '12'
1 +( + '2')// 3
1- '2' // -1
これは、実際には +の二重の役割によって引き起こされます。上記のコードでは、2番目の式が文字列の前にA +サインを使用していることに気付くことができ、クラスを数値に変換することを強制します。 JavaScriptのタイプの変換の理解に関しては、ほとんどの場合、理解するだけで十分です +は二重の役割を持っています。他の理解可能なクラス、同様のクラスは割り当て/過負荷で変更でき、エラーを含めることもできます。
コードコピーは次のとおりです。
var err = new error();
console.log(err instance of error); // 真実
err = 'sofish';
console.log(err); // 'sofish'
4。JavaScriptリファレンスタイプ
これはこの記事の難しいポイントです。基本的なタイプと比較して、参照はプロパティとメソッドをそれらに追加できます。参照は、参照タイプの値を変数に割り当てるのと同様の値であり、ヒープメモリに格納されているのと同じ値を指します。変数(プロパティ)は過負荷になる可能性がありますが、コピーは非常に興味深いことです。後で詳しく説明します。
1.プロパティとメソッドを追加します
次のコードで、基本的な同様の割り当てにエラーを報告しないと仮定すると、次のように無効になります。
コードコピーは次のとおりです。
var arr = [1,2,3];
arr.hello = 'world';
console.log(arr.hello); // '世界'
var str = 'sofish';
str.hello = 'world';
console.log(str.hello); // 未定義
2。型値を参照する操作
参照タイプはスタックメモリに保存されるため、同じ元の値を指すとき、値の操作はすべての参照に影響します。ここでの例は、再割り当て(値の直接操作ではない)がオブジェクトを再現し、元の値を変更しないことです。例えば:
コードコピーは次のとおりです。
var arr = [1,2,3]、sofish = arr;
sofish.push( 'hello world');
console.log(arr); // [1、2、3、 'Hello World']
//非麻痺タイプ
sofish = ['魚ではない']; // Sofishが同様に変更すると、元の値は変更されません
console.log(arr); // [1、2、3、 'hello world']]
3。参照型値のコピー
元の値の操作はすべての参照に影響しますが、これは必ずしも私たちが望むものではありません。操作中に他の参照に影響を与えることなく、真新しいオブジェクトをコピーする必要がある場合があります。一般に、日付 / function / regexpなどの特定の操作はほとんどありません。これは、主に配列とオブジェクトに追加のアイテム、属性などがあるためです。したがって、理解する必要があるのは、配列とオブジェクトオブジェクトをコピーする方法です。
3.1配列のコピー
配列オブジェクトには、スライスメソッドが存在して傍受された配列を返し、ES5フィルターなどで新しい配列を返します。そのため、この方法を使用してコピーできます。
コードコピーは次のとおりです。
var arr = [1、2、3];
var sofish = arr.slice();
//新しい配列の操作は元の配列に影響しません
sofish.push( 'hello world');
console.log(arr); // [1、2、3]
3.2オブジェクトのコピー
配列のコピーでは、スライス法を使用します。実際、配列とオブジェクトの場合、for ... in loopを使用してトラバースを送信してコピーする値を割り当てることができます。
コードコピーは次のとおりです。
var obj = {name: 'sofish'}、sofish = {}、p;
for(p in obj)sofish [p] = obj [p];
//新しいオブジェクトの操作は元の値に影響しません
sofish.say = function(){};
console.log(obj); // {name: 'sofish'}
3.3シャドウ/ディープコピー
上記の操作のように、それは私たちがしばしばShadowコピーと呼んでいるものです。ただし、配列とオブジェクトの両方に複数のレイヤー(寸法)があります。このようなコピーは、最上層の値のみを考慮に入れます。可能な値の配列とオブジェクトは、まだ元のオブジェクトを指します。例えば:
コードコピーは次のとおりです。
var arr = [1、{bio: 'not a fish'}]、sofish = []、p;
for(p in arr){
sofish [p] = arr [p];
}
//「sofish」に含まれるオブジェクト「cat」の操作は、元の値に影響します
sofish [1] .bio = 'hackable';
console.log(arr); // [1、cat:{bio: 'hackable'}]
それで、それをする方法は?この問題を解決するためにコピー()関数を使用しましょう。
コードコピーは次のとおりです。
/*オブジェクトをコピーします
* @param:obj {javaScriptオブジェクト}元のオブジェクト
* @param:isdeep {boolean}は深いコピーです
* @return:{JavaScriptオブジェクト}新しいオブジェクトを返します
*/
関数コピー(obj、isdeep){
var ret = obj.slice? []:{}、p、prop;
// IS関数で使用します
if(!isdeep && is(obj、 'array'))を返しますobj.slice();
for(p in obj){
if(!obj.hasownproperty(p))継続;
prop = obj [p];
ret [p] =(is(prop、 'object')||(prop、 'array'))?
copy(prop、isdeep):prop;
}
返品;
}
このようにして、コピー(OBJ、isDeep)関数を介して配列またはオブジェクトをコピーできます。あなたはそれをテストすることができます:
コードコピーは次のとおりです。
var arr = [1、{bio: 'not a Fish'}];
var sofish = copy(arr);
//浅いコピーは、最初のレイヤーの動作の元の値に影響しませんが、2番目のレイヤーに影響します
sofish.push( 'cat');
console.log(arr); // [1、{bio: 'not a Fish'}]
sofish [1] .bio = 'hello world';
console.log(arr)// [1、{bio: 'hello world'}]
//ディープコピーは元の値に影響しません
sofish = copy(arr、1);
sofish [1] .bio = 'foo or bar';
console.log(arr); // [1、{bio: 'hello world'}]
それでおしまい。基本的に、タイプに関するより難しいポイントを理解する必要があります。もちろん、複製は最も厄介なポイントです。しばしば操作を必要とする配列とオブジェクトに加えて、日付/関数/regexpの複製もあります。