当程序须要将值保存起来以备未来使用时,便将其赋值给一个变量,值的类型称做数据类型。javascript
JavaScript 的变量是松散类型的,所谓松散类型就是能够用来保存任何类型的数据。换句话说,每一个变量仅仅是一个用于保存值的占位符而已。定义变量时要使用关键字 var
来声明的,以下所示:java
var message;复制代码
这行代码定义了一个名为 message
的变量,该变量能够用来保存任何值(像这样未通过初始化的变量,会保存一个特殊的值 undefined
)。JavaScript 也支持直接初始化变量,所以在定义变量的同时就能够设置变量的值,以下所示:git
var message = "hello";复制代码
此时,变量 message
中保存了一个字符串值 "hello"
。像这样初始化变量并不会把它标记为字符串类型,所以,能够在修改变量值的同时修改值的类型。以下所示:github
var message = "hello";
message = 100; // 有效的语句,很差的写法复制代码
在这个例子中,变量 message
一开始保存了一个字符串值 "hello"
,而后该值又被一个数字值100取代。虽然咱们不建议修改变量所保存值的类型,但这种操做在 JavaScript 中彻底有效。编程
有一点必须注意,即便用 var
运算符定义的变量是的该做用域中的局部变量。也就是说,若是在函数中使用 var
定义一个变量,那么这个变量在函数退出后就会被销毁,例如:微信
function test(){
var message = "hello"; // 局部变量
}
test();
console.log(message); // 产生错误复制代码
这里,变量 message
是在函数中使用 var
定义的,是局部变量。当函数被调用时,就会建立该变量并为其赋值。而在此以后,这个变量又会当即被销毁,所以例子中的下一行代码就会致使错误。不过,能够像下面这样省略 var
运算符,从而建立一个全局变量:数据结构
function test(){
message = "hello"; // 全局变量,很差的写法
}
test();
console.log(message); // "hello"复制代码
这个例子省略了 var
运算符,于是 message
就成了全局变量。这样,只要调用一次 test()
函数,这个变量就有了定义,就能够在函数外部的任何地方被访问到。less
虽然省略 var
运算符能够定义全局变量,但这也不是推荐的作法,由于在局部做用域中定义全局变量很难维护,给未经声明的变量赋值在严格模式下会抛出 ReferenceError
错误。编程语言
JavaScript 中有5种简单数据类型(也称为「基本数据类型」或「原始数据类型」):Undefined
、Null
、Boolean
、Number
、String
。还有1种复杂数据类型 Object
,Object
本质上是由一组无序的名值对组成的。JavaScript 不支持任何建立自定义类型的机制,全部值最终都将是上述6种数据类型之一。函数
typeof
运算符鉴于 JavaScript 是松散类型的,所以须要有一种手段来检测给定变量的数据类型,typeof
就是负责提供这方面信息的运算符。对一个值使用 typeof
运算符可能返回下列某个字符串:
"undefined"
,若是这个值未声明或已声明但未初始化。"boolean"
,若是这个值是布尔值。"string"
,若是这个值是字符串。"number"
,若是这个值是数值。"object"
,若是这个值是对象或 null
。"function"
,若是这个值是函数。下面是几个使用 typeof
运算符的例子:
var message = "some string";
console.log(typeof message); // "string"
console.log(typeof(message)); // "string"
console.log(typeof 95); // "number"复制代码
从以上例子能够看出,typeof
运算符既能够对变量使用,又能够对字面量使用。因为 typeof
是一个运算符而不是函数,所以例子中的圆括号尽管可使用,但并不提倡。
typeof null
结果是 "object"
是历史遗留 Bug,在 ECMAScript 6中,曾经有提案为历史平反, 将 type null
的值纠正为 "null"
,但最后该提案被拒。理由是历史遗留代码太多,不如继续将错就错。
从技术角度讲,函数在 JavaScript 中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,所以经过 typeof
运算符来区分函数和其余对象是有必要的。
扩展阅读「为何 JavaScript 里面
typeof null
的值是"object"
?」
www.zhihu.com/question/21…扩展阅读「MDN 之
typeof
」
developer.mozilla.org/zh-CN/docs/…扩展阅读「JavaScript 检测原始值、引用值、属性」
shijiajie.com/2016/06/20/…扩展阅读「JavaScript 检测之 basevalidate.js」
shijiajie.com/2016/06/25/…
Undefined
类型Undefined
类型只有1个值,即 undefined
。使用 var
声明变量但未对其加以初始化时,这个变量的值就是 undefined
,直接使用未声明的变量会产生错误。对未声明或已声明但未初始化的变量执行 typeof
运算符会返回 "undefined"
值,例如:
var message; // 这个变量声明以后默认取得了 undefined 值
// var age // 这个变量并无声明
console.log(message); // "undefined"
console.log(age); // 产生错误
console.log(typeof message); // "undefined"
console.log(typeof age); // "undefined"复制代码
Null
类型Null
类型也只有1个值,即 null
。它用来表示值的空缺。你能够认为 undefined
是表示系统级的、出乎意料的或相似错误的值的空缺,而 null
是表示程序级的、正常的或在乎料之中的值的空缺。在下列场景中应当使用 null
。
在下列场景中不该当使用 null
。
null
来检测是否传入了某个参数。null
来检测一个未初始化的变量。Boolean
类型Boolean
类型是 JavaScript 中使用得最多的一种类型,该类型只有两个字面值:true
和 false
。须要注意的是,他们是区分大小写的,也就是说 True
和 False
(以及其余的混合大小写形式)都不是 Boolean
值,只是标识符。
虽然 Boolean
类型的字面值只有两个,但 JavaScript 中全部类型的值都能使用 if
语句或 Boolean()
函数转换为对应的 Boolean
值,例如:
var message = "Hello world!";
if (message){
console.log("Value is true."); // 被执行
}
var messageAsBoolean = Boolean(message);
console.log(messageAsBoolean); // true复制代码
下表给出了各类数据类型及其对应的转换规则。
数据类型 | 转换为true的值 | 转换为false的值 |
---|---|---|
Undefined | - | undefined |
Null | - | null |
Boolean | true | false |
String | 任何非空字符串 | ""(空字符串) |
Number | 任何非零数字值(包括无穷大) | 0和NaN |
Object | 任何对象 | - |
Number
类型Number
类型是 JavaScript 中最使人关注的数据类型,这种类型使用 IEEE 754 格式来表示整数和浮点数值(浮点数值在某些语言中也被称为双精度数值)。和其余编程语言不一样,JavaScript 中的全部数字均用浮点数值表示。
扩展阅读「IEEE 754-1985」
en.wikipedia.org/wiki/IEEE_7…
在 JavaScript 中进行算术计算时,全部以八进制和十六进制表示的数值最终都将被转换成十进制数值。例如:
var a = 10; // 十进制
var b = 023; // 八进制
var c = 0x12ac; // 十六进制
console.log(b); // 19
console.log(c); // 4780复制代码
八进制第一位必须是0,后面跟八进制序列0到7,若是超出了范围,则忽略前导0,后面的数值当作十进制解析,例如:089会被解析为89。(八进制字面量在严格模式下是无效的,会抛出错误。)
十六进制前两位必须是 0x 或 0X,后跟十六进制序列0~九、a~f(不区分大小写),若是超出了范围,则会报语法错误。
所谓浮点数值,就是该数值中必须包含一个小数点,而且小数点后面必须至少有一位数字。虽然小数点前面能够没有整数,但咱们不推荐这种写法。例如:
var a = 1.1;
var b = 0.1;
var c = .1; // 有效,但不推荐复制代码
JavaScript 会不失时机的将浮点数转换成整数。例如:
var a = 5.; // 解析成整数5
var b = 5.0; // 解析成整数5复制代码
对于极大或者极小的数值,可采用科学技术法(也称e表示法)。JavaScript 会将那些小数点后面带有6个零以上的小于1的浮点数值转换为以e表示法表示的数值。例如:
var a = 3.14e7; // 等于31400000
var b = 3.14E-7; // 等于0.000000314
console.log(0.0000003); // 3e-7复制代码
浮点数值的最高精度是17位小数,但在进行算术计算时其精确度远远不如整数,例如:
console.log(0.1 + 0.2); // 0.30000000000000004复制代码
这个舍入偏差会致使没法测试特定的浮点数值,所以,永远不要测试某个特定的浮点数值。
因为内存限制,JavaScript 能表示的数值范围从 Number.MIN_VALUE
到 Number.MAX_VALUE
,并将超出范围的数转换成 Number.POSITIVE_INFINITY
或 Number.NEGATIVE_INFINITY
。0做为除数是不会报错的,正数除以0返回正无穷,负数除以0返回负无穷,0除以0返回NaN
。例如:
console.log(Number.MAX_VALUE); // 最大数 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 最小数 5e-324
console.log(Number.POSITIVE_INFINITY); // 正无穷 Infinity
console.log(Number.NEGATIVE_INFINITY); // 负无穷 -Infinity
console.log( 1 / 0); // Infinity
console.log(-1 / 0); // -Infinity复制代码
JavaScript 提供了 isFinite()
函数,来肯定一个数是否是有穷的。例如:
console.log(isFinite(100)); // true
console.log(isFinite(Infinity)); // false复制代码
NaN
(not a number),是一个特殊的数值。之因此称它为「非数值」,是由于它不能参与算数运算,任何涉及 NaN
的操做都返回 NaN
。而且 NaN
与任何值都不相等(包括自身)。例如:
console.log(typeof NaN); // "number"
console.log(0 / 0); // NaN
console.log(NaN - NaN); // NaN
console.log(Infinity - Infinity); // NaN
var a = NaN;
console.log(a === a); // false复制代码
JavaScript 提供了 isNaN()
函数,来肯定一个数是否是 NaN
。例如:
console.log(isNaN(100)); // false
console.log(isNaN("100")); // false
console.log(isNaN(true)); // false
console.log(isNaN("sss")); // true
console.log(isNaN(NaN)); // true复制代码
Number()
、parseInt()
、parseFloat()
转型函数isNaN()
函数在接收到一个值以后,会尝试使用转型函数 Number()
将这个值转换为数值,转换规则以下:
undefined
转换为 NaN
;null
转换为 0;true
转换为 1
、false
转换为 0
;number
整数转换为十进制,小数不变;string
若是只包含十进制数和小数,则返回对应的数值,若是只包含八进制数,则忽略前导0返回剩余部分,若是只包含十六进制,则返回十进制数,空字符串转换为0,其它字符串转换为 NaN
;object
先则调用对象的 valueOf()
方法,而后依照前面的规则转换返回的值。若是转换的结果是 NaN
,则调用对象的 toString()
方法,而后再次依照前面的规则转换返回的字符串值。因为 Number()
转型函数在转换字符串时不够理想,所以还有两个专门用来转换字符串的函数 parseInt()
和 parseFloat()
函数。
parseInt()
函数会忽略字符串前面的空格,直至找到第一个非空格字符,只要第一个非空格字符不是数字或者正负号,一概返回 NaN
, 若是第一个非空格字符是数字字符,parseInt()
会继续解析第二个字符,直到解析完全部后续字符或者遇到了一个非数字字符。例如:
console.log(parseInt("")); // NaN(Number("")返回 0)
console.log(parseInt("123S")); // 123
console.log(parseInt("12.4")); // 12复制代码
parseFloat()
函数也会忽略字符串前面的空格,直至找到第一个非空格字符,只要第一个非空格字符不是数字或者正负号或者小数点,一概返回 NaN
, 若是第一个非空格字符是上述字符之一,parseFloat()
会继续解析第二个字符,直到解析完全部后续字符或者遇到了一个非浮点数值。例如:
console.log(parseFloat("098.2")); // 98.2
console.log(parseFloat("123.23.23")); // 123.23复制代码
String
类型String
类型用于表示由零或多个16位 Unicode 字符组成的字符序列,即字符串。字符串能够由双引号(")或单引号(')表示,所以下面两种字符串的写法都是有效的:
var firstName = "Nicholas";
var lastName = 'Zakas';复制代码
JavaScript 中的这两种语法形式没有什么区别。用双引号表示的字符串和用单引号表示的字符串彻底相同。不过,以双引号开头的字符串也必须以双引号结尾,而以单引号开头的字符串必须以单引号结尾。
String
数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者具备其余用途的字符。例如:\n
换行、\t
制表、\b
空格、\r
回车、\f
进纸、\\
斜杠、\'
单引号,在用单引号表示的字符串中使用、\"
双引号,在用双引号表示的字符串中使用。
转义字符可出如今字符串中的任意位置,且长度为1。如要在字符串中显示 \
,则必须使用 \
进行转义。例如:
console.log("\n\\".length); // 2
console.log("\\hello"); // "\hello"(长度为6)复制代码
大部分值均可以使用继承而来的 toString()
方法转换为字符串,但 undefined
和 null
值没有这个方法。对数值使用 toString()
方法时,能够传入一个数字基数,以此输出对应进制的字符串值。例如:
console.log(true.toString()); // "true"
var num = 10;
console.log(num.toString()); // "10"
console.log(num.toString(2)); // "1010"
console.log(num.toString(8)); // "12"
console.log(num.toString(16)); // "a"复制代码
在不知道要转换的值是否是 undefined
或 null
的状况下,还可使用转型函数 String()
,这个函数可以将任何类型的值转换为字符串。String()
函数遵循下列转换规则:
toString()
方法,则调用该方法(没有参数)并返回相应的结果;undefined
,则返回 "undefined"
;null
,则返回 "null"
。var value;
console.log(String(10)); // "10"
console.log(String(true)); // "true"
console.log(String(null)); // "null"
console.log(String(value)); // "undefined"复制代码
Object
类型JavaScript 中全部对象都继承自 Object
类型,每一个对象都具备下列基本的属性和方法:
constructor
:保存着用于建立当前对象的函数(构造函数)。hasOwnProperty()
:用于检查给定的属性在当前对象实例中是否存在。propertyIsEnumerable()
:用于检查给定的属性是否可以使用for-in语句来枚举。isPrototypeOf()
:用于检查对象是不是传入对象的原型。toString()
方法:返回对象的字符串表示。toLocaleString()
:返回对象的本地字符串表示。valueOf()
:返回对象的字符串、数值或布尔值表示(一般与toString()方法的返回值相同)。Object
本质上是由一组无序的名值对组成,「名称」部分是一个 JavaScript 字符串,「值」部分能够是任何 JavaScript 的数据类型(包括对象和方法)。这使用户能够根据具体需求,建立出至关复杂的数据结构。
如下两种方法均可以建立一个空对象,这两种方法在语义上是相同的。第二种更方便的方法叫做「对象字面量」法。这也是 JSON 格式的核心语法,通常咱们优先选择第二种方法。例如:
var obj = new Object();
var obj = {}; // 好的写法复制代码
「对象字面量」也能够用来在对象实例中定义一个对象:
var obj = {
name: "Carrot",
"for": "Max",
details: {
color: "orange",
size: 12
}
}复制代码
对象的属性能够经过链式(chain)表示方法进行访问:
obj.details.color; // orange
obj["details"]["size"]; // 12复制代码
完成建立后,对象属性能够经过以下两种方式进行赋值和访问:
obj.name = "Simon" // 赋值
var name = obj.name; // 访问
obj["name"] = "Simon"; // 赋值
var name = obj["name"]; // 访问复制代码
// 挑战一
console.log(typeof "undefined"); // ???
console.log(typeof null); // ???复制代码
// 挑战二
var message = "some string";
console.log(typeof massage); // ???
message = 10000;
console.log(typeof message); // ???复制代码
// 挑战三
var a;
var b = null;
var c = {};
if(a && b && c){
console.log("true."); // ???
}else{
console.log("false."); // ???
}复制代码
// 挑战四
console.log(typeof (0 / 0)); // ???
console.log(023 + 123); // ???复制代码
// 挑战五
console.log(Number("1234S")); // ???
console.log(parseInt("1234S")); // ???复制代码
// 挑战六
console.log(3.14E-7 === 0.000000314); // ???
console.log(0.1 + 0.6 === 0.7); // ???
console.log(0.1 + 0.7 === 0.8); // ???
console.log(NaN === NaN); // ???复制代码
// 挑战七
console.log("\right\now"); // ???
console.log("\right\now".length); // ???
console.log(010.toString(2)); // ???复制代码
// 挑战八
// 一、为 person、wife、child 对象新增 weight 属性,数值分别为 6二、3六、15。
// 二、为 person 对象新增二胎 child2 子对象,name 为 emma,其余属性自行发挥。
var person = {
name: "stone",
age: 30,
wife: {
name: "sohpie",
age: 30
},
child:{
name: "tommy",
age: 3
}
}复制代码
挑战九,深度阅读下面两篇文章,提出你的疑问。
「JavaScript 检测原始值、引用值、属性」
shijiajie.com/2016/06/20/…「JavaScript 检测之 basevalidate.js」
shijiajie.com/2016/06/25/…
关注微信公众号「劼哥舍」回复「答案」,获取关卡详解。
关注 github.com/stone0090/j…,获取最新动态。