Javascript基礎--基本タイプと引用タイプ
4479 ワード
概念
Javascript言語には変数のタイプがあります.基本タイプと引用タイプがあります.基本タイプの値は
変数をコピー
js言語の変数コピーは他の言語と基本的に一致しています.変数の基本タイプ値をコピーすると、よく分かります.まずスタックメモリの中に新しい変数値のために空間を開けて、コピーされた変数の内容を新しい空間にコピーします.一方、変数の参照タイプ値をコピーすると、コピーされた変数がメモリに保存されているのはポインタアドレスですので、コピーした後も新しい変数の値は同じブロックメモリを指します.このようなコピー方式は、私たちがよく言っている経由JSON: 再帰によって、下記のコードはjqueyのexted方法で を実現します.
タイプ検出の方法
typeofを使って変数の種類を判断できます.
Javascript言語には変数のタイプがあります.基本タイプと引用タイプがあります.基本タイプの値は
に保存され、Unidefined、Null、Boolean、Number、Stringを含む.参照タイプの値は
に保存されています.参照タイプの値を保存する変数は、この
を指すポインタの一つです.含む:Aray、Object、RegExp、Dateなど.変数をコピー
js言語の変数コピーは他の言語と基本的に一致しています.変数の基本タイプ値をコピーすると、よく分かります.まずスタックメモリの中に新しい変数値のために空間を開けて、コピーされた変数の内容を新しい空間にコピーします.一方、変数の参照タイプ値をコピーすると、コピーされた変数がメモリに保存されているのはポインタアドレスですので、コピーした後も新しい変数の値は同じブロックメモリを指します.このようなコピー方式は、私たちがよく言っている
です.例を挙げますvar x = {
data : 'hello'
};
console.log(x.data); // :hello
var y = x;
y.data = 'world';
console.log(x.data); // : world
上のコードはxとyが同じブロックのメモリを指すため、x.dataのプリント結果はhello
からworld
になりました.実際の仕事では、この
によってしばしば私たちに迷惑をかけます.例えば、上記のxは他の変数のための値付け
として使用されています.新しい変数yのメンバー値が変わると、元の変数xの内容を変更したくないです.つまり
です.下のコードは、深くコピーする目的があります.var copyObj = JSON.parse(JSON.stringify(obj));
コードが簡潔で、一般の需要を満たす.エラーは、深くコピーできませんでした.toJsonを実現していないタイプです.例えば、RegExpタイプです.そしてプロトタイプチェーンもなくしました.jQuery.extend = jQuery.fn.extend = function() {
var src, copyIsArray, copy, name, options, clone,
target = arguments[0] || {},
i = 1,
length = arguments.length,
deep = false;
// Handle a deep copy situation
if ( typeof target === "boolean" ) {
deep = target;
// skip the boolean and the target
target = arguments[ i ] || {};
i++;
}
// Handle case when target is a string or something (possible in deep copy)
if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
target = {};
}
// extend jQuery itself if only one argument is passed
if ( i === length ) {
target = this;
i--;
}
for ( ; i < length; i++ ) {
// Only deal with non-null/undefined values
if ( (options = arguments[ i ]) != null ) {
// Extend the base object
for ( name in options ) {
src = target[ name ];
copy = options[ name ];
// Prevent never-ending loop
if ( target === copy ) {
continue;
}
// Recurse if we're merging plain objects or arrays
if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {
if ( copyIsArray ) {
copyIsArray = false;
clone = src && jQuery.isArray(src) ? src : [];
} else {
clone = src && jQuery.isPlainObject(src) ? src : {};
}
// Never move original objects, clone them
target[ name ] = jQuery.extend( deep, clone, copy );
// Don't bring in undefined values
} else if ( copy !== undefined ) {
target[ name ] = copy;
}
}
}
}
// Return the modified object
return target;
};
深度コピーが必要な場合は、exted関数の第一パラメータ転送true:$このコードには問題があります.解決されていません.var a = {};
var b = {};
a.b = b;
b.a = a;
$.extend(true, {}, a) // , "Uncaught RangeError: Maximum call stack size exceeded"
この問題を解決するなら、loadshの実現を参考にしてもいいです.タイプ検出の方法
typeofを使って変数の種類を判断できます.
var a = 'string';
var b = true;
var c;
var d = 100;
var e = {data: 'hello'};
var f = [1, 2, 3];
var g = new RegExp();
console.log(typeof a); // string
console.log(typeof b); // boolean
console.log(typeof c); // undefined
console.log(typeof d); // number
console.log(typeof e); // object
console.log(typeof f); // object
console.log(typeof g); // object
typeofは基本タイプを判断するのに有用であるが、すべての参照タイプはObjectから継承されているので、「Object」を印刷します.オブジェクトがArayかRegExpかを判断するためには
を使用することができます.var f = [1, 2, 3];
var g = new RegExp();
console.log(f instanceof Array); // true
console.log(g instanceof RegExp); // true
また、オブジェクトがArayタイプかどうかの判断には、より一般的な方法があります.instanceof
(ie 9以上)の低バージョンブラウザで互換性のあるコードを解決します.(ie 8以下)if (!Array.isArray) {
Array.isArray = function(obj) {
return Object.prototype.toString.call(obj) == '[object Array]';
}
}