在JavaScript并非所有的一切都是对象 |
||||||||||||||||
虽然很多语言宣称:“一切皆是对象”,但是 javascript 中,并不是所有的值都是对象 。 原始值 vs 对象 定义 下面的值是原始值 。 1.字符串
1.原始值的包装器:Boolean, Number, String 。很少直接使用 。 2.用字面量创建的对象 。 下面的字面量产生对象,也可以通过构造函数创建对象 。您可以使用字面量创建对象 。 •[] 就是 new Array() 区别 1.对象是可变的: 复制代码 代码如下: > var obj = {}; > obj.foo = 123; // 添加属性和值 123 > obj.foo // 读属性,返回属性的值 123 2.每个对象都有自己唯一的标识符,因此通过字面量或构造函数创建的对象和任何其他对象都不相等,我们可以通过 === 进行比较 。 复制代码 代码如下: > {} === {} false 对象是通过引用来比较的,只有两个对象有相同的标识,才认为这个对象是相等的 。 复制代码 代码如下: > var obj = {}; > obj === obj true 3.变量保存了对象的引用,因此,如果两个变量应用了相同的对象——我们改变其中一个变量时,两一个也会随之改变 。 复制代码 代码如下: > var var1 = {}; > var var2 = var1; > var1.foo = 123; // 修改变量 val1 的属性 正如预期的那样,原始值和对象不一样: 1.原始值是不可变的;你不能给它们添加属性: 复制代码 代码如下: > var str = "abc"; > str.foo = 123; // 添加属性(此操作将被忽略) 123 > str.foo // 读属性的值,返回 undefined undefined 2.原始值没有内部标识,原始值是按值比较的: 比较两个原始值的依据是他们的内容,如果两个原始值的内容相同,这认为这两个原始值相同 。 复制代码 代码如下: > "abc" === "abc" true 这意味着,一个原始值的标识就是它的值,javascript 引擎没有为原始值分配唯一标识 。 最后两个事实结合起来的意思是:我们无法区分一个变量到底是对象的引用,还是原始值的副本 。 陷阱:原始值和它们的包装类型 原始值类型 boolean, number 以及 string 都有自己对应的包装类型 Boolean, Number 和 String 。 包装类型的实例都是对象值,两种类型之间的转换也很简单: •转换为包装类型:new String("abc") 复制代码 代码如下: > typeof "abc" string > typeof new String("abc") object > "abc" instanceof String > "abc" === new String("abc") 包装类型的实例是一个对象,因此和 JavaScript 和对象一样,包装类型也无法进行值的比较(只能比较引用) 。 复制代码 代码如下: > var a = new String("abc"); > var b = new String("abc"); > a == b false // 虽然 a 和 b 有相同的内容,但是依然返回 false > a == a true 原始值没有自己的方法 复制代码 代码如下: > "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 复制代码 代码如下: > typeof "abc" string > typeof 123 number > typeof {} object > typeof [] object typeof 返回以下字符串:
注释: •typeof 在操作 null 时会返回 "object",这是 JavaScript 语言本身的 bug 。不幸的是,这个 bug 永远不可能被修复了,因为太多已有的代码已经依赖了这样的表现 。这并不意味着,null 实际上就是一个对象[4] 。 •typeof 还可以让检查一个变量是否已声明,而不会抛出异常 。 没有任何一个函数可以实现此功能,因为你不能把一个未声明的变量传递给函数的参数 。 复制代码 代码如下: > typeof undeclaredVariable undefined > undeclaredVariable ReferenceError: undeclaredVariable is not defined •函数也是对象类型;这可能是很多人无法理解的,但有时候却是非常有用的 。 •数组是一个对象 。 更多关于 typeof 的信息 [5] 和 [6] 。 instanceof 复制代码 代码如下: value instanceof Constructor 如果上面的表达式返回 true,则表示 value 是 Constructor 的一个实例 。它等价于: 复制代码 代码如下: Constructor.prototype.isPrototypeOf(value) 大多数对象是 Object 的实例,因为原型链的末端(prototype chain)是 Object.prototype 。 原始值不是任何对象的实例: 复制代码 代码如下: > "abc" instanceof Object false > "abc" instanceof String false |