重读犀牛-对象类型札记

这是我参与 11 月更文挑战的第 22 天,活动详情查看:2021 最后一次更文挑战

对象类型

全局对象(global object)

当JavaScript解释器启动时将创建一个新的全局对象,并定义如下属性

  • 全局属性
  • 全局函数
  • 构造函数
  • 全局对象
//使用JavaScript关键字this来引用全局对象
var global = this; // 定义一个引用全局对象的全局变量
复制代码

包装对象

存取字符串、数字或布尔值的属性时创建的临时对象称做包装对象(一种实现细节)。
只要引用了属性,JavaScript就会将字面量通过调用new String()/Number()/ Boolean()构造函数创建一个临时对象,这些方法的调用均是来自于这个临时对象。
一旦属性引用结束,这个新创建的对象就会销毁。
null和undefined没有包装对象:访问它们的属性会造成一个类型错误。

//“==”等于运算符将原始值和其包装对象视为相等,   === 全等运算符视为不等
var s = "test", n = 1, b = true;  // 一个字符串、数字和布尔值
//显示创建包装对象
var S = new String(s);   // 一个字符串对象
var N = new Number(n);   // 一个数值对象
var B = new Boolean(b);   // 一个布尔对象

console.log( s == S )         // true
console.log( s === S )         // false
typeof(s)   //  "string"
typeof(S)   //  "object"
复制代码

不可变的原始值和可变的对象引用

对象(包括数组和函数)称为引用类型(reference type), 对象的比较均是引用的比较:当且仅当它们引用同一个基对象时,它们才相等。

var o = { x: 1 }, p = { x: 1 };
o === p     // false
var a = [], b = [];
a === b     // false
复制代码

类型转换

值/from 字符串/to 数字/to 布尔值/to 对象/to
undefined "undefined" NaN false throws TypeError
null "null" 0 false throws TypeError
true "true" 1 new Boolean(true)
false "false" 0 new Boolean(false)
""(空字符串) 0 false new String("")
"1.2" 1.2 true new String("1.2")
"one" NaN true new String("one")
0 "0" false new Number(0)
-0 "0" false new Number(-0)
NaN "NaN" false new Number(NaN)
Infinity "Infinity" true new Number(Infinity)
-Infinity "-Infinity" true new Number(-Infinity)
1 "1" true new Number(1)
{}(任意对象) 明细 明细 true
[] (任意数组) "" 0 true
[9] (1个数字元素) "9" 9 true
['a'] (其他数组) join()方法 NaN true
function(){}(任意函数) 明细 NaN true

转换和相等性

== 在判断时进行了类型转换, 一个值转换为另一个值并不意味着两个值相等。

//undefined转换成false    
undefined == false //false
复制代码

显示类型转换

最简单的方法就是使用Boolean()、Number()、String()或Object()函数。除了null或undefined之外的任何值都具有toString()方法,这个方法的执行结果通常和String()方法的返回结果一致。

  • “+”运算符的一个操作数是字符串,将会把另外一个操作数转换为字符串。
  • 一元“+”运算符将其操作数转换为数字。
  • 一元“!”运算符将其操作数转换为布尔值并取反。
x + ""  // String(x)
+x  // Number(x)  x-0
!!x // Boolean(x)
复制代码

toString()方法 可以接收表示转换基数(radix)的可选参数,如果不指定此参数,转换规则将是基于十进制。支持进制数(范围在2~36之间)

parseInt()函数 parseFloat()函数(全局函数)

如果字符串前缀是“0x”或者“0X”,parseInt()将其解释为十六进制数,方法会跳过任意数量的前导空格,尽可能解析更多数值字符,并忽略后面的内容。如果第一个非空格字符是非法的数字直接量,将最终返回NaN。
parseInt()可以接收第二个可选参数,这个参数指定数字转换的基数,合法的取值范围是2~36

对象转换为原始值

所有的对象(包括数组和函数)都转换为true。 适用于包装对象,new Boolean(false)是一个对象而不是原始值,它将转换为true。

++只适用于本地对象(native object)++ 对象继承了俩个转换方法:

1.toString()

  • 默认的toString()方法返回 "[object Object]"
  • 数组类(Array class)将每个数组元素转换为一个字符串,并在元素之间添加逗号后合并成结果字符串。
  • 函数类(Function class)返回这个函数的实现定义的表示方式。
  • 日期类(Date class)返回了一个可读的(可被JavaScript解析的)日期和时间字符串。
  • RegExp类(RegExp class)将RegExp对象转换为表示正则表达式直接量的字符串。

2.valueOf()
如果存在任意原始值,它就默认将对象转换为表示它的原始值。 对象是复合值,而且大多数对象无法真正表示为一个原始值,因此默认的valueOf()方法简单地返回对象本身,而不是返回一个原始值。

  • 数组、函数和正则表达式 返回对象本身。
  • 日期类 返回它的一个内部表示:1970年1月1日以来的毫秒数。

步骤:对象到字符串(object-to-string)

  1. 如果对象具有toString()方法,则调用这个方法。如果它返回一个原始值,JavaScript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
  2. 如果对象没有toString()方法,或者这个方法并不返回一个原始值,那么JavaScript会调用valueOf()方法。如果存在这个方法,则JavaScript调用它。如果返回值是原始值,JavaScript将这个值转换为字符串(如果本身不是字符串的话),并返回这个字符串结果。
  3. 否则,JavaScript无法从toString()或valueOf()获得一个原始值,因此这时它将抛出一个类型错误异常。

步骤:对象到数字(object-to-number)

  1. 如果对象具有valueOf()方法,后者返回一个原始值,则JavaScript将这个原始值转换为数字并返回这个数字。
  2. 否则,如果对象具有toString()方法,后者返回一个原始值,则JavaScript将其转换并返回。
  3. 否则,JavaScript抛出一个类型错误异常。

数组是对象,调用valueOf方法无法返回原始值,所以调用toString().空数组转换成空字符串,然后空字符串转化成0;含一个元素的数组转换为字符串结果,然后转化为数值。

运算符

"+" 可以数字和字符串连接操作,若果一个操作数时对象,对象转为原始值。
"==" 原始值和对象比较,对象转换为原始值进行比较。

对象到原始值的转换:非日期对象先尝试调用valueOf(),然后调用toString()返回的原始值将被直接使用,不会被强制转换为数字或字符串;日期对象直接转换成字符串。

"2"+3   //"23"
2+[2]   //"22"
2+[2,3] //"22,3"
2+[]    //"2"
[2]==2  //true
[2]=='2' //true
[]==''  //true
 
//日期对象
var now=new Date()
typeof(now+1)   //"string"
typeof(now-1)   //"number"
now==now.toString()  //true
now>(now-1)   //true
复制代码

猜你喜欢

转载自juejin.im/post/7033397128353284133