ホームページ  >  記事  >  ウェブフロントエンド  >  JavaScript のすべてがオブジェクトであるわけではない_基本

JavaScript のすべてがオブジェクトであるわけではない_基本

WBOY
WBOYオリジナル
2016-05-16 17:37:291172ブラウズ

多くの言語は「すべてはオブジェクトである」と主張していますが、JavaScript ではすべての値がオブジェクトであるわけではありません。

プリミティブ値 vs オブジェクト
JavaScript の値は、プリミティブ値 (プリミティブ) とオブジェクト (オブジェクト) の 2 つの主要なカテゴリに分類できます。

定義
JavaScript での 2 つの値の定義:

以下の値は元の値です。

1. 文字列
2. 数値: JavaScript のすべての数値は浮動小数点数
3. ブール値
4.null
5.未定義


その他の値はすべてオブジェクトです。 オブジェクトはさらに分割できます:

1. 元の値のラッパー: ブール値、数値、文字列。直接使用されることはほとんどありません。

2. リテラルで作成されたオブジェクト。 次のリテラルはオブジェクトを生成します。オブジェクトはコンストラクターを通じて作成することもできます。リテラルを使用してオブジェクトを作成できます。

•[] は新しい Array()
•{} は新しい Object()
•function() {} は新しい Function()
•/s*/ は新しい RegExp("\ s*")
3. 日付: new Date("2011-12-24")

相違点
列挙されたプリミティブと非プリミティブを介してプリミティブとオブジェクトを定義できます。 ただし、プリミティブとオブジェクトが何であるかを説明することもできます。 オブジェクトから始めましょう。

1. オブジェクトは変更可能です:

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

> var obj = {};
> ; obj.foo = 123; // 属性と値を追加
123
> // 属性を読み取り、属性値を返します
123

2. 各オブジェクトには独自の一意の識別子があるため、リテラルまたはコンストラクターを通じて作成されたオブジェクトは他のオブジェクトと等価ではなく、=== を通じて比較できます。

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

>
false

オブジェクトは参照によって比較され、同じ識別子を持つ 2 つのオブジェクトのみが等しいとみなされます。

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

> var obj = {};
> ; obj === obj
true

3. 変数はオブジェクトへの参照を保存するため、2 つの変数が同じオブジェクトに適用される場合、変数の 1 つを変更すると、両方の変数も変更されます。

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

> var var1 = {};
> ; var var2 = var1;

> var1.foo = 123; // 変数 val1 のプロパティを変更します
123
> var2.foo // val2 も変更します
123

予想どおり、プリミティブ値はオブジェクトと同じではありません:

1. プリミティブ値は不変です。属性を追加することはできません。

コードをコピーします コードは次のとおりです。
>
> str.foo = 123; // 属性を追加します (この操作は無視されます)
123
> str.foo // 属性の値を読み取り、未定義
を返します🎜>

2. 元の値には内部識別子がなく、元の値は値によって比較されます。2 つの元の値を比較する基準は、2 つの元の値の内容が同じである場合です。 2 つの元の値は同じとみなされます。

コードをコピーします コードは次のとおりです。
> "abc" === " abc「
本当

这意味着,一个原始值的标识就是它的值,javascript 引擎没有为原始值分配唯一标识。

最后两个事实结合起来的意思是:我们无法区分一个变量到底是对象的引用,还是原始值的副本。

陷阱:原始值和它们的包装类型
规则:忽略尽可能多的包装类型。 在其他编程语言如Java,你很少会注意到他们。

原始值类型 boolean, number 以及 string 都有自己对应的包装类型 Boolean, Number 和 String。 包装类型的实例都是对象值,两种类型之间的转换也很简单:

•转换为包装类型:new String("abc")
•转换为原始类型:new String("abc").valueOf()
原始值类型以及它们相应的包装器类型有很多不同点,例如:

复制代码 代码如下:

> typeof "abc"
'string'
> typeof new String("abc")
'object'

> "abc" instanceof String
false
> new String("abc") instanceof String
true

> "abc" === new String("abc")
false

包装类型的实例是一个对象,因此和 JavaScript 和对象一样,包装类型也无法进行值的比较(只能比较引用)。

复制代码 代码如下:

> var a = new String("abc");
> var b = new String("abc");
> a == b
false // 虽然 a 和 b 有相同的内容,但是依然返回 false
> a == a
true

原始值没有自己的方法
包装对象类型很少被直接使用,但它们的原型对象定义了许多其对应的原始值也可以调用的方法。 例如,String.prototype 是包装类型 String 的原型对象。 它的所有方法都可以使用在字符串原始值上。 包装类型的方法 String.prototype.indexOf 在 字符串原始值上也有,它们并不是两个拥有相同名称的方法,而的的确确就是同一个方法:

复制代码 代码如下:

> "abc".charAt === String.prototype.charAt
true

在数字的包装类型 Number 的原型对象有 toFixed 方法,即 Number.prototype.toFixed,但是当我们写如下代码时却发生错误:

复制代码 代码如下:

> 5.toFixed(3)
SyntaxError: Unexpected token ILLEGAL

此错误是解析错误(SyntaxError),5 后面跟着一个点号(.),这个点被当作了小数点,而小数点后面应该是一个数,以下代码可以正常运行:

复制代码 代码如下:

> (5).toFixed(3)
"5.000"
> 5..toFixed(3)
"5.000"

值的分类:typeof 和 instanceof
如果你想要对值进行分类,你需要注意原始值和对象之间的区别。 typeof 运算可以用来区分原始值和对象。instanceof 可以用来区分对象,而且,instanceof 对于所有的原始值都返回 false。

typeof
typeof 可以用来判断原始值的类型,以及区分对象值和原始值:

复制代码 代码如下:

> typeof "abc"
'string'
> typeof 123
'number'
> typeof {}
'object'
> typeof []
'object'

typeof 返回以下字符串:

参数 结果
undefined "undefined"
null "object"
布尔值 "boolean"
数字 "number"
字符串 "string"
函数 "function"
其他 "object"

注:

•typeof は null を操作すると「object」を返しますが、これは JavaScript 言語自体のバグです。残念ながら、既存のコードの多くがすでにこの動作に依存しているため、このバグは修正されることはありません。これは、null が実際にオブジェクトであることを意味するものではありません[4]。

•typeof を使用すると、例外をスローせずに変数が宣言されているかどうかを確認することもできます。 宣言されていない変数を関数のパラメーターに渡すことはできないため、これを行う関数はありません。

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

> typeof undeclaredVariable
' '
> undeclaredVariable
参照エラー: undeclaredVariable が定義されていません

• 関数もオブジェクト型です。これは多くの人には理解されないかもしれませんが、場合によっては非常に便利です。

•配列はオブジェクトです。

typeof [5] および [6] の詳細。

instanceof
instanceof は、値がコンストラクターのインスタンスであるかどうかを検出できます:

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

コンストラクターの値インスタンス

上記の式が true を返す場合、値が Constructor のインスタンスであることを意味します。これは以下と同等です:

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

Constructor.prototype.isPrototypeOf(value)

プロトタイプチェーンの最後は Object.prototype であるため、ほとんどのオブジェクトは Object のインスタンスです。 プリミティブ値はオブジェクトのインスタンスではありません:

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

> >false
> "abc" 文字列のインスタンス
false

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