★03.类型、值和变量

原始类型

原始类型有:数字、字符串、布尔值、nullundefined

数字

  • 浮点数范围:
    • 最大值:正负1.79E308
    • 最小值:正负5E-324
  • 整数范围:正负2E53
  • 0-0相等,区别在于乘除法时的符号。
  • 上溢出时,用Infinity表示。下溢出时用-Infinity表示。
  • 0整除的结果是Infinity。被-0整除的结果是-Infinity
  • 0除以0的结果是NaN
  • NaN与任何值都不相等,包括自身。所以判断一个变量是否为NaN时要用x!=x,当表达式为true时,xNaN,或者直接使用isNaN()函数。
  • 当一个数不为NaNInfinity-Infinity时,isFinite()返回true

字符串

  • JavaScript 没有单个字符的 字符类型
  • JavaScript 采用 UTF-16 编码的 Unicode 字符集,大多数字符用一个16位值表示,但是有些字符用两个16位值表示,称为 代理项对
  • JavaScript 定义的字符串操作方法(包括length())均作用于16位值,而非字符,不会对代理项对做特殊处理。
  • HTML 代码和 JavaScript 代码混杂时,最好使用'"两种引号风格,以便区分。如

  • 转义字符包括:
    • \o:NUL字符
    • \b:退格符
    • \t:水平制表符
    • \n:换行符
    • \v:垂直制表符
    • \f:换页符
    • \r:回车符
    • \":双引号
    • \':撇号或单引号
    • \\:反斜线
    • \xXX:由两个十六进制数指定的 Latin-1 字符
    • \uXXXX:由4位十六进制数指定的 Unicode 字符
  • \位于没有在上表中出现的字符前,则忽略\,如\##等价。
  • 相关操作方法:
var s = "string";
s.charAt(0);
s.charAt(s.length-1)
s.substring(1, 4);
s.slice(1, 4);             // 同上
s.slice(-3);               // 最后3个字符
s.indexOf("r");            // 字符"r"首次出现的位置
s.lastIndexOf("r");        // 字符"r"最后出现的位置
s.indexOf("r", 3);         // 字符"r"在位置3之后首次出现的位置
s.split(", ");             // 分割子串
s.replace("s", "S");       // 替换
s.toUpperCase();
  • 字符串的操作方法不会改变字符串变量,只会返回新的字符串。

布尔值

  • 布尔值只有两个直接量:falsetrue
  • 假值:即会转化为false的值,其中包括undefinednull0-0NaN""
  • 真值:除了上面列出的值,其他所有值都会转化为true
  • 布尔值只有一个方法toString(),返回值为"true""false"

null和undefined

  • undefined是预定义的全局变量,而不是关键字。
  • 函数没有返回值的时候,会返回undefined
  • 函数形参没有传入实参时,此形参的值为undefined
  • null是关键字。
  • null == undefined返回"true"null === undefined返回"false"
  • 如果你想将它们赋值给变量或者属性,或将它们作为参数传入函数,最佳的选择是使用nullundefined通常用于辨别非预期内的情况。

对象类型

  • 除了原始类型以外的类型就是对象类型。
  • 由属性集合组成。
  • 五种特殊的对象类型:数组类型、函数类型、Date类型、RegExp类型、错误类型。
  • 变量都是引用,两个引用指向一个对象的时候,修改一个引用的值也会改变另一个引用。
var a = [];
var b = a;
b[0] = 1;
a[0];        // 1
a === b;     // true

数组类型

  • 不能直接比较,要逐个元素进行比较。

Date类型

var date1 = new Date(2017, 0, 3, 10, 11, 12);   // 2017年1月3日 10时11分12秒
var date2 = new Date(2017, 0, 3, 10, 11, 13);   // 2017年1月3日 10时11分13秒
var diff = date2 - date1;                       // 计算两个时间间隔的毫秒数
date1.getFullYear();                            // 2017年
date1.getMonth();                               // 0月---月份从0开始算起
date1.getDate();                                // 一月的第几天
date1.getDay();                                 // 星期几
date1.getHours();                               // 10时
date1.getMinutes();                             // 11分
date1.getSeconds();                             // 12秒
date1.getUTCHours();                            // 使用UTC表示的小时

RegExp类型

  • RegExp是一种特殊的 JavaScript 对象类型。
  • RegExp直接量:在两条斜线之间的文本构成了一个RegExp直接量,如/^HTML/[1-9][0-9]*
  • 相关方法:
var text = "testing: 1, 2, 3";
var pattern = /\d+/g;
pattern.test(text);          // true: 匹配成功
text.search(pattern);        // 9
text.match(pattern);         // ["1", "2", "3"]
text.replace(pattern, "#");  // testing: #, #, #
text.split(/\D+/);           // ["", "1", "2", "3"]

全局对象

  • JavaScript 解释器启动时(或者任何 Web浏览器 加载新页面的时候),它将创建 一个 新的全局对象,这个全局对象包含:
    • 全局属性:比如undefinedInfinityNaN
    • 全局函数:比如isNaN()parseInt()eval()
    • 构造函数:比如Date()RegExp()String()Object()Array()
    • 其它全局对象:比如 MathJSON
  • JavaScript 中可以用this来表示全局对象。可以在全局作用域中使用如下方法来引用全局对象:var global = this;
  • 在客户端 JavaScript 中,在其表示的浏览器窗口中的所有 JavaScript 代码中,Window对象取代了this充当了全局对象。可以在全局作用域中使用如下方法来引用全局对象:var global = Window.window;
  • Window对象定义了核心的全局属性,但它也针对 Web浏览器 和客户端 JavaScript 定义了少部分其它全局属性。
  • 如果代码中声明了一个全局变量,这个全局变量就是全局对象的一个属性。

包装对象

  • JavaScript 中的包装对象类似 Java 中的包装器。
  • JavaScript 对象时属性或已命名值的集合。通过.符号来引用属性值。
  • 尽管数字、字符串、布尔值没有属性,但是被.运算符作用时,会创建对应的临时对象(Number()String()Boolean()),此时会有属性。这个临时对象被称为包装对象。
  • nullundefined没有包装对象。
  • 区分数字、字符串、布尔值和数字对象、字符串对象、布尔值对象:
var s = "test";              // 字符串
var n = 1;                   // 数字
var b = true;                // 布尔值
var S = new String(s);       // 字符串对象
var N = new Number(n);       // 数字对象
var B = new Boolean(b);      // 布尔值对象
s == S;                      // "true"
s === S;                     // "false"
n == N;                      // "true"
n === N;                     // "false"
b == B;                      // "true"
b === B;                     // "false"
  • 包装对象会在作用完毕后销毁:
var s = "test";
s.len = 4;
var t = s.len;               // t的值为undefined

类型转换

简介

类型转换即在 JavaScript 期望使用某种类型的时候,将其他类型转换为这种类型的过程。

字符串 数字 布尔值 对象
undefined "undefined" NaN false throw TypeError
null "null" 0 false throw 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] "9" 9 true
['a'] 使用join()方法 NaN true
function() {} NaN true

转换与相等性

  • =====的区别在于:==在比较两个操作数的时候可能做了类型转换,而===则不会做类型转换。

显式类型转换

  • 当不通过new来调用Boolean()Number()String()Object()函数时就是显式类型转换。
Number("3");       // 3
String(false);     // "false"
Boolean([]);       // true
Object(3);         // new Number(3)
  • 除了nullundefined之外的任何值都具有toString(),通常和String()返回结果一致。

Number转换为String

var n = 123456.789;
n.toFixed(0);          // "123457"
n.toFixed(2);          // "123456.79"
n.toFixed(5);          // "123456.78900"
n.toExponential(1);    // "1.2e+5"
n.toExponential(3);    // "1.235e+5"
n.toPrecision(4);      // "1.235e+5"
n.toPrecision(7);      // "123456.8"
n.toPrecision(10);     // "123456.7890"

String转换为Number

parseInt("3 blind mice");         // 3
parseInt("-12.34");               // -12
parseInt("0xFF");                 // 255
parseInt("0xff");                 // 255
parseInt("0.1");                  // 0
parseInt(".1");                   // NaN

parseInt("11", 2);                // 3
parseInt("ff", 16);               // 255
parseInt("zz", 36);               // 1295
parseInt("077", 8);               // 63
parseInt("077", 10);              // 77

parseFloat(" 3.14 meters");       // 3.14
parseFloat(".1");                 // 0.1
parseFloat("$72.47");             // NaN

对象转换为原始值

  • 对象转换为布尔值 的规则是:所有对象都转换为true,包括 包装对象 new Boolean(false)
  • 对象转换为字符串 的规则是:
    • 通过toString()转换为字符串。
    • 若没有toString(),则通过valueOf()转换为数字,再转换为字符串。
    • 若既没有toString(),也没有valueOf(),抛出 类型错误异常
  • 对象转换为数字 的规则是:
    • 通过valueOf()转换为数字。
    • 若没有valueOf(),则通过toString()转换为字符串,再转换为数字。
    • 若既没有toString(),也没有valueOf(),抛出 类型错误异常
  • 对象遇到+==!=<><=>=时,转换规则如下:
    • Date类对象会使用toString()转换为字符串。
    • Date类以外的其他对象会使用以下规则:
      • 使用valueOf()转换为数字,然后直接使用,不会进一步转换为字符串。
      • 若没有valueOf(),则使用toString()转换为字符串,然后直接使用,不会进一步转换数字。
  • 对象遇到-等其他运算符,则直接使用 对象转换为数字 规则。

类型转换小技巧

x + ""       // 等于String(x)
+x           // 等于Number(x)
!!x          // 等于Boolean(x)

变量声明

  • 声明但不初始化变量时,初始值为undefined
  • JavaScript 没有花括号括起来的块级作用域。
  • 声明提前 :局部变量声明无论在函数体内的哪里,都会被提升至函数体的开头部分,但是初始化语句不会,还是待在原来的地方。
  • 多次声明同一个变量是无所谓的。
var scope = "global";
function f() {
    console.log(scope);           // 局部变量的scope,值为undefined,覆盖全局作用域的scope
    var scope = "local";          // 虽然在这里声明,但是在整个函数作用域里是可见的。初始化语句则要运行到这一句才会真正赋值。
    console.log(scope);           // local
}
  • 将所有函数内局部变量声明在函数体开头部分是个好习惯。

全局变量

  • 当声明一个 JavaScript 全局变量时,实际上是定义了全局对象的一个属性。
  • 当使用var声明一个变量时,创建的这个属性是不可配置的。
var a = 1;                        // 全局变量的声明方式一
b = 2;                            // 全局变量的声明方式二
this.c = 3;                       // 全局变量的声明方式三
delete a;                         // false
delete b;                         // true
delete c;                         // true

你可能感兴趣的:(★03.类型、值和变量)