首頁  >  文章  >  web前端  >  在JavaScript並非所有的一切都是物件_基礎知識

在JavaScript並非所有的一切都是物件_基礎知識

WBOY
WBOY原創
2016-05-16 17:37:291177瀏覽

雖然很多語言宣稱:“一切皆是物件”,但是 javascript 中,並不是所有的值都是物件。

原始值 vs 物件
javascript 中的值可以被分割為兩大類:原始值(primitive)和物件(object)。

定義
javascript 的兩種值的定義:

下面的值是原始值。

1.字串
2.數字:在 JavaScript 中所有的數字都是浮點數
3.布林值
4.null
5.undefined


所有其它的值都是物件(object)。 物件可以進一步劃分:

1.原始值的包裝器:Boolean, Number, String。很少直接使用。

2.用字面量建立的物件。 下面的字面量產生對象,也可以透過建構函式建立對象。您可以使用字面量建立物件。

•[] 就是new Array()
•{} 就是new Object()
•function() {} 就是new Function()
•/s*/ 就是new RegExp("\ s*")
3.日期:new Date("2011-12-24")

區別
您可以透過列舉的原語和定義物件非原語定義原語和物件。 但你也可以描述的原語和物件是什麼。 讓我們開始與對象。

1.物件是可變的:

複製程式碼 程式碼如下:

> var obj = {};


> var obj = {};123
> obj.foo // 讀取屬性,傳回屬性的值
123

2.每個物件都有自己唯一的標識符,因此透過字面量或建構函數所建立的物件和任何其他物件都不相等,我們可以透過 === 進行比較。

複製程式碼
程式碼如下:


> {} === {}

> {} === {}false🎜>

物件是透過引用來比較的,只有兩個物件有相同的標識,才認為這個物件是相等的。
複製程式碼


程式碼如下:
> var obj = {};

> var obj = {};true 3.變數保存了物件的引用,因此,如果兩個變數應用了相同的物件-我們改變其中一個變數時,兩一個也會隨之改變。



複製程式碼


程式碼如下:


> var var1 = {};

> var var1 = {};

var var2 = var1;

> var1.foo = 123; // 修改變數 val1 的屬性

123

> var2.foo // val2 也改變了123 正如預期的那樣,原始值和物件不一樣:
1.原始值是不可變的;你不能給它們添加屬性:





複製程式碼
程式碼如下:

> var str = "abc";

str.foo = 123; // 新增屬性(此操作會被忽略)123> str.foo // 讀取屬性的值,回傳undefinedundefined
2.原始值沒有內部標識,原始值是按值比較的: 比較兩個原始值的依據是他們的內容,如果兩個原始值的內容相同,這認為這兩個原始值相同。



複製程式碼 程式碼如下:> "abc" === "abc"true

这意味着,一个原始值的标识就是它的值,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 語言本身的 bug。不幸的是,這個 bug 永遠不可能被修復了,因為太多已有的程式碼已經依賴了這樣的表現。這並不意味著,null 實際上就是一個物件[4] 。

•typeof 還可以讓檢查一個變數是否已聲明,而不會拋出異常。 沒有任何一個函數可以實現此功能,因為你不能把一個未宣告的變數傳遞給函數的參數。

複製程式碼 程式碼如下:

> typeof undeclaredV​​eable undeclaredVariable
ReferenceError: undeclaredVariable is not defined


•函數也是物件類型;這可能是很多人無法理解的,但有時卻是非常有用的。

•陣列是一個物件。

更多關於 typeof 的資訊 [5] 和 [6]。

instanceof

instanceof 可以偵測一個值是否是某個建構子的實例:

複製程式碼 程式碼如下:
value instanceof Conorstruct


value
如果上面的表達式傳回 true,則表示 value 是 Constructor 的一個實例。它等價於:

複製程式碼 程式碼如下:
Constructor.prototype.isPrototype. 🎜>

大多數物件是 Object 的實例,因為原型鏈的末端(prototype chain)是 Object.prototype。 原始值不是任何物件的實例:

複製程式碼

程式碼如下:> "abc" instanceof Object> "abc" instanceof Stringfalse

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn