15 数据类型

15.0 原始类型的方法

在JavaScript中,诸如字符串、数字等原始类型也有其方法。对原始类型调用方法时,看起来似乎是直接对原始类型调用的方法,其实不然。因为原始类型不是对象,所以并没有方法,只有对象才有方法。JavaScript引擎会先从这些原始类型中创建一个可实现的对象,然后调用对象的方法,最后销毁这个对象。这样就实现了对原始类型调用方法。

15.1 数字类型

数字中的e

在实际运用中,如果我们想令一个变量等于十亿。一般情况下,我们可以这样写:

let number = 1000000000;

但这样写我们需要连续输入好多个0,过于繁琐,。这时,JavaScript提供了一种全新的方式。

let number = 1e9;  // 也是十亿

其中,e 后面的正数代表前面数字后 0 的个数。

同理,e 也可以表示小数:

let number = 1.2e-2;  // 等价于0.012

其中,e 后面的负数代表小数点后几位。

特殊的进制数字

0x为十六进制数字的前缀,常用来表示颜色;

0b为二进制数字的前缀;

0o为八进制数字的前缀;

toString(base)方法

该方法需要传入一个参数base,用于将源数字转换为base进制的数字:

let number = 255;alert( number.toString(16) );  // 转换成16进制 ff
alert( number.toString(2) );  // 转换成2进制 11111111

使用两个点来调试方法

alert( 255..toString(16) );

如果使用一个 . ,JavaScript会认为其是一个小数点而非方法调用操作符。因此使用需要使用两个点。第一个 . 代表小数点,后面是空的代表小数部分为0。第二个 . 为方法调用操作符,代表调用number对象的toString(base)方法。也可以写成如下形式:

alert( (255).toString(16) );

使用括号包裹同样也可以解决此问题。

舍入

Math.floor()

向下取整,

3.1 => 3;

3.7 => 3;

-1.1 => -2;

-1.6 => -2;

Math.ceil()

向上取整,

3.1 => 4;

3.7 => 4;

-1.1 => -1;

-1.6 => -1;

Math.round()

就近取整,

3.1 => 3;

3.7 => 4;

-1.1 => -1;

-1.6 => -2;

Math.trunc() IE浏览器不支持

抹去小数点后的数字

3.1 => 3;

3.7 => 3;

-1.1 => -1;

-1.6 => -2;

总结
Math.floor() Math.ceil() Math.round() Math.trunc()
3.1 3 4 3 3
3.7 3 4 4 3
-1.1 -2 -1 -1 -1
-1.6 -2 -1 -2 -1

将数字舍入到小数点后n位:

eg:将1.234舍入到小数点后一位

1.先给数字乘以10的幂次,再调用上面的舍入函数。

alert( Math.floor( (1.23456 * 100) ) / 100 );  // 1.23456 => 123.456 => 123 => 1.23

2.使用函数toFixed(n)将数字保留到小数点后n位,但返回的是字符串

let num = 1.23456;alert( num.toFixed(2) );  // 1.23

toFixed(n)函数类似于Math.round()函数,为就近舍入。

不精确的计算

在JavaScript内部,数字是以 64 位格式 IEEE-754 表示的,所以正好有 64 位可以存储一个数字:其中 52 位被用于存储这些数字,其中 11 位用于存储小数点的位置(对于整数,它们为零),而 1 位用于符号。

如果一个数字太大,就会导致溢出,其值为Infinity:

alert( 1e500 );  // Infinity

但常遇到的往往是精度损失,会出现下面这样神奇的情况:

alert( 0.1 + 0.2 == 0.3 );  // false

这是因为采用二进制计数时,只有2的整数次幂才是整数,其他均为无限小数。所以

0.1 + 0.2 实质为0.30000000000000004,的确不等于 0.3。

为避免这一问题,我们最好在有浮点数参与运算时使用toFixed(n)函数设置其保留位数:

alert( +(0.1 + 0.2).toFixed(2) == 0.3 );  // true,+将其转换为数字类型

isNaN()和isFinite()

isNaN()函数可以判断被检测的对象是否是NaN,它会先将源对象转换为number类型,再进行判断。

可是我们为什么需要这个函数?用 源对象 == NaN 判断不可以吗?

事实上,NaN与其他任何东西都不相等,包括其自身:

alert( NaN == NaN );  // false

因此,判断源对象是否为NaN类型,只能使用isNaN()函数。

isFinite()函数可以判断源对象是否为正常的数字,它会先将源对象转换为number类型,再进行判断。

如果是普通的数字,则返回true;如果是Infinity,NaN,undefined等特殊的形式,则返回false。

正如前文中所提到的,空字符和只带有空格的字符会被转换为0,因此会返回true。

parseInt()和parseFloat()

对于普通的字符串,使用 + 或Number()可以将其强制转换为number类型,但如果字符串中带有字符,则会出现错误。

在实际运用过程中,常常有这样的形式:CSS中常见的"100px",商品价格常见的“100元”。

这时,就需要用到parseInt()和parseFloat()

它们可以将字符串转换为number类型的数字,如果遇到错误,则返回之前转换的结果。

parseInt()返回整数,而parseFloat()返回浮点数:

alert( parseInt("100px") );  // 100,遇到"p"时发生错误,停止转换并返回100
alert( parseFloat("200元") );  // 200,遇到"元"时发生错误,停止转换并返回200alert( parseFloat("8.5元") );  // 8 遇到"."时发生错误,停止转换并返回8
alert( parseFloat("8.5元") );  // 8.5 遇到"元"是发生错误,停止转换并返回8.5

其他数学函数

JavaScript中有一个Math对象,里面存放了一些常用的数学函数和常量,例如:

Math.random( )可以返回一个在 [0, 1) 区间内的随机数

Math.max( ) /Math.min( ) 可以返回序列中的最大值/最小值

Math.pow(x, n) 可以计算 x 的 n 次幂

需要时可以翻阅Math对象的说明查看

15.2 字符串类型

反引号允许字符串跨行,单引号和双引号不允许。

let test = `
This
is
a
test.
`;

字符串长度

字符串对象的length属性表示字符串的长度:

alert( "test".length );  // 4

特别注意length为字符串的属性,而不是函数,所以后面没有 ()

访问字符

类似Python,要访问位于 pos 的字符,可以使用方括号 [ ]

let test = 'test';alert( test[0] );  // t

如果下标越界,则返回undefined

let test = 'test';alert( test[4] );  // undefined

字符串是不可变的

通常的解决方法是将改变后的字符串赋值给新的变量。

大小写转换

字符串对象方法:toLowercase() 和 toUppercase()可以将字符串变为小写或大写。

let test1 = 'test';
let test2 = 'TEST';alert( test1.toUpperCase() );  // TEST
alert(test2.toLowerCase() );  // test

查找字符串

字符串对象方法:str.indexOf(target, position)

target为要查找的字符串对象,position是可选的起始位置,不传入默认从头开始。如果找到该字符串,则返回该字符串第一次出现的位置;如果未找到该字符串,则返回-1。

let test = 'This is a test.';alert( test.indexOf("is") );  // 2 查找到"This"中的"is",返回2
alert( test.indexOf("is", 4) );  // 5 从" "开始,查找到"is",返回5
alert( test.indexOf("no") );  // -1 未找到,返回-1

由于未找到字符串时返回-1,在配合if语句使用时可以进行简写:

let test = "This is a test.";if( test.indexOf("is") != -1 ) {alert("Found it!");
}

可以简写为:

let test = "This is a test.";if(~test.indexOf("is")) {alert("Found it!");
}

这是因为 ~ 是按位取反运算符,它将数字转换为32bit整数,然后按位取反。

最终效果为:~n = -(n+1)

因此,当结果为 -1 时,按位取反结果为 -(-1+1) = 0 刚好为 false。

但不建议这样使用。

现代方法

现代字符串方法:str.includes(substr, pos)

可以根据字符串中有无包含substr字符串来相应的返回true和false。同样,pos可以指定开始匹配位置。

let test = "This is a test.";alert(test.includes("te"));  // true

现代字符串方法:str.starsWith(substr)

可以根据字符串开头有无包含substr字符串来返回true和false。

let test = "This is a test.";alert(test.startsWith("Th"));  // true

现代字符串方法:str.endsWith(substr)

可以根据字符串结尾有无包含substr字符串来返回true和false。

let test = "This is a test.";alert(test.endsWith("st."));  // true

获取子字符串

str.slice(star[, end]) 方法

同Python的字符串切片,返回star和end之间的字符串。同样为左闭右开区间,即[star, end)。

如果没有传入end参数,则会返回从star到字符串结尾的字符串。

star和end参数同样也可以为负值。

let test = "This is a test.";alert(test.slice(0, 4));  // "This"

str.substring(star[, end]) 方法

与slice几乎相同,但支持star > end,不支持star和end为负值。

let test = "This is a test.";alert(test.substring(0, 4)); // "This"
alert(test.substring(4, 0)); // "This"

str.substr(star[, length]) 方法

返回从star开始,长度为length的字符串

let test = "This is a test.";alert(test.substr(0, 7));  // "This is"
总结
str.slice(star[, end]) 返回从star到end之间的字符串,star和end可以为负值
str.substring(star[, end]) 返回从star到end之间的字符串,star可以大于end,但star和end不能为负值
str.substr(star[, length]) 返回从star开始,长度为length的字符串

字符串转换

字符串对象方法:str.codePointAt(pos)可以返回pos位置字符的unicode编码

let test = "This is a test.";alert(test.codePointAt(0) );  // "T" 84

函数:String.fromCodepoint(code)可以将unicode编码转化为字符:

alert( String.fromCodePoint(84) );  // T

15.3 数组

JavaScript中的数组可以存储任何类型的变量,可以是数字类型、字符串类型、甚至函数,其本质是一种对象。

创建数组非常简单:

let array = new Array();  // 从构造器创建
let array = [];  // 绝大多数情况下采用此方法创建

数组方法

JavaScript中的数组既可以当做队列使用,也可以当做栈来使用。

push() 方法

向数组末尾添加一个元素

let array = [];array.push("test");alert(array);  // test

pop() 方法

取出数组末尾最后一个元素

let array = [1, 2, 3, 4];alert(array.pop());  // 4
alert(array);  // 1, 2, 3

shift() 方法

取出数组首段第一个元素

let array = [1, 2, 3, 4];alert(array.shift());  // 1
alert(array);  // 2, 3, 4

unshift() 方法

在数组首段添加元素

let array = [];array.unshift(0);alert(array);  // 0 

值得注意的是,push() 和 unshift() 方法都可以一次性添加多个元素:

let array = [];array.unshift(0, 1, 2);alert(array);  // 0, 1, 2array = [];array.push(0, 1, 2);alert(array);  // 0, 1, 2

在性能上,push() 和 pop() 方法运行的速度比较快,而shift() 和 unshift() 方法运行的比较慢

因为在首端进行操作需要对数组进行重新编号,大大减慢了运行速度。

splice() 方法

splice()方法的泛用性较强,可以用来删除、添加和替换元素,其语法规则如下:

arr.splice(start[, deleteCount, elem1, ..., elemN])

表示:从数组的start下标的元素开始计数,将其后deleteCount个元素替换为eleme1, ..., elemN

因此,将deleteCount设置为1,eleme1, ..., elemeN设置为空即可实现删除操作。

let array = ["This", "is", "a", "test"];array.splice(0, 0, "test")  // 在下标为0处添加test元素alert( array );  // test,This,is,a,test

被添加的元素个数大于deleteCount即可实现添加操作。

let array = ["This", "is", "a", "test"];array.splice(0, 0, "test")  // 在下标为0处添加test元素alert( array );  // test,This,is,a,test

只需要使替换元素的个数大于deleteCount即可实现添加元素:

let array = ["This", "is", "a", "test"];array.splice(0, 1)  // 从下标为0处开始计数,将一个元素替换为空,等价于删除下标为0的元素alert( array );  // is,a,test

该方法同样支持负向索引。

slice() 方法

slice() 方法是splice的简化版,语法如下:

arr.slice([start], [end])

表示将该数组的start到end之间的元素复制到一个新数组中并返回该数组,注意为左闭右开区间

let array = ["This", "is", "a", "test"];let new_array = array.slice(1, 4);  // 左闭右开区间alert( new_array );  // is,a,test

该方法同样支持负向索引。

concat() 方法

concat() 方法可以进行数组的复制,其语法如下:

arr.concat(arg1, arg2...)

该方法会按先后顺序复制括号内的参数,将其连接到源数组的后方,最后返回新数组:

let array = ["This", "is"];let new_array = array.concat(["a", "test"]);  // 将a, test连接到array后方alert( new_array );  // This,is,a,test

forEach() 方法

该方法可以为数组中的每一个元素执行一个函数操作,其语法如下:

arr.forEach(function(item, index, array) {// ... do something with item
});

例如:

// 对每个元素调用 alert
["Bilbo", "Gandalf", "Nazgul"].forEach(alert);

循环

因为数组是一种特殊的对象,所以从理论上来说可以使用对象的for...in...循环,但一般不在数组中使用,因为for...in...不仅仅会遍历到数组中的元素,还会遍历到其属性。

因此,数组一般使用类似的for...of...循环:

let fruits = ["Apple", "Banana", "Orange"];for (let fruit of fruits) {alert(fruit);  // 依次显示Apple, Banana, Orange
}

当然,类似C语言式的遍历也是可行的。

关于length

数组的length属性是可以被修改的。手动增加length的数值,什么都不会发什么。

但手动减小length的数值,数组会被截断。所以,清空数组最简单的方法就是array.length = 0。

多维数组也同样适用

不要使用==比较数组

如果使用==来比较数组,其过程和==比较对象的过程相同。

搜索

和字符串一样,数组也能使用arr.indexOf/lastindexOf和arr.includes方法,作用也同字符串相同。

需要注意的是,这些方法使用的比较为严格比较,即 === ,在比较时不进行类型转换。

find和findindex

在实际使用中,数组中可能存储对象,这是就需要用到find函数,其语法规则如下:

let result = arr.find(function(item, index, array) {// 如果返回 true,则返回 item 并停止迭代// 对于假值(falsy)的情况,则返回 undefined
});

例如,我们想要找到 id==1 的用户:

let users = [{id: 1,name: 'LiMing'},{id: 2,name: 'XiaoGang'},{id: 3,name: 'LiHua'},
]let user = users.find(item => item.id == 2);alert(user.name); // XiaoGang

arr.findIndex方法和arr.find方法基本相同,但它返回被找到元素的索引,未找到时返回 -1

filter方法

与arr.find方法类似,但它返回所有满足条件的对象所组成的数组,其语法规则如下:

let results = arr.filter(function(item, index, array) {// 如果 true item 被 push 到 results,迭代继续// 如果什么都没找到,则返回空数组
});

例如:

let users = [{id: 1,name: 'LiMing'},{id: 2,name: 'XiaoGang'},{id: 3,name: 'LiHua'},
]let some_users = users.filter(item => item.id < 3);  // 找到所有id小于3的对象alert(some_users.length); // 2

转换数组

map

它会对数组中的每一个元素都执行一个函数,其语法规则如下:

let result = arr.map(function(item, index, array) {// 返回新值而不是当前元素
})

例如:

let users = ['LiMing', 'LiHua', 'XiaoGang'];let lengths = users.map(item => item.length);  // 将数组中的元素转换为其长度alert(lengths);  // 6 5 8

sort

sort函数可以对数组进行原地排序,它会改变原来的数组。默认情况下,其按字符串顺序排序,但可以传入函数,按照函数返回值的大小来进行排序。这样就可以实现自定义排序内容。

let numbers = [2, 15, 3];numbers.sort();  // 默认按字符串顺序排序alert(numbers);  // 15 2 3
let numbers = [2, 15, 3];function compareNumberic(a, b) {if (a > b) return 1;if (a == b) return 0;if (a < b) return -1;
}numbers.sort(compareNumberic);  // 按数字大小进行比较alert(numbers); // 2 3 15

比较函数还可以进行简写:

let numbers = [2, 15, 3];numbers.sort((a, b) => a - b);alert(numbers); // 2 3 15

reverse

reverse方法可以颠倒数组中元素的顺序:

let numbers = [2, 15, 3];numbers.reverse();alert(numbers); // 3 15 2

spilt和join

同Python,这里不再赘述。

reduce

reduce方法也可以遍历数组,不同与for...of的是,它可以使用数组前一位调用的结果,其语法规则如下:

let value = arr.reduce(function(accumulator, item, index, array) {// ...
}, [initial]);

其中,accumulator为上一次的调用后的值,item, index, array的意思同之前,initial代表初始值。

例如:

let numbers = [1, 2, 3];let result = numbers.reduce((sum, item) => sum + item, 0); // 实现数组的累加alert(result);  // 6

建议总是设定初始值,否则在数组为空时会出现错误。

判断是否是数组

数组是基于对象的,因此使用typeof运算符或typeof()函数均不能将数组和对象区分开:

alert(typeof {});  // object
alert(typeof []);  // object

使用Array.isArray()方法可以判断:

alert(Array.isArray([]));  // true

JavaScript学习笔记(二)相关推荐

  1. JavaScript学习笔记之数组(二)

    JavaScript学习笔记之数组(二) 1.['1','2','3'].map(parseInt) 输出什么,为什么? ['1','2','3'].map(parseInt)//[1,NaN,NaN ...

  2. amazeui学习笔记二(进阶开发4)--JavaScript规范Rules

    amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...

  3. JavaScript 学习笔记(二)

    JavaScript 学习笔记(二) 文章目录 JavaScript 学习笔记(二) 一 JSON 1. JSON 对象 什么是JSON对象 JSON对象与Javascript对象的区别 在JavaS ...

  4. GEE(Google Earth Engine) 最基础代码学习笔记二 —— JavaScript 语言

    GEE(Google Earth Engine) 学习笔记二 Javascript 语言 1. 注释 print('Hello World!'); 如果要注释,则在代码前面加//,比如: // pri ...

  5. JavaScript学习笔记(十五)

    JavaScript学习笔记(十五) 事件 事件是DOM(文档对象模型)的一部分.事件流就是事件发生顺序,这是IE和其他浏览器在事件支持上的主要差别. 一.事件流 1.冒泡型事件 IE上的解决方案就是 ...

  6. Mr.J-- jQuery学习笔记(二十一)--模拟微博页面

    先看之前的节点操作方法:Mr.J-- jQuery学习笔记(二十)--节点操作方法 Mr.J-- jQuery学习笔记(五)--属性及属性节点 Mr.J-- jQuery学习笔记(十一)--事件委托  ...

  7. JavaScript学习笔记(六)--数组

    数组初始化 我们都知道,数组是用于保存多个值的集合,在数组中,值被称为元素,值可以是任意的数据类型.在Javascript中,创建数组通常有两种方式:字面量和构造函数. 字面量 数组的元素可以是任意的 ...

  8. JavaScript学习笔记:创建、添加与删除节点

    JavaScript学习笔记:创建.添加与删除节点 文章目录 JavaScript学习笔记:创建.添加与删除节点 一.DOM对象节点类型 二.创建节点 1.创建元素节点 2.创建文本节点 3.创建属性 ...

  9. JavaScript 学习笔记(第三天)

    JavaScript 学习笔记(第三天) 一.数组 1.1.数组的基础 1.2.数据类型分类 1.3.创建数组 1.3.1.字面量创建一个数组 1.3.2.内置构造函数创建数组 1.4.数组的基本操作 ...

  10. JavaScript学习笔记(九)(验证框架,layer弹出层)

    JavaScript学习笔记(九) 一.jQuery Validate验证框架 1.引入相关插件路径 2. 修改一些规则 3. 自定义验证规则 4.异步验证 整体代码 二.layer弹出层 1.引入相 ...

最新文章

  1. arduino 温度调节器_多点测平均温度实现智能控制(arduino-ds18b20)
  2. 实例介绍,如何在开发中将各层日志归类输出.
  3. Xmpp实现简单聊天系列 --- ②用户注册和登陆
  4. List集合的迭代器方法
  5. SQL Server如何查看存储过程的执行计划
  6. 统计指定目录下的视频时长
  7. MongoDB的排除查询$ne缺陷
  8. 电灯泡实验应该怎么做_英文论文润色应该怎么做
  9. 利用vs 分析DMP文件、pdb文件定位release下的异常崩溃
  10. 本特利传感器330103-00-05-10-02-00
  11. 二元二次方程例题_二元二次方程练习题.doc
  12. iOS 单元测试 Tests 和 UITests
  13. 小米手机系统服务组件是干什么的_2799 元!小米 1 亿像素拍照手机来了,还有 MIUI 系统的小米手表...
  14. WinEdt10.3 激活
  15. [转]firefox浏览器油猴脚本-让网页背景成苹果蓝,保护眼睛
  16. 矩阵的Jordan分解实例
  17. Word中的图片设置嵌入式之后显示不全问题
  18. Chrome 出现“您未安装Flash Player播放器或者版本过低”问题
  19. Android Studio 安卓微信底部界面(带消息红点)代码
  20. Android 百度在线语音识别

热门文章

  1. 西电计组实验一 存储器实验
  2. 使用DeepWalk从图中提取特征
  3. keil stm32标准库放在哪里_STM32(1)——使用Keil MDK以及标准外设库创建STM32工程...
  4. java中for(int a:list)
  5. element-UI el-dialog组件按ESC键关闭不了弹窗
  6. 现代密码学(五) 数论和密码学困难性假设
  7. 遇见一只黑猫,她说Python是个怪物
  8. 基于keil5 的stm32F103C8T6的ST-LINK V2的仿真器使用
  9. 【高等数学】伯努利方程及其求解方法
  10. 怎么用色环搭配颜色?色环搭配常用色彩组合有哪些?