JavaScript数据类型(data type),包括七种基本值和一种对象类型。
七种基本值(primitive values、原始值)类型: null、undefined、number、string、boolean、Symbol、bigInt和 Object类型。
①null:空、无。表示不存在,当为对象的属性赋值为null,表示删除该属性。在布尔运算中被认为是false。
②undefined:未定义。当声明变量却没有赋值时会显示该值。可以为变量赋值为undefined。一个声明未定义的变量的初始值。
③number:除了能够表示浮点数外,还有一些带符号的值:+Infinity,-Infinity 和 NaN (非数值,Not-a-Number)。
④string:用于表示文本数据,在字符串中的每个元素占据了字符串的位置。第一个元素的索引为0,下一个是索引1,依此类推。字符串的长度是它的元素的数量。JavaScript 中字符串是不可变的(如,JavaScript 中对字符串的操作一定返回了一个新字符串,原始字符串并没有被改变)。
⑤boolean:布尔表示一个逻辑实体,可以有两个值:true 和 false。
⑥symbol:表示独一无二的值。这种类型的对象永不相等,即始创建的时候传入相同的值,可以解决属性名冲突的问题,做为标记。ES6 引入了一种新的原始数据类型 symbol,表示独一无二的值。
⑦bigInt:可以用任意精度表示整数。使用 BigInt,您可以安全地存储和操作大整数,甚至可以超过数字的安全整数限制。BigInt是通过在整数末尾附加 n 或调用构造函数来创建的。ES10 又引入bigint。
基本类型的值是不可变的——值本身无法被改变。其特点:
☆基本类型的值是不可变的。
需要注意的是,基本类型本身和一个赋值为基本类型的变量的区别。变量会被赋予一个新值,而原值不能像数组、对象以及函数那样被改变。基本数据类型(primitive data type)详见原始数据 - 术语表 | MDN
一种对象类型(Object type)。此外,还有Array(数组)类型,以及分别用于表示日期和正则表达式的 Date(日期)和 RegExp(正则表达式),这三种类型都是特殊的对象。严格意义上说,Function(函数)也是一种特殊的对象。关于对象类型可参见 重新介绍 JavaScript(JS 教程) - JavaScript | MDN 有关部分。
对象类型(Object type)细分包括:Object类型、Array类型、Date类型、RegExp类型、Function类型,也称为引用值(reference values)类型。
基本类型值指的是简单的数据段;引用类型值指由多个值构成的对象。当把变量赋值给一个变量时,解析器首先要做的就是确认这个值是基本类型值还是引用类型值。
JavaScript中字面量、变量与常量
首先给个例子来对三者有个直观大致的了解:
var a=10; //a为变量,10为字面量
var strName="LiLi"; //strName为变量,“LiLi"为字面量
const b=3 ;//b为常量,3为字面量
☆字面量
字面量的分类:
整数型字面量:1、2、3、100、-100......
浮点型字面量:1.3、1.2、1.1、4.6、7.8......
布尔型字面量:ture、false(只有这两个,表示真假,ture标识真,false表示假)
字符串型字面量:“abc”、'12' 、“中国”
字面量有的地方称为直接量,即看见什么,它就是什么。你也可以认为字面量就是一个值,比如变量的值。如:
//等号右侧的值均为字面量
var obj={name:"LiLi", age:18};//{name:"LiLi", age:18}为对象字面量
var str="abcd";//abcd为字符串字面量
var num=99;//99为数值字面量
var arr=[1,2,3];//[1,2,3]为数组字面量
☆变量
变量是用于存储数据的容器,在程序的运行中可以发生变化或者被再次赋值。
在ES6中新增了let关键字声明变量,作用与var类似,只是声明的变量只在其所在区域内有效,如:
let str="es6";//str为变量,"es6"为字面量
☆常量
常量与变量一样均是用于存储数据的容器,只不过常量的值在程序的运行中不可以发生改变。
在ES6之前并没有声明常量的方法,在ES6中新增加了const来定义常量。建议常量的命名全部大写,如果由多个单词构成,可以用下划线割开,如:
const MY_SITE="http://www.LiLi.cn";//MY_SITE为常量,"http://www.LiLi.cn"为字面量
常量与变量的区别:
常量与变量的存储方式是一样的,只不过常量必须要有初始值,而且值不允许被修改,而变量可以无初始值,且可以多次赋值。
常量与字面量的区别:
常量与字面量均不会被改变。常量为存储数据的容器,而字面量为等号右侧的值,字面量是由字符串,数字等构成的字符串或数值。
JavaScript中基本数据类型和引用数据类型的区别
参见“JavaScript中基本数据类型和引用数据类型的区别“ 详见:JavaScript中基本数据类型和引用数据类型的区别 - cc_ccc - 博客园
和“跟我学习javascript的基本类型和引用类型“ 详见: https://www.jb51.net/article/74897.htm
1、基本数据类型和引用数据类型
ECMAScript包括两个不同类型的值:基本数据类型和引用数据类型。
【注 据《JavaScript高级程序设计》 第4版4.1节:JavaScript变量可以包含两种不同数据:
基本值(primitive values、原始值)和引用值(reference value)。
基本值是简单的数据;引用值是由多个值构成的对象。
保存基本值的变量是按值(by value)访问的,操作的是变量的实际值。
操作对象(object)时,操作的是该对象的引用(reference)而非实际的对象本身,因此,保存引用值的变量是按引用(by reference)访问的。】
基本数据类型指的是简单的数据段(存放在栈中);引用数据类型指的是有多个值构成的对象(存放在内存中)。
当我们把变量赋值给一个变量时,解析器首先要确认的就是这个值是基本类型值还是引用类型值。
2、常见的基本数据类型:
基本数据类型是按值访问的,因为可以直接操作保存在变量中的实际值。示例:
var a = 10;
var b = a;
b = 20;
console.log(a); // 10值
console.log(b); //20
上面,b获取的是a值得一份拷贝,虽然,两个变量的值相等,但是两个变量保存了两个不同的基本数据类型值。
b只是保存了a复制的一个副本。所以,b的改变,对a没有影响。
下图演示了这种基本数据类型赋值的过程:
也就是说基本类型在赋值 b=a 操作后,这两个变量可以参加任何操作而相互不受影响。
3、引用类型数据:
也就是对象类型Object type,比如:Object 、Array 、Function 、Data等。
javascript的引用数据类型是保存在堆内存中的对象。
与其他语言的不同是,你不可以直接访问堆内存空间中的位置和操作堆内存空间。只能操作对象在栈内存中的引用地址。
所以,引用类型数据在栈内存中保存的实际上是对象在堆内存中的引用地址。通过这个引用地址可以快速查找到保存中堆内存中的对象。
var obj1 = new Object();
var obj2 = obj1;
obj2.name = "我有名字了";
console.log(obj1.name); // 我有名字了
说明这两个引用数据类型指向了同一个堆内存对象。obj1赋值给onj2,实际上这个堆内存对象在栈内存的引用地址复制了一份给了obj2,
但是实际上他们共同指向了同一个堆内存对象。实际上改变的是堆内存对象。
下面我们来演示这个引用数据类型赋值过程:
引用类型的赋值obj2 = obj1后两个变量指向同一个对象,操作会相互影响。
【栈(stack)和堆(heap):使用内存的两种方式。】
检测数据类型
typeof经常用来检测一个变量是不是最基本的数据类型。如
onsole.log(typeof 23); //输出:number
console.log(typeof 'abc123'); //string"
console.log(typeof true); //boolean
console.log(typeof x); //undefined
console.log(typeof undefined); //undefined
参见下图:
function stu(){} //定义一个函数
console.log(typeof stu); //输出:function
参见下图:
小结、typeof对基本类型(除null)和函数对象很方便,对于对象类型就没办法细分了。
比较特殊的是typeof null返回“object”。
历史原因,规范尝试修改typeof null返回“null”修改完大量网站无法访问,为了兼容,或者说历史原因返回"object"。
console.log(typeof null); //输出:"object"
对于数组等对象类型
var arr = [1,2,3];
console.log(typeof arr); //输出:"object"
对数组等对象的判断可用如下:
☆检验是否是null
Object.prototype.toString.call(null) === '[object Null]';//true
☆检验是否是数组
let a = [1,2,3]
Object.prototype.toString.call(a) === '[object Array]';//true
☆检验是否是函数
let a = function () {};
Object.prototype.toString.call(a) === '[object Function]';//true
☆检验是否是数字
let a = 1;
Object.prototype.toString.call(a) === '[object Number]';//true
☆检验是否是对象
let b = {}
Object.prototype.toString.call(a) === '[object Object]';//true
☆检验是否是undefined
Object.prototype.toString.call(undefined) === '[object Undefined]';//true
★null和undefined 类型
JavaScript 中的 null 表示一个空值(non-value),必须使用 null 关键字才能访问,undefined 是一个“undefined(未定义)”类型的对象,表示一个未初始化的值,也就是还没有被分配的值。我们之后再具体讨论变量,但有一点可以先简单说明一下,JavaScript 允许声明变量但不对其赋值,一个未被赋值的变量就是 undefined 类型。还有一点需要说明的是,undefined 实际上是一个不允许修改的常量。两者转化为值时不一样:
Number(null) // 0
Number(2 + null) // 2
Number(undefined) // NaN
Number(undefined + 2) //NaN
参见下图:
对于undefined:
①变量被声明了,但没有赋值时,就等于undefined。
②调用函数时,应该提供的参数没有提供,该参数等于undefined。
③对象没有赋值的属性,该属性的值为undefined。
④函数没有返回值时,默认返回undefined。
★number类型
JavaScript 采用“遵循 IEEE 754 标准的双精度 64 位格式”("double-precision 64-bit format IEEE 754 values")表示数字。——在JavaScript(除了BigInt)当中,并不存在整数或整型(Integer)。
console.log(2 / 3); // 输出:1.5
console.log(Math.floor(3 / 2)); // 1
console.log(0.1 + 0.2); //0.30000000000000004
JavaScript 支持标准的算术运算符,包括加法、减法、取模(或取余)等等。还有一个之前没有提及的内置对象 Math(数学对象),用以处理更多的高级数学函数和常数:
Math.PI ;//3.141592653589793
要小心NaN:如果把 NaN 作为参数进行任何数学运算,结果也会是 NaN:
NaN + 5; //NaN
可以使用内置函数 isNaN() 来判断一个变量是否为 NaN:
isNaN(NaN); // true
JavaScript 还有两个特殊值:Infinity(正无穷)和 -Infinity(负无穷):
1 / 0; // Infinity
-1 / 0; // -Infinity
可以使用内置函数 isFinite() 来判断一个变量是否是一个有穷数, 如果类型为Infinity, -Infinity 或 NaN则返回false:
isFinite(1/0); // false
isFinite(Infinity); // false
isFinite(-Infinity); // false
isFinite(NaN); // false
isFinite(0); // true
isFinite(2e64); // true
isFinite("0"); // true
如果是纯数值类型的检测,则返回 false:
Number.isFinite("0"); // false
可以使用内置函数 parseInt() 将字符串转换为整型。该函数的第二个可选参数表示字符串所表示数字的基(进制):
parseInt("123", 10); // 123
parseInt("010", 10); // 10
一些老版本的浏览器会将首字符为“0”的字符串当做八进制数字,2013 年以前的 JavaScript 实现会返回一个意外的结果:
parseInt("010"); // 8
parseInt("0x10"); // 16
这是因为字符串以数字 0 开头,parseInt()函数会把这样的字符串视作八进制数字;同理,0x开头的字符串则视为十六进制数字。
如果想把一个二进制数字字符串转换成整数值,只要把第二个参数设置为 2 就可以了:
parseInt("11", 2); // 3
JavaScript 还有一个类似的内置函数 parseFloat(),用以解析浮点数字符串,与parseInt()不同的地方是,parseFloat() 只应用于解析十进制数字。
一元运算符 + 也可以把数字字符串转换成数值:
+ "42"; // 42
+ "010"; // 10
+ "0x10"; // 16
备注: parseInt() 和 parseFloat() 函数会尝试逐个解析字符串中的字符,直到遇上一个无法被解析成数字的字符,然后返回该字符前所有数字字符组成的数字。但是运算符 "+"对字符串的转换方式与之不同, 只要字符串含有无法被解析成数字的字符,该字符串就将被转换成 NaN。可分别使用这两种方法解析“10.2abc”这一字符串,并比较得到的结果,来理解这两种方法的区别。
★string类型
avaScript 中的字符串是一串Unicode 字符序列。这对于那些需要和多语种网页打交道的开发者来说是个好消息。更准确地说,它们是一串UTF-16编码单元的序列,每一个编码单元由一个 16 位二进制数表示。每一个Unicode字符由一个或两个编码单元来表示。
如果想表示一个单独的字符,只需使用长度为 1 的字符串。
通过访问字符串的 length属性,可以得到字符串的长度。如:
"hello".length; // 5
字符串也有方法 (methods)能让你操作字符串和获取字符串的信息。如:
"hello".charAt(0); // "h"
"hello, world".replace("world", "mars"); // "hello, mars"
"hello".toUpperCase(); // "HELLO"
JavaScript的字符串,使用单引号和双引号没有特殊的区别,都可以用来创建字符串,但是一般情况下JavaScript使用单引号,而且单引号里面可以有双引号,双引号里面也可以有单引号;特殊情况下JavaScript需要使用转义符号"\",用(\")表示("),用(\')表示('),而在HTML中则是用"。
console.log("Broken \n lines"); //其中\n具有特殊意义
当配合转义字符\使用的时候,有些字符可以成为具有特殊意义的字符。下面是一些特殊字符的例子。
\n:换行符
\t:制表符
\b:退格
\r:回车
\\:反斜杠
\':单引号
\":双引号
字符串可以被视为字符数组,因此可以使用数组的方括号运算符,用来返回某个位置的字符(位置编号从0开始)。
字符串中每个字符都有特定的位置,首字符从位置 0 开始,第二个字符在位置 1,依此类推。这意味着字符串中的最后一个字符的位置一定是字符串的长度减 1,可以使用位置(索引)可以访问字符串中任何的字符:
var s = 'hello!';
s[0] // "h"
s[1] // "e"
s[4] // "o"
★boolean类型
false、0、空串("")、NaN、null和undefined都被视为false;其他的都被视为true。JavaScript中有三个布尔操作符:AND(&)、OR(|)和NOT(!)。
在JavaScript中有两种方法可以创建Boolean类型的值。
可以将字面量true或false赋给变量。考虑下面的例子:
var pBooleanTrue = true;
var pBooleanFalse = false;
使用Boolean()函数。这是个普通的函数,可以返回一个Boolean类型的原始值:
var fBooleanTrue = Boolean(true);
var fBooleanFalse = Boolean(false);
★symbol类型
内置的函数Symbol() 不能用 “new Symbol()”命令,因为 Symbol 是原始数据类型,不是对象。可以接受一个字符串作为参数,创建的 symbol类型值——表示独一无二的值,即每一个 Symbol 的值都是不相等的,不重复。
chrome 67+开始支持BigInt。目前Edge还不支持BigInt。
let sy = Symbol("KK");
console.log(sy); // Symbol(KK)
typeof(sy); // "symbol"
相同参数 Symbol() 返回的值不相等,如:
let sy1 = Symbol("kk");
sy === sy1; // false
目前Edge还不支持BigInt,故使用Chrome实验,参见下图:
★bigInt类型
JavaScript中的基本数据类Number是双精度浮点数,在浏览器控制台分别输入Number.MAX_SAFE_INTEGER和Number.MIN_SAFE_INTEGER可查看对应的最大/小值,参见下图:
BigInt是JavaScript中的一个新的原始类型,可以用任意精度表示整数。BigInt可以通过在整数末尾附加 n 或调用构造函数来创建。
chrome 67+开始支持BigInt。目前Edge还不支持BigInt。
要创建一个BigInt,在数字后面添加n后缀即可,如123n。全局BigInt(number)函数可以用来将Number转换成BigInt。换句话说,BigInt(123) === 123n。让我们用这两种技术来解决我们之前遇到的问题:
目前Edge还不支持BigInt,故使用Chrome实验:
参见上图:BigInt(Number.MAX_SAFE_INTEGER),JavaScript中的基本数据类Number是双精度浮点数,它可以表示的最大安全范围是正负9007199254740991。
1234567890123456789 * 123;
→ 151851850485185200000 明显是错误的,上面两个数字,末尾分别是9和3,9*3=27,然而结果末尾却是000。
1234567890123456789n * 123n;
→ 151851850485185185047n 这次我们得到了正确的结果。
JavaScript 的运算符
☆JavaScript 算数运算符
算数运算符用于对数字执行算数运算:
运算符 |
描述 |
+ |
加法 |
- |
减法 |
* |
乘法 |
/ |
除法 |
% |
系数 |
++ |
递加 |
-- |
递减 |
说明:++和--运算符
var a= 1;
var b= a++;
console.log(a); //2
console.log(b); //1
++和--操作符都是单目操作符,既可作为前缀,也可以作为后缀。它们所出现的位置很重要。当++作为前缀的时候,如++a,会先增加变量的值,然后再将该值从表达式返回,而不是像a++那样,先返回a的当前值,然后再增加。请看:
var a= 1;
var b= ++a;
console.log(a); //2
console.log(b); //2
☆JavaScript 赋值运算符
赋值运算符向 JavaScript 变量赋值:
运算符 |
例子 |
等同于 |
= |
x = y |
x = y |
+= |
x += y |
x = x + y |
-= |
x -= y |
x = x - y |
*= |
x *= y |
x = x * y |
/= |
x /= y |
x = x / y |
%= |
x %= y |
x = x % y |
例子:
var x = 7;
x += 8; //x=15
+ 和+=运算符也可用于对字符串连接。如:
txt1 = "Hello ";
txt1 += "Kitty!"; // Hello Kitty!
字符串和数字的相加
相加两个数字,将返回和,但对一个数字和一个字符串相加将返回一个字符串,如:
x = 7 + 8; //15
y = "7" + 8; //78
z = "Hello" + 7; // Hello7
完整的网页文件代码如下:
运算符示例1
对数字和字符串相加,会返回字符串。
将上述代码,保存文件名为:运算符示例1.html
运行之,参见下图:
☆JavaScript 比较运算符
运算符 |
描述 |
== |
等于 |
=== |
等值等型(严格相等) |
!= |
不相等 |
!== |
不等值或不等型(非严格相等) |
> |
大于 |
< |
小于 |
>= |
大于或等于 |
<= |
小于或等于 |
? : |
三元运算符 |
JavaScript提供两种相等关系:严格(strict)相等和非严格(loose)相等。从根本上而言,在比较两个值的时候,非严格相等会进行类型转换,而严格相等不进行类型转换。可以通过===执行严格相等比较,通过==执行非严格相等比较。
ECMAScript 6还提供了Object.is方法来进行类似于===的严格相等比较,但是Object.is会针对NaN做特别处理:-0和+0。当NaN===NaN和NaN==NaN的结果都为false时,Object.is(NaN, NaN)将返回true。
(1) 使用===的严格相等
严格相等在比较两个值的时候,不会进行任何隐式类型转换。比较过程中会应用以下规则。
严格相等是检查相等关系时应该使用的正确方法。应该设立这么一条规则:坚持使用===,避免使用==。
条件 |
输出 |
"" === "0" |
false |
0 === "" |
false |
0 === "0" |
false |
false === "false" |
false |
false === "0" |
false |
false === undefined |
false |
false === null |
false |
null === undefined |
false |
如果比较对象的话,可以得到如下结果:
条件 |
输出 |
{} === {} |
false |
new String('bah') === 'bah'; |
false |
new Number(1) === 1; |
false |
var bar = {}; bar === bar; |
true |
例子:
var n = 0;
var o = new String("0");
var s = "0";
var b = false;
console.log(n === n); // true - 数值相同
console.log(o === o); // true - 非数字类型比较
console.log(s === s); // true - 同上
console.log(n === o); // false - 不进行隐式类型转换,因此类型不相同
console.log(n === s); // false - 类型不同
console.log(o === s); // false - 类型不同
console.log(null === undefined); // false
console.log(o === null); // false
console.log(o === undefined); // false
(2) 使用==的非严格相等
不要使用这种形式的相等比较。说真的,离它越远越好。非严格相等有很多缺点,其主要原因在于JavaScript的弱类型化。相等操作符==在比较之前会先尝试转换类型。下面的例子展示了这个过程:
条件 |
输出 |
"" == "0" |
false |
0 == "" |
true |
0 == "0" |
true |
false == "false" |
false |
false == "0" |
true |
false == undefined |
false |
false == null |
false |
null == undefined |
true |
从这些例子中显然可以看出非严格相等会导致出人意料的结果。另外,隐式类型转换也会对性能产生影响。因此在JavaScript中,一般不要使用非严格相等。
☆JavaScript 逻辑运算符
运算符 |
描述 |
&& |
逻辑与 |
|| |
逻辑或 |
! |
逻辑非 |
例如:
console.log(false && (1 == 2));//返回false
console.log(false || (1 == 2));// 返回false
console.log(!(1 == 2));// 返回true
☆JavaScript 位运算符
运算符 |
用法 |
描述 |
按位与( AND) |
a & b |
对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。 |
按位或(OR) |
a | b |
对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。 |
按位异或(XOR) |
a ^ b |
对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。 |
按位非(NOT) |
~ a |
反转操作数的比特位,即0变成1,1变成0。 |
左移(Left shift) |
a << b |
将 a 的二进制形式向左移 b (< 32) 比特位,右边用0填充。 |
有符号右移 |
a >> b |
将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位。 |
无符号右移 |
a >>> b |
将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。 |
详见:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_AND
ECMAScript 整数有两种类型,即有符号整数(允许用正数和负数)和无符号整数(只允许用正数)。
有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数。数值范围从 -2147483648 到 2147483647。
下图展示的是数 18 的表示法:
请注意位的编号。从低位开始,第 1 位为位 0,第32 位为位31。
18 的二进制版本只用了前 5 位,它们是这个数字的有效位。把数字转换成二进制字符串,就能看到有效位:
var iNum = 18;
iNum.toString(2); //"10010"
负数也存储为二进制代码,不过采用的形式是二进制补码。
计算数字二进制补码的步骤有三步,现在以-18的二进制补码为例:
(1)确定该数字的非负版本的二进制表示(首先要确定 18 的二进制表示)
0000 0000 0000 0000 0000 0000 0001 0010
(2)求得二进制反码,即要把 0 替换为 1,把 1 替换为 0
1111 1111 1111 1111 1111 1111 1110 1101
(3)在二进制反码上加 1
1111 1111 1111 1111 1111 1111 1110 1101
1
----------------------------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110
记住,在处理有符号整数时,开发者不能访问 31 位(符号位)。
有趣的是,把负整数转换成二进制字符串后,ECMAScript 并不以二进制补码的形式显示,而是用数字绝对值的标准二进制代码前面加负号的形式输出(这是为避免访问位31)。例如:
var iNum = -18;
iNum.toString(2); //"-10010"
无符号整数把最后一位作为另一个数位处理。在这种模式中,第 32 位不表示数字的符号,而是值 231。由于这个额外的位,无符号整数的数值范围为 0 到 4294967295。对于小于 2147483647 的整数来说,无符号整数看来与有符号整数一样,而大于 2147483647 的整数则要使用位 31(在有符号整数中,这一位总是 0)。
把无符号整数转换成字符串后,只返回它们的有效位。
注意:在 ECMAScript 中,所有整数字面量都默认存储为有符号整数。只有 ECMAScript 的位运算符才能创建无符号整数。
位运算符直接处理每一个比特位(bit),位运算符只对整数起作用,如果一个操作数不是整数,会自动转为整数后再执行,如:遇到小数时,也会将小数部分舍去,只保留整数部分;对字符串将字符串转为数值。
二进制位或(or)运算符:符号为|,表示若两个二进制位都为0,则结果为0,否则为1。
二进制位与(and)运算符:符号为&,表示若两个二进制位都为1,则结果为1,否则为0。
二进制位非(否)(not)运算符:符号为~,表示对一个二进制位取反。
异或(xor)运算符:符号为^,表示若两个二进制位不相同,则结果为1,否则为0。
左移(left shift)运算符:符号为<<,将一个数的二进制值向左移动指定的位数,尾部补0,即乘以2的指定次方(最高位即符号位不参与移动)。
右移(right shift)运算符:符号为>>,将一个数的二进制值向右移动指定的位数,头部补0,即除以2的指定次方(最高位即符号位不参与移动)。
带符号位的右移(zero filled right shift)运算符:符号为>>>,将一个数的二进制形式向右移动,包括符号位也参与移动,头部补0。所以,该运算总是得到正值。对于正数,该运算的结果与右移运算符(>>)完全一致,区别主要在于负数。
位非(~)的处理过程:
可简化为:对该数求负,然后减 1。
~ 3 // -4
~ -3 //2
~2.3 //-3
~-2.3 //1
位与(&)的处理过程
逐位比较两个操作数,两个二进制位之中只要有一个位为0,就返回0,否则返回1。
0 & 3 // 0
说明,0(二进制00)和3(二进制11)进行二进制与运算会得到00(即0)。
位或(|)的处理过程
逐位比较两个操作数,两个二进制位之中只要有一个为1,就返回1,否则返回0。
0 | 3 // 3
说明,0和3的二进制形式分别是00和11,所以进行二进制或运算会得到11(即3)。
i = i | 0;
将i(不管是整数或小数)转为32位整数。利用这个特性,可以写出一个函数,将任意数值转为32位整数。
function toInt32(x) {
return x | 0;
}
上面这个函数将任意值与0进行一次或运算,这个位运算会自动将一个值转为32位整数。下面是这个函数的用法。
toInt32(1.001) // 1
toInt32(1.999) // 1
异或运算(^)在两个二进制位不同时返回1,相同时返回0。
0 ^ 3 // 3
上面表达式中,0(二进制00)与3(二进制11)进行异或运算,它们每一个二进制位都不同,所以得到11(即3)。
左移运算符(<<)表示将一个数的二进制值向左移动指定的位数,尾部补0,即乘以2的指定次方(最高位即符号位不参与移动)。
4 << 1 // 8
-4 << 1 // -8
右移运算符(>>)表示将一个数的二进制值向右移动指定的位数,头部补0,即除以2的指定次方(最高位即符号位不参与移动)。
4 >> 1 // 2
-4 >> 1 // -2
带符号位的右移运算符(>>>)表示将一个数的二进制形式向右移动,包括符号位也参与移动,头部补0。所以,该运算总是得到正值。对于正数,该运算的结果与右移运算符(>>)完全一致,区别主要在于负数。
4 >>> 1 // 2
-4 >>> 1 // 2147483646
☆其它运算符
typeof 返回操作数的类型。
Instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
. 读、写对象的属性,语法格式为:
对象.属性
[] 读、写数组的元素,或者读、写对象的属性,语法格式为:
数组[整数]
对象['属性名称']
() 控制表达式中的运算优先级等
new:创建实例对象或者调用函数,语法格式为:
new constructor[([arguments])]
运算符优先级从高到低
优先级 |
运算符 |
说明 |
结合性 |
1 |
[]、.、() |
字段访问、数组索引、函数调用和表达式分组 |
从左向右 |
2 |
++ -- -~!delete new typeof void |
一元运算符、返回数据类型、对象创建、未定义的值 |
从右向左 |
3 |
*、/、% |
相乘、相除、求余数 |
从左向右 |
4 |
+、- |
相加、相减、字符串串联 |
从左向右 |
5 |
<<、>>、>>> |
左位移、右位移、无符号右移 |
从左向右 |
6 |
<、<=、>、>=、instanceof |
小于、小于或等于、大于、大于或等于、是否 |
从左向右 |
7 |
==、!=、===、!== |
相等、不相等、全等,不全等 |
从左向右 |
8 |
& |
按位“与” |
从左向右 |
9 |
^ |
按位“异或” |
从左向右 |
10 |
| |
按位“或” |
从左向右 |
11 |
&& |
短路与(逻辑“与”) |
从左向右 |
12 |
|| |
短路或(逻辑“或”) |
从左向右 |
13 |
?: |
条件运算符(三元运算符) |
从右向左 |
14 |
=、+=、-=、*=、/=、%=、&=、|=、^=、<、<=、>、>=、>>= |
混合赋值运算符 |
从右向左 |
15 |
, |
多个计算(多重求值) |
按优先级计算,然后从右 |
圆括号用于改变由运算符优先级确定的计算顺序。 这就是说,先计算完圆括号内的表达式,然后再将它的值用于表达式的其余部分。如
result = 10 * (5 + 3); //80
原始类型(基本类型)字面量和内置构造函数
JavaScript中的原始类型(primitive type基本类型):数字、字符串、布尔值、bigInt、symbol、null、undefined。除了null、undefined、Symbol之外,其他三种都有对应的“包装对象”(wrapper object)。可以通过内置构造函数Number()、String()、Boolean()、BigInt()来生成包装对象。字面量比等价的内置构造函数要好用,参见下面的表格:
内置构造函数(不推荐使用) |
字面量语法和原始值(推荐使用) |
new String() |
如 "abc" |
new Number() |
如10、12.3 |
new Boolean() |
true、false |
new BigInt() |
如 10n |
为了说明数字原始值和数字对象之间的区别,看一下下面这个例子:
// 一个数字原始值
var n = 100;
console.log(typeof n); // "number"
// 一个Number对象
var nobj = new Number(100);
console.log(typeof nobj); // "object"
包装对象带有一些有用的属性和方法。比如,数字对象就带有toFixed()和toExponential()之类的方法,字符串对象带有substring()、chatAt()和toLowerCase()等方法以及length属性。这些方法非常方便,和原始值相比,这是包装对象的优势,但其实原始值也可以调用这些方法,因为原始值会首先转换为一个临时对象,如果转换成功,则调用包装对象的方法。
// 像使用对象一样使用一个字符串原始值
var s = "hello";
console.log(s.toUpperCase()); // "HELLO"
// 值本身也可以像对象一样
"monkey".slice(3, 6); // "key"
// 数字也是一样
(22 / 7).toPrecision(3); // "3.14"
因为原始值可以根据需要转换成对象,这样的话,也不必为了用包装对象的方法而将原始值手动“包装”成对象。比如,不必使用new String("hi"),直接使用"hi"即可。
// 避免这些:
var s = new String("my string");
var n = new Number(101);
var b = new Boolean(true);
// 更好更简洁的办法:
var s = "my string";
var n = 101;
var b = true;
不得不使用包装对象的一个场景是,有时我们需要对值进行扩充并保持值的状态。原始值毕竟不是对象,不能直接对其进行扩充。
// 字符串原始值
var greet = "Hello there";
// 为使用split方法,原始值被转换为对象
greet.split(' ')[0]; // "Hello"
// 给原始值添加属性并不会报错
greet.smile = true;
// 但实际上却没有作用
typeof greet.smile; // "undefined"
在这段示例代码中,greet只是临时被转换成了对象,以保证访问其属性、方法时不会出错。而如果是另一种情况,greet通过new String()被定义为一个对象,那么扩充smile属性的过程就会像我们预期的那样。对字符串、数字或布尔值进行扩充的情况很少见,因此建议只在确实有必要的情况下使用包装对象。
当省略new时,包装对象的构造函数将传给它的参数转换为原始值:
typeof Number(1); // "number"
typeof Number("1"); // "number"
typeof Number(new Number()); // "number"
typeof String(1); // "string"
typeof Boolean(1); // "boolean"
JavaScript中的对象可以简单地理解为键-值对(key-value pair)组成的散列表(hash table,也叫哈希表)。在其他编程语言中被称作“关联数组”。其中的值可以是原始值也可以是对象。不管是什么类型,它们都是“属性”(property),属性值同样可以是函数,这时属性就被称为“方法”(method)。
在JavaScript中除去原始数据类型,所有其它值都是对象。对象可以进一步分为:
原始值的包装类型:Boolean、Number、String、BigInt() ,但很少使用。
原始类型(基本类型)和对象的不同点
1)原始类型没有附加方法; 所以你永远不会看到undefined.toString()。 也正因为如此,原始类型是不可变的,因为它们没有附加的方法可以改变它:
var s = "boy";
s.bar = "girl";
console.log(s.bar); // undefined
而默认情况下,对象是可变的,可以添加方法:
var obj = {};
obj.foo = 123;
console.log(obj.foo); // 123
2)此外,与作为引用存储的对象不同,原始类型作为值本身存储。 这在执行相等性检查时会产生影响:
"dog" === "dog"; // true
14 === 14; // true
{} === {}; // false
[] === []; // false
(function () {}) === (function () {}); // false
原始类型按值存储,对象通过引用存储,存储地址也不同,原始类型直接存放在栈中,而对象是存放在堆里的。
【附注、以下类型生成的对象可以通过构造函数创建:
内置构造函数 |
原始值 |
无 |
null |
无 |
undefined |
无 |
symbol |
new String() |
如 "abc" |
new Number() |
如10、3.14 |
new Boolean() |
True、false |
new BigInt() |
如10n |
new Object() |
{} |
new Array() |
[] |
new RegExp("[a-z]","g") |
/[a-z]/g |
new Date() |
无 |
通常情况下,除了Date()之外,其他的内置构造函数并不常用。】
JavaScript类型转换
JavaScript是一种动态语言,并没有传统定义上的类型,但是有必要搞明白,JavaScript在内部是如何处理数据类型并进行强制转换(coercion)的——所有正式的JavaScript程序都少不了要以某种形式来处理值的强制转换,因此理解相关的概念很重要。
当自己动手修改类型的时候会发生显式强制转换(explicit coercion)。在下面的例子中,使用toString()将一个数字转换成了String类型,并从中提取出第二个字符:
var fortyTwo = 42;
console.log(fortyTwo.toString()[1]); //打印"2"
显式类型转换是通过具体的方法(函数)进行转换的方式。Number()方法是把变量转成数字类型;String()方法是把变量转成字符串类型;Boolean()方法是把变量转成布尔值类型。如:
let foo = "123";
let bar = 456;
typeof foo; //"string"
Number(foo); //123
typeof Number(foo); //"number"
注意:当一个变量不能转成数字类型时,会返回NaN,NaN表示变量值不是数字,但其类型却是数字类型。如:
let baz = "hi";
Number(baz); //NaN
typeof Number(baz); //"number"
在JavaScript中,提供了isNaN()的方法,用于判断当前变量是否为NaN,如果为NaN则返回true,如果不为NaN则返回false。如:
isNaN(Number(baz)); //true
isNaN(NaN); //true
隐式类型转换(Implicit type conversion)是通过运算的方式,自动进行转换的方式。
当数字与字符串相乘时,会自动把字符串转成数字类型,然后计算出结果。当数字与布尔值相乘时,会自动把布尔值转成数字类型,true会转成1,false会转成0,然后计算出结果。如:
"12" * 3; //36
2 * true; //2
2 * false; //0
需要注意+运算符,+除了表示加法,还表示连接。因此当数字与字符串相加时,并不会发生隐式类型转换,而其他运算符不表示连接,可以进行隐式类型转换。如:
2 + 5 //7
"2" + 5; //"25"
2 + true; //3
"2" + true; //"2true"
undefined表示未定义,而null表示已经定义,其值为空,因此,当隐式类型转换时,undefined不可以转换为数字,而null可以转换成0。具体示例代码如下:
2 * undefined; //NaN
2 * null; //0
再给出几个隐式转换的例子如下:
"123" - 1 结果是 122
[](空数组)+ [](空数组) 结果是 ""(空数组)
[](空数组) + {}(空对象) 结果是 "[object Object]"(字符串)
false(布尔值) + [](空字符串)结果是 "false"(字符串)
显式强制转换易于理解,可靠性也好;JavaScript也会基于某些猜测来更改值的类型,这叫作隐式强制转换(implict coercion)。这种猜测使得JavaScript解决了一些问题,但同时也遗憾地引发了一些悄无声息且出乎意料的错误。下面的代码片段展示了一些显式和隐式的强制转换:
var t=1;
var u=""+t; //隐式强制转换
console.log(typeof t); //"number"
console.log(typeof u); //"string"
var v=String(t); //显式强制转换
console.log(typeof v); //"string"
var x=null
console.log(""+x); //"null"
解释之,当t的值是数字(这里是1)的时候,""+t会使得JavaScript认为你要将某些内容和字符串""拼接在一起。因为只有字符串才能彼此拼接,所以JavaScript就先将数字1转换成字符串"1",然后再将两者拼接起来,形成最终的结果(字符串值)。这就是JavaScript实施隐式转换的过程。而String(t)则是一个意图非常明确的调用,用于将一个数字转换成String类型。这是一种显式类型转换。最后一行代码的结果有些让人意外。我们将null和""拼接在了一起,居然没有出错?
JavaScript是怎么做类型转换的?一个抽象值是怎么变成字符串、数字或者布尔值的?其实,JavaScript在内部是依靠toSting()、toNumber()和toBoolean()方法来实现这一切的。
当一个非String类型的值被强制转换成String类型时,JavaScript在内部使用的是toString()方法。所有的原始值都有对应的字符串形式——null的字符串形式是"null",undefined的字符串形式是"undefined",等等。
当非数字值需要被强制转换成数字时,JavaScript会在内部使用toNumber()方法:true变成1,undefined变成NaN,false变成0,null变成0。在字符串上使用toNumber()时会进行字面上的转换,如果转换失败,则返回NaN。
在JavaScript中,值有类型,变量没有。由于JavaScript的动态性质,变量可以随时保存任何类型的值。avaScript并不强制类型,也就是说语言本身并不要求变量中值的类型必须一直和初始类型相同。变量中可以保存字符串,下一次赋值时可以保存数字,等等。
var a = 1;
typeof a; // "number"
a = false;
typeof a; // "boolean"
JavaScript默认会很贴心地将原始值包裹起来形成包装对象,这样我们就可以直接访问包装对象的方法和属性,就好像这些方法和属性是原始值自带的一样。因此,可以实现类似于下面的操作:
var a="abc";
console.log(a.length); //3
console.log(a.toUpperCase()); //ABC
JavaScript 对象(Object) 类型
在 JavaScript 中,几乎所有的对象都是 Object 类型的实例,它们都会从 Object.prototype 继承属性和方法。
JavaScript 提供多个内建对象,比如Array 、Date、RegExp等等。 对象只是带有属性和方法的特殊数据类型。此外,JavaScript 允许自定义对象。
Array(数组)对象
JavaScript数组的目标是能组织存储各种各样的数据,并且访问方式和其它语言一样,特点是能混合存储类型不相同的数据——与其它程序语言不同的是,JavaScript的数组元素的数据类型可以不相同。数组元素:是指存储在数组中并赋予唯一索引号的数据段 。
一维数组示意图如下:
二维数组示意图如下:
创建数组的方式
☆创建一个空数组
数组在创建时可以不包含任何元素数据,即空数组。创建后返回一个数组对象,使用该对象可以往数组中添加元素。语法如下:
var Obj = new Array();
上述语句将创建一个空数组。变量Obj引用创建后的数组对象,通过此变量可以操作数组,Array()为数组对象的构造函数。
☆通过指定数组长度创建数组
在创建数组时可以指定数组的元素长度,通过这种方式可以创建一个有指定元素个数的数组对象 。语法如下:
var Obj = new Array( Size );
Size指明新建的数组有多少个元素。数组对象的length将被设置为Size,仅指定长度但没有实际填充元素及其数据的数组将得不到数据存储空间
☆通过指定数组元素创建数组
新建的数组将包含创建时指定的元素,通常用在数据已经准备就绪的场合。语法如下:
var Obj = new Array( 元素1, 元素2, …, 元素N );
如创建一个数组用于保存“Peter”、“Tom”、“Vicky”和“Jet”这几个学生的名字 :
var students = new Array( "Peter", "Tom", "Vicky", "Jet" ); // 通过指定元素创建数组
☆直接创建数组
JavaScript创建数组的另一种简便的方式是使用“[]”运算符直接创建,数组的元素也是创建时被指定。这种方法的目标也是创建数组,与前面的方法相比仅仅是语法上的不同 。语法如下:
var Obj = [ 元素1, 元素2, 元素3, …, 元素N ];
数组元素的基本操作
☆读取数组元素
读取数组元素最简单的方法就是使用“[]”运算符,此运算符在第四章已经讲过。使用“[]”运算符可以一次读取一个数组元素,语法如下:
数组名[下标索引];
目标元素通常由下标索引号决定,例如读取第一个元素为“数组名[0]”,依此类推 。
下面的代码从一个填有商品名字数组中读出第二种商品的名字:
var products = new Array( “洗衣粉”, “香皂”, “洗洁精” ); // 商品列表
var product = products[ 1 ]; // 取出第二种商品
☆添加数组元素
添加新元素通常使用Array对象的push方法,push方法是将新元素添加到数组的尾部。使用unshift可以将指定个数的新元素插入数组的开始位置,形成新的数组 ,下面是添加元素的一般形式:
var students = new Array(); // 创建一个没有任何元素的数组
students.push( “Lily” ); // 将Lily的名字添加到数组中
也可以使用“[]”运算符指定一个新下标来添加新元素,新元素添加到指定的下标处。如果指定的下标超过数组的长度,数组将被扩展为新下标指定的长度。
push方法一次可以添加单个元素或多个元素到数组末端。使用语法如下:
数组名.push( [ 元素1, [ 元素2, […, [元素N ] ] ] ] );
元素:可选项,可以是一个或多个JavaScript对象,使用“,”分隔。
在数组顶端插入元素
unshift是将元素插入数组的首部。一次可以插入单个或多个元素,所有元素按顺序插入,操作完成后返回新数组的引用。语法如下。:
数组名.unshift( [元素1, [ 元素2, [ 元素3, […, [元素N ] ] ] ] ] );
☆删除数组元素
通常使用delete运算符删除一个指定的元素,如果需要删除全部元素只需要删除数组对象即可。使用语法如下:
delete 数组名[下标];
例如,使用数组作为学生名单,现要删除数组中第一个元素,代码如下:
var names = Array( “李莉”, “杨杨” ); // 有两个名字的名单
delete names[0]; // 删除第一名字“莉莉”
删除数组的最后一个元素
pop方法的作用是移除数组末尾的一个元素。前面讲过使用delete运算符删除指定的元素,与delete不同,pop方法删除最后一个元素后还将其返回。 语法如下:
数组名.pop();
移除数组顶端的元素
pop方法是移除数组末端的一个元素,而shift方法正好相反,其移除数组的第一个元素并将其返回。该方法执行后数组剩下的元素向前移动,下标索引号重新调整从0开始按顺序赋予所有元素。Shift的语法如下:
数组名.shift( );
在基本数据结构中,队列非常有用,其遵循选进先出(FIFO)的规则,与堆栈不同。shift和push方法结合使用,可以将数组当成队列使用。
☆将数组转换为字符串
toString方法将数组表示为字符串,各个元素按顺序排列组合成为字符串返回 。语法:
对象名.toString( [radix] );
其中,radix为可选项参数,表示进制。当对象是数字对象时,该参数起作用。对象名是数组对象变量名,方法执行后各元素以“,”隔开按顺序加入字符串中 。
☆将数组元素连接成字符串
可以使用join方法将各元素组合为字符串,连接符号由用户指定。语法如下:
数组名.join(分隔符);
其中,分隔符:必选项,是一个字符串串对象,作为各元素间的分隔字符串。
☆颠倒数组元素的顺序
可以使用reverse方法将一个Array对象中所有元素的次序反转,然后返回元素顺序。语法:
数组名.reverse( );
☆对数组元素进行排序
Array对象的sort方法可以将一个数组中的所有元素排序。执行时先将调用该方法的数组中的元素按用户指定的方法进行排序,排序后的所有元素构成一个新数组并返回之。通常用来对数据排序,语法如下:
数组名.sort( [ sortfunction ] )
其中,sortfunction:可选项。用来确定元素顺序的函数的名称。如果这个参数被省略,那么元素将按照ASCII字符顺序进行升序排列。
负值:表示传给sortfunction两个实参中,第一个的值比第二个的小。
零:表示传给sortfunction两个实参的值相等。
正值:表示传给sortfunction两个实参中,第一个的值比第二个的大。
☆将多个数组的元素连接一起成为新的数组
concat方法可以将多个数组的元素连接一起成为新的数组,新数组中的元素按连接时的顺序排列。当需要合并多个数组时,此方法比较方便。语法如下:
数组名.concat( [ item1, [ item2, [ item3 , […, [ itemN ] ] ] ] ] );
其中,item:可选项,要连接到“数组名”引用的数组末尾的其它项目。可以是数组对象也可以是单个数组元素,或者是其它JavaScript对象。
☆删除、替换或插入数组元素
splice方法的作用是,从一个数组中移除一个或多个元素。剩下的元素组成一个数组,移除的元素组成另一个数组并返回它的引用。同时,原数组可以在移除的开始位置处顺带插入一个或多个新元素,达到修改替换数组元素的目的。 语法
数组名. splice( start, deleteCount, [ item1 [, item2 [ , . . . [ , itemN ] ] ] ] );
其中:
start:必选项,表示从数组中剪切的起始位置下标索引号。
deleteCount:必选项,表示将从数组中切取的元素的个数。
item:可选项,表示切取时插入原数组切入点开始处的一个或多个元素。
☆从数组中返回选定的元素
slice()方法语法
数组名.slice(start, end)
其中
start 规定从何处开始选取。如果是负数,那么它规定从数组尾部开始算起的位置。如果该参数为负数,则表示从原数组中的倒数第几个元素开始提取,slice(-2) 表示提取原数组中的倒数第二个元素到最后一个元素(包含最后一个元素)。
end 规定从何处结束选取。该参数是数组片断结束处的数组下标。如果没有指定该参数,那么切分的数组包含从 start 到数组结束的所有元素。如果该参数为负数, 则它表示在原数组中的倒数第几个元素结束抽取。 slice(-2,-1) 表示抽取了原数组中的倒数第二个元素到最后一个元素(不包含最后一个元素,也就是只有倒数第二个元素)。
slice() 方法不会改变原始数组。
☆查找数组中某个指定的元素位置。
语法
数组名.indexOf(item,start)
其中:
item 必须。查找的元素。
start 可选的整数参数。规定在数组中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字符串的首字符开始检索。
indexOf()方法用于确定一个数组项在当前数组中的位置,会返回一个数字,如果匹配成功则返回匹配到的数组项位置,如果匹配不成功则返回-1。具体示例代码如下:
方法用于确定一个数组项在当前数组中的位置,会返回一个数字,如果匹配成功则返回匹配到的数组项位置,如果匹配不成功则返回-1。示例如下:
let arr = ['abc' ,'x' ,10, 5];
let f = arr.indexOf('x');
console.log(f); //1
☆数组元素的个数
数组对象的length(长度)属性指示了数组元素的个数。
通过设定length属性可以指定数组的长度。
在得知长度情况下可以方便的遍历整个数组,读取数组元素个数信息的方法如下代码所示:
var Obj = new Array( 1, 2, 3 );
var count = Obj.length;
指定了数组的length属性,真正的有效元素只包含已经存入数据的元素,其它没有真正填充数据的元素仍然为空。
下面给出示例:
var list = ['a','b','c']
var list2 = ['d','e']
(1)数组中元素的数目:list2.length = 2
(2)在一个数组中添加另一个数组中的元素:list.concat(list2) = ['a','b','c','d','e']
(3)数组中的元素组合字符串:join()
(4)删除并返回数组的最后一个元素pop()
(5)数组的末尾添加一个或多个元素push()
例如:
var list = ['a','b','c']
var list2 = ['d','e']
list2.length; //2
list.concat(list2); //["a", "b", "c", "d", "e"]
list.join('.'); //"a.b.c"
list.pop(); //"c"
list; // ["a", "b"]
list2.push('x'); //
list2; //["d", "e", "x"]
参见下图:
(6)slice() 方法可从已有的数组中返回选定的元素
(7) sort() 方法用于对数组的元素进行排序,是按照字符编码的顺序进行排序
例如:
var arr = new Array(6);
arr[0] = "G";
arr[1] = "J";
arr[2] = "T";
arr[3] = "Ja";
arr[4] = "A";
arr[5] = "M";
document.write(arr);
document.write("
");
document.write(arr.slice(2,4) + "
"); //从数组中返回选定的元素
document.write("
");
document.write(arr.sort()); //排序
将上述代码,保存文件名为:数组.html
运行之,参见下图:
(8) splice()从数组中添加或删除元素,然后返回被删除的数组元素。
splice()语法:arrayObject.splice(index,howmany,item1,.....,itemX)
说明①:index表示从什么位置开始添加或删除数组元素
②:howmany表示删除的元素数量,如果为0,则表示不删除数组元素
③:item1,.....,itemX表示新增的数组元素
④:splice()方法会改变原始数组
数组的map() 方法
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
数组名.map(function(currentValue,index,arr), thisValue)
其中:
function(currentValue, index,arr)
必须。函数,数组中的每个元素都会执行这个函数。
currentValue 必须。当前元素的值
index 可选。当前元素的索引值
arr 可选。当前元素属于的数组对象
thisValue
可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue,或者传入 null、undefined,那么回调函数的 this 为全局对象。使用数组对象的map() 方法的例子:
使用数组对象的map() 方法的例子
点击“开始”按钮获取数组元素的平方根。
将上述代码,保存文件名为:使用数组对象的map() 方法的例子.html
运行之,参见下图:
Date对象
JavaScript并没有日期数据类型。不过,可以在应用程序中使用Date对象及其方法来处理日期和时间。
JavaScript处理日期的方法和Java类似。在JavaScrpt中,日期被存储为自1970年1月1日00:00:00起的毫秒数。
可以使用以下声明创建一个Date对象:
var dataObject = new Date([parameters]);
Date对象构造函数的参数如下。
不提供参数,创建的是当前的日期和时间。例如:
var today = new Date();
描述日期的字符串,形如Month day, year hours:minutes:seconds。例如:
var twoThousandFifteen = new Date("December 31, 2015 23:59:59");
如果忽略了时、分或秒,这些值会被设置为0。
一组表示年、月、日的整数。例如,var christmas = new Date(2015, 11, 25);。
一组表示年、月、日、时、分和秒的整数。例如,var christmas = new Date(2015, 11, 25, 21, 00, 00);。
在JavaScript中创建及处理日期的示例如下:
var today = new Date();
console.log(today.getDate()); //显示获取的星期的某一天的数字
console.log(today.getMonth()); //显示获取的月份的数字【注】
console.log(today.getFullYear()); //
console.log(today.getHours()); //
console.log(today.getMinutes()); //
console.log(today.getSeconds()); //
//自1970年1月1日00:00:00 UTC之后的毫秒数
console.log(today.getTime()); //
console.log(today.getTimezoneOffset()); //
Date.getMonth返回值是0(1月)~11(12月)之间的一个整数。
【注】Date对象用1表示一个月中的第一天,但用0表示一年中的第一个月。
关于JavaScript Date 对象,可参见JavaScript Date 对象_w3cschool