一、对象
在JavaScript的世界里,一切都是对象。
**基本数据类型被视为对象:**在JavaScript中,即使像数字(Number)、字符串(String)、布尔值(Boolean)这样的基本数据类型,也是以对象的方式来处理的。
这些基本类型有对应的包装对象,例如Number、String和Boolean。当你对这些基本类型的值使用对象的方法时,JavaScript会临时将它们转换为对应的包装对象,以便可以调用那些方法。
javascript
let str = "Hello";
console.log(str.toUpperCase()); // 输出 "HELLO"
在上面的代码中,str是一个字符串,但我们仍然可以调用其toUpperCase方法,因为JavaScript在运行时将其转换为了一个String对象。
**函数也是对象:**在JavaScript中,函数实际上也是对象。
它们有属性和方法,可以像其他对象一样被操作。这允许我们为函数添加属性或方法,或将函数作为参数传递给其他函数。
但是某些对象还是和其他对象不太一样。为了区分对象的类型,我们用 typeof 操作符获取对象的类型,它总是返回一个字符串:
javascript
typeof 123; // 'number'
typeof NaN; // 'number'
typeof 'str'; // 'string'
typeof true; // 'boolean'
typeof undefined; // 'undefined'
typeof Math.abs; // 'function'
typeof null; // 'object'
typeof []; // 'object'
typeof {}; // 'object'
可见,number、string、boolean、function和undefined有别于其他类型。
特别注意 null 的类型是 object,Array 的类型也是 object ,如果我们用 typeof 将无法区分出 null、Array和通常意义上的object------{}。
二、包装对象
除了这些类型外,JavaScript还提供了包装对象。
类似于Java中的int和Integer这种暧昧关系。
在JavaScript中,有三种基本数据类型(原始类型)具有对应的包装对象:number、boolean和string都有包装对象。分别为:Number、String和Boolean!
没错,在JavaScript中,字符串也区分string类型和它的包装类型。
包装对象用new创建:
javascript
typeof new Number(123); // 'object'
new Number(123) === 123; // false
typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false
typeof new String('str'); // 'object'
new String('str') === 'str'; // false
javascript
var n = new Number(123); // 123,生成了新的包装类型
var b = new Boolean(true); // true,生成了新的包装类型
var s = new String('str'); // 'str',生成了新的包装类型
虽然包装对象看上去和原来的值一模一样,显示出来也是一模一样,但他们的类型已经变为object了!
所以,包装对象和原始值用===比较会返回false:
javascript
typeof new Number(123); // 'object'
new Number(123) === 123; // false
typeof new Boolean(true); // 'object'
new Boolean(true) === true; // false
typeof new String('str'); // 'object'
new String('str') === 'str'; // false
【备注】:=== 是一个严格相等运算符 ,它比较两个值是否严格相等。
这意味着它不仅比较值,还比较值的类型。只有当两个操作数严格相等时,=== 才会返回 true。
严格相等运算符 === 在进行比较时不会进行类型转换。
== 是抽象相等运算符 ,它在比较之前会进行类型转换,尝试将两边的操作数转换为相同的类型,然后再进行比较。
因此,== 可能会导致一些意想不到的结果,特别是当处理不同类型的值时。
为了避免由于隐式类型转换导致的错误和混淆,通常推荐使用 === 而不是 == 进行比较。
所以,不建议使用包装对象!尤其是string类型!!!
如果我们在使用Number、Boolean和String时,没有写new会发生什么情况?
此时,Number()、Boolean和String()被当做普通函数,把任何类型的数据转换为number、boolean和string类型(注意不是其包装类型):
javascript
var n = Number('123'); // 123,相当于parseInt()或parseFloat()
typeof n; // 'number'
var b = Boolean('true'); // true
typeof b; // 'boolean'
var b2 = Boolean('false'); // true! 你敢信'false'字符串转换结果为true!因为它是非空字符串!
var b3 = Boolean(''); // false
var s = String(123.45); // '123.45'
typeof s; // 'string'
总结一下,有这么几条规则需要遵守:
1、不要使用new Number()、new Boolean()、new String()创建包装对象;
2、用parseInt()或parseFloat()来转换任意类型到number;
javascript
var n = parseInt('123');
3、用String()来转换任意类型到string,或者直接调用某个对象的toString()方法;
任何对象都有toString()方法吗?
null和undefined就没有!
确实如此,这两个特殊值要除外,虽然null还伪装成了object类型。
number对象调用toString()报SyntaxError:
javascript123.toString(); // SyntaxError
遇到这种情况,要特殊处理一下:
javascript123..toString(); // '123', 注意是两个点! (123).toString(); // '123'
4、通常不必把任意类型转换为boolean再判断,因为可以直接写if (myVar) {...};
5、typeof操作符可以判断出number、boolean、string、function和undefined;
6、判断Array要使用Array.isArray(arr);
7、判断null请使用myVar === null;
8、判断某个全局变量是否存在用typeof window.myVar === 'undefined';
9、函数内部判断某个变量是否存在用typeof myVar === 'undefined'。