Javascript有七种内置类型:
我们可以用 typeof 运算符来查看值的类型,它返回的是类型的字符串值。但是其中类型和他们的字符串值并不一一对应:
其中 typeof null === “object” // true 比较特殊,我们需要使用符合条件来检测 null 值的类型:
var a = null;
(!a && typeof a === "object"); // true
null 是“假值”(falsy 或者 false-like),也是唯一一个用typeof 检测会返回“object”的基本类型值。
还有一种情况:
typeof function a(){/* ... */} === "function"; // true
这样看来,function 也是 JavaScript 的一个内置类型。然而,它实际上只是 object 的一个“子类型”。具体来说,函数是“可调用对象”,它有一个内部属性[[ call ]] ,该属性使其可以被调用。
函数不仅仅是对象,还可以拥有属性。例如:
function a(b, c) {
/* ... */
}
函数对象的 length 属性是其声明的参数的个数:
a.length; //2
因为该函数声明了两个命名函数,b 和 c,所以其 length 值为 2。
再来看看数组。Javascript 支持数组,那么它是否也是一个特殊类型?
typeof [1, 2, 3] === "object"; // true
JavaScript 中的变量是没有类型的,只有值才有。变量可以随时持有任何类型的值。
换句话说,就是 js 的变量在声明一个变量的时候不需要强调它的类型,同时同一变量可以是多种类型的值。比如一个变量可以现在被赋值为字符串类型,随后又被赋值为数字类型值。
已在作用域中声明但还没有赋值的变量,是undefinded。还没有在作用域中声明过的变量是 undeclared。
var a;
a; // undefined
b; // ReferenceReeor: b is not defined
typeof a; // undefined
typeof b; // undefined
和其他强类型语言不同,在 Javascript 中,数组可以容纳任何类型的值,可以是字符串、数字、对象,甚至其他数组(多维数组就是通过这种方式实现的)。
…
可以通过 slice() 来将类数组转化为数组。
Array.prototype.slice.call( arguments );
slice() 返回参数列表。Array.form 同样可以实现这个功能。
数组常用的方法有:
字符串拥有和数组一些相似的地方,比如通过 a[0] 这样的索引来访问元素。indexOf 来查找元素下标。concat() 来合并。但是并不意味着字符串就是字符数组。
Javascript中字符串是不可变的,而数组是可变的。字符串的成员函数不会改变其原始值,而是创建并返回一个新的字符串。而数组的成员函数都是在其原始值上进行操作。
许多数组函数用来处理字符串很方便。虽然字符串没有这些函数。但是可以借用:
var a = "foo";
a.join; //undefined
a.map; //undefined
var c = Array.prototype.join.call(a, "-");
var d = Array.prototype.map.call(a, function(v) { /*...*/} );
这样既可以调用了。
字符串反转可以通过则无法借用,因为反转是会改变成员对象的,而字符串是不可变的。不过我们可以通过以下操作来进行反转:
var c = a.split("").reverse().join("")
字符串常用的方法有:
charAt()
返回指定索引位置处的字符slice()
提取字符串的片断,并把提取的字符串作为新的字符串返回出来split()
使用指定的分隔符将一个字符串拆分为多个子字符串,并将其以数组形式返回。substr(), substring()
截取一个字符串的片段,并返回截取的字符串。 substr和substring这两个方法不同的地方就在于参数二,substr的参数二是截取返回出来的这个字符串指定的长度,substring的参数二是截取返回这个字符串的结束点,并且不包含这个结束点。match()
方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配,并返回一个包含该搜索结果的数组。replace()
把一个目标字符串当中的文本,替换成自己需要的字符。search()
在目标字符串中搜索与正则规则相匹配的字符,搜索到,则返回第一个匹配项在目标字符串当中的位置,没有搜索到则返回一个-1。toLowerCase(),toUpperCase()
全部转为大写或小写includes(), startsWith(), endsWith()
includes用来检测目标字符串对象是否包含某个字符,返回一个布尔值,startsWith用来检测当前字符是否是目标字符串的起始部分,相对的endwith是用来检测是否是目标字符串的结尾部分。repeat()
返回一个新的字符串对象,新字符串等于重复了指定次数的原始字符串。接收一个参数,就是指定重复的次数。Javascript 只有一种数值类型:number,包括“整数”和带小数的十进制数。
JavaScript中的整数就是没有小数的十进制数。所以 42.0 等同于 42。
JavaScript 中的数字类型是基于 IEEE 754 标准来实现的,该标准通常也被称为“浮点数”。JavaScript 使用的是“双精度”格式(即64位二进制)。
默认情况下大部分数字都以十进制显示,小数部分最后面的 0 被省略。特别大和特别小的数字默认使用指数格式显示。
tofixed(…) 方法可以指定小数部分的显示位数。 toPrecision(…) 方法用来指定有效位数
的显示位数,(可以四舍五入)。
undefined 指没有值或从未赋值,null 表示空值或曾赋过值但目前没有值。
null 是一个特殊关键字,不是标识符,我们不能将其当作变量来使用和赋值。然而 undefined 却是一个标识符,可以被当作变量来使用和赋值。
void 是一个运算符。void __ 没有返回值,因此返回结果是 undefined。void 不改变表达式的结果,只是让表达式不返回值。
NaN 意指“不是一个数字”“not a number”。可以理解为“无效数值”。
例如:
var a = 2 / "foo"; // NaN
NaN 不等于自身
JavaScript有一个常规的0(也叫+0)和一个 -0。
var a = 0 / 3; // -0
var a = 0 * 3; // -0
+0 === -0 // true
加法和减法不会得到 -0。
我们为什么需要-0 呢?有些应用程序中的数据需要以级数形式来表示(比如动画帧的移动速度),数字的符号位用来代表其他信息(比如移动方向)。此时如果一个值为 0 的变量失去了它的符号位,它的方向信息就会丢失。所以保留 0 值的符号位可以防止这类情况的发生。
ES6 新加入 object.is 判断两个值是否绝对相等。对于ES6 之前的版本,有一个简单的 polyfill:
if(!Object.is) {
Object.is = function(v1, v2) {
//判断是否是 -0
if((v1 === 0 && v2 === 0)) {
return 1 / v1 === 1 / v2;
}
// 判断是否是NaN
if(v1 !== v1) {
return v2 !== v2;
}
// 其他情况
return v1 === v2
}
}
JavaScript中没有指针,JavaScript 中变量不可能成为指向另一个变量的指向另一个变量的引用。JavaScript 引用指向的是值。
JavaScript 对值和引用的赋值/传递在语法上没有区别,完全根据值的类型来决定。
下面看一个例子:
function foo(x) {
x.push(4);
x; //[1,2,3,4]
x = [4,5,6];
x.push(7);
x; //[4,5,6,7]
}
var a = [1,2,3]
foo(a);
a; // 是[1,2,3,4],不是[4,5,6,7]
在向函数传递a 的时候,实际是将引用 a 的一个复本赋值给 x,而a 仍然指向 [1,2,3]。在函数中我们可以通过引用 x 来更改数组的值,但并不影响 a 的指向,所以a 仍然指向 [1,2,3,4]。
再看一个例子:
function foo(x) {
x = x + 1;
x;
}
var a = 2;
var b = new Number(a);
foo(b);
console.log(b); // 是2,不是3
原因是标量是基本类型值是不可变的。如果一个数字对象的基本类型值是2,那么该值就不能更改,除非创建一个包含新值的数字对象。
x = x + 1,x 的标量基本类型值 2 从数字对象中拆封出来后,x就神不知鬼不觉地从引用对象变成了数字值,它的值 2 + 1 = 3.然而函数外的 b 仍然指向原来那个值为 2 的数字对象。
我们可以为数字对象添加属性,通过它们间接地进行数据交换。
本文所有用例,部分话语引用自 “You Don’t Know JavaScript: Types & Grammar by Kyle Simpson(O’Reilly).Copyright 2015 Getify Solutions, Inx., 978-1-491-909419-0”