原生函数
也叫JavaScript的内建函数。常用的有:
String()
Number()
Boolean()
Array()
Object()
Function()
RegExp()
Date()
Error()
Symbol()——ES6新加入
封装对象包装
JavaScript会自动为基本类型值包装,所以像一些.length、.toString()的属性和方法,在基本类型被字面量定义之后,也能拥有这些方法和属性。
特别注意在封装数字和布尔值后,用来进行判断时,会有一些疑惑:
var a = new Boolean(false);
if (!a) {
console.log("Oops"); // 执行不到这里
}
var b = new Number(0);
if(!b) {
console.log('Number'); // 执行不到这里
}
原生函数作为构造函数
当Array构造函数只带一个数字参数时,这个参数为数组的预设长度,而非数组的第一个元素。
永远不要创建和使用空单元数组。
除非万不得已,否则尽量不要使用Object()、Function()、RegExp(),直接使用字面量语法,其中RegExp()和Function()在需要动态定义时才比较有用。正则使用字面量语法的执行效率要高于使用构造函数,这和JavaScript在执行前需要预编译有关。
Date()和Error()没有对应的常量形式,所以在代码中用的比较多。
ES6新加入的基本数据类型——符号Symbol。主要解决对象属性重名的问题,作为对象属性时,常规的对象属性遍历是无法获取Symbol的,只能通过特殊的方法来获取——Object.getOwnPropertySymbols()。所以常被用来作为类的私有方法。用来替代_下划线前缀的属性。Symbol由于其值的”唯一性“还可以用来消除魔术字符串。阮一峰老师的blog上讲的很详细。
特殊的原生原型
typeof Function.prototype; // "function"
Function.prototype(); // 空函数!
RegExp.prototype.toString(); // "/(?:)/"————空正则表达式
"abc".match(RegExp.prototype); // [""]
Array.isArray(Array.prototype); // true
Array.prototype.push(1, 2, 3); // 3
Array.prototype; // [1, 2, 3]
强制类型转换
类型转换分为两种,一种发生在静态语法分析时;另一种则是发生在动态类型语言的运行时(runtime),JavaScript统称为强制类型转换。
强制类型转换总返回标量基本类型值,既简单值(如字符串、数字、boolean等)。
值类型转换
隐式强制类型转换和显示强制类型转换是相对而言的:
var a = 42;
var b = a + ""; // 隐式
var c = String(a); // 显示
如果明白a + ""是怎么回事,那么它也是显示的,如果不明白String(a)是怎么回事,那么它也是隐式的。
抽象值操作(即“仅供内部使用的操作”)
ToString
处理非字符串到字符串的强制类型转换。
null --> "null"
undefined --> "undefined"
true --> "true"
极大极小的数字则转换为指数形式:
var a = 1.07 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
a.toString(); // "1.07e21"
普通对象,除非自定义,否则toString()返回内部属性[[Class]]的值。
var obj = { a: 1 };
obj.toString(); // "[object Object]"
数组的默认toString()方法经过了重新定义,将所有单元字符串化以后再用","连接起来:
let a = [1, 2, 3];
a.toString(); // 1,2,3
let b = [{ c: 1 }, { d: 2 }];
b.toString(); // [object Object],[object Object]
数组的toString可以被显示调用,或者在需要字符串化时自动调用。
JSON字符串化
对象中如果定义了toJSON方法,JSON字符串化时会首先调用该方法,然后用它的返回值来进行序列化——toJSON应该“返回一个能够被字符串化的安全的JSON值”。
JSON.stringify并不是强制类型转换,只是其中几种转换规则与ToString相同:字符串、数字、布尔值和null。
ToNumber
对象转换为数字分为3步:
- 检查该值是否有
valueOf()方法,如果有,且返回基本类型值,则使用此基本类型值强制类型转换。 - 如果没有
valueOf()方法,则检查是否有toString()方法,有,且返回基本类型值,则同上。 - 如果以上两种方法都没有,则抛出
TypeError错误。
ToBoolean
JavaScript规范定义了一小撮可以被强制类型转换为false的值:
undefined
null
false
+0、-0和NaN
""
但是JavaScript规范并没有明确规定假值列表之外的都是真值,不过我们可以理解为假值列表以外的值都是真值。
假值对象
并不是说对象是假值,也不是说封装了假值的对象:
var a = new Boolean(false);
var b = new Number(0);
var c = new String("");
var d = Boolean(a && b && c); // true
而是浏览器在某些特定情况下,在常规JavaScript语法基础上自己创建了一些外来(exotic)值,这些就是“假值对象”。虽然代码中会出现这些假值对象,但是它并不属于JavaScript语言范畴:
if(document.all) {...}
document.all由DOM提供给JavaScript程序使用,以前曾是正真意义上的对象,可以强制转换城true,但后来废止了,IE也并不打算继续支持,但是许多程序中还有诸如以下的代码:
if(document.all) {/* it's IE */}
为了不再支持it's IE中的代码,所以将document.all作为假值来处理。
真值
假值列表以外的都是真值,值得注意的是:
var c = "''";
var d = Boolean(c); // true
因为""是假值列表中唯一的字符串。
显示强制类型转换
字符串和数字之间的显示转换
var a = 42;
var b = String(a); // "42"
var c = "3.14";
var d = Number(c); // 3.14
String()遵循前面讲过的ToString规则,将值转换为字符串基本类型。Number()遵循前面讲过的ToNumber规则,将值转换为数字基本类型。
除了String()和Number()以外,还有其他方法可以实现字符串和数字之间的显式转换:
var a = 42;
var b = a.toString(); // "42"
var c = "3.14";
var d = +c; // 3.14
toString()是显示的,但是其中也涉及到隐式转换,因为toString()对于42这种基本类型不适用,需要JavaScript引擎自动为42创建一个封装对象。
+c是+运算符的一元(unary)形式(即只有一个操作数)。+运算符显式地将c转换为数字,而非数字加法运算。
注意:需要区分一元运算符+和-和递增++和递减--运算符。
1 - - 1; // 2
var d = 5 + +"3.14"; // 8.14
日期显示转换为数字
const t = new Date; // 构造函数没有参数的话,使用new运算可以不用()
+t // 1628564390661
~运算符
字位运算符只适用于32位整数,运算符会强制操作数使用32位格式,这里则是通过抽象操作ToInt32实现的,ToInt32则首先执行ToNumber强制类型转换。
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!