ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScriptの基本型と参照型を簡単に分析_基礎知識

JavaScriptの基本型と参照型を簡単に分析_基礎知識

WBOY
WBOYオリジナル
2016-05-16 16:46:391183ブラウズ

JavaScript の型については、次のように簡単に要約できます。強く型付けされた言語と比較すると、弱い (緩やかな) 型付け言語であり、基本型と参照型があり、それらの違いは固定スペースがあることです。スタック メモリでは、不定の領域がヒープ メモリに保存され、実装場所へのポインタがスタック メモリに保存されます。

市販されている多くの本には、それについて語るスペースがたくさんあります。この記事では、JavaScript、特に JavaScript の種類についての基本的な理解を必要とするいくつかの側面について説明します。それでも理解できない場合は、この記事を読む前に JavaScript に関する本を手に取って読んでください。

1. 基本型と参照型

1. 基本型: Unknown/Null/Boolean/Number/String
2. 参照型: Object/Array/Function/Date/RegExp/Error/Map/Set…

なぜ参照型が列挙されていないのでしょうか?少なくともこの記事については、これだけ知っていれば十分だからです。その他はめったに使用されない可能性があり、Map や Set などもすべてのブラウザでサポートされているわけではありません。

2.JavaScriptの種類の判定

JavaScript には型を決定するために使用できる演算子が 2 つあります。これらは typeof と instanceof ですが、その範囲は非常に小さく、うまく混合できず、信頼性が低いことで有名です。正しい場合もありますが、多くの場合は信頼できません。ちょっと見てみると、次のことがわかります:

コードをコピー コードは次のとおりです:

// 信頼できる場合:
typeof ' sofish' // string
new String('sofish')instanceof String // true

// 信頼できない場合:
typeof [] // object
typeof null // object
'sofish'instanceof String // false


うーん、おそらく多くの初心者 JavaScript プログラマーはこれのせいで悪口を言うでしょう。 JS を使用する必要がある場合、ほとんどの人はすでに jQuery などのライブラリを持っており、それらは型を簡単に検出できるようにカプセル化されています。もちろん、実際には、「JavaScript ではすべてがオブジェクトである」ということわざがあるため、検出するのはそれほど面倒ではありません。もちろん、多くのドキュメントで言及されているように、未定義は実際には NaN や Infinity のような単なるグローバル プロパティです。おそらくそれはご存知でしょう。しかし、「オブジェクト」が役に立ちます:

コードをコピー コードは次のとおりです:

/ * 検出オブジェクトの型
* @param: obj {JavaScript Object}
* @param: type {String} 大文字で始まる JS 型名
* @return: {Boolean}
*/
関数 is(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 番目の式で String の前に数値が使用されており、そのクラスが強制的に Number に変換されていることがわかります。 JavaScript の型変換を理解するには、ほとんどの場合、これには 2 つの役割があることを理解すれば十分です。他の理解可能なクラスは、エラー: であっても、代入/オーバーロードを使用して変更できます。

コードをコピー コードは次のとおりです。

var err = new Error();
コンソール .log(err エラーのインスタンス) // true;

err = 'sofish';
console.log(err) // 'sofish'



4. JavaScript 参照型

これがこの記事の難点です。基本型と比較して、参照はプロパティとメソッドを追加できます。参照に似た値は参照であり、参照型の値は変数に割り当てられ、ヒープ メモリに格納されている同じ値を指します。変数 (プロパティ) はオーバーロードできますが、コピーは非常に興味深いものになる可能性があります。これについては後ほど詳しく説明します。

1. プロパティとメソッドを追加します

次のコードでは、基本的に同様の値を割り当てた場合、エラーは報告されませんが、取得時には無効になることがわかります:

コードをコピーします コードは次のとおりです:

var arr = [1,2,3];
arr.hello = 'world';
コンソール .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 = ['not a Fish']; // sofish も同様に変更すると、元の値は変更されません
console.log(arr); // [ 1、2、3、「ハローワールド」]

3. 参照型の値をコピーする

元の値に対する操作はすべての参照に影響しますが、操作中に他の参照に影響を与えずに新しいオブジェクトをコピーする必要がある場合があります。一般に、Date/Function/RegExp... などの特定の操作はほとんどなく、主に項目やプロパティを配列やオブジェクトに追加するような操作です。したがって、理解する必要がある主なことは、Array オブジェクトと Object オブジェクトをコピーする方法です。


3.1 配列のコピー

Array オブジェクトには、インターセプトされた配列を返すスライスメソッドがあり、ES5 ではフィルターなども新しい配列を返すので、このメソッドを使用してコピーできます。

コードをコピーします コードは次のとおりです:

var arr = [1, 2, 3 ];
var sofish = arr.slice();

// 新しい配列の操作は元の配列には影響しません
sofish.push('hello world');
console.log(arr) // [1, 2, 3]


3.2 オブジェクトのコピー 配列をコピーするにはスライスメソッドを使用します。実際、配列とオブジェクトの両方で、for ... in ループを使用して、コピーする値を走査して割り当てることができます。


コードをコピー コードは次のとおりです:
var obj = { name: 'sofish' }, sofish = {}, p;
for (p in obj) sofish[p] = obj[p];
//新しいオブジェクトに対する操作は元の値には影響しません

sofish.say = function() {};
console.log(obj); // { name: 'sofish' }

3.3 シャドウ/ディープコピー

上記のような操作は、私たちがよくシャロー コピー (シャドウ コピー) と呼ぶものです。ただし、Array と Object は両方とも複数のレイヤー (ディメンション) を持つことができます。このようなコピーでは、可能な値のうち最上位のレイヤーの値のみが考慮されますが、Array と Object は依然として元のオブジェクトを指します。例:


コードをコピー コードは次のとおりです:
var arr = [1, { bio: '魚ではありません' } ], sofish = [], p;
for(p in arr) {
sofish[p] = arr[p];
}
// `sofish` に含まれるオブジェクト `cat` に対する操作は元の値に影響します

sofish[1].bio = 'hackable';
console.log(arr);// [1 、猫: { bio: 'hackable' } ]

それではどうすればよいでしょうか?この問題を解決するには、copy() 関数を使用してみましょう:

コードをコピー コードは次のとおりです:

/* コピーオブジェクト
* @param: obj {JavaScript Object} 元のオブジェクト
* @param: isDeep {Boolean} ディープコピーかどうか
* @return: {JavaScript Object} 新しいオブジェクトを返します
*/
function copy(obj, isDeep) {
var ret = obj.slice ? [] : {}, p, prop;
// is で使用しますfunction
if(!isDeep && is(obj, 'Array')) return obj.slice();
for(p in obj) {
if(!obj.hasOwnProperty(p)) continue;
prop = obj[p];
ret[p] = (is(prop, 'Object') || is(prop, 'Array'))
copy(prop, isDeep) : prop ;
}
return ret;
}

このようにして、copy(obj, isDeep) 関数を通じて配列またはオブジェクトをコピーできます。テストできます:
コードをコピー コードは次のとおりです:

var arr = [ 1, {bio : '魚ではありません'}];
var sofish = copy(arr);

// 最初のレイヤーの浅いコピー操作は元の値に影響しませんが、2 番目のレイヤーに影響します
sofish.push('cat'); // [ 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'}]

それだけです。基本的に、理解する必要がある型に関する難しい点はすべて理解する必要があります。もちろん、コピーが最も面倒な点です。操作が必要なことが多い配列やオブジェクトの他に、Date/Function/RegExp のコピーもあります。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。