JavaScript学习笔记(二)
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学习笔记(二)相关推荐
- JavaScript学习笔记之数组(二)
JavaScript学习笔记之数组(二) 1.['1','2','3'].map(parseInt) 输出什么,为什么? ['1','2','3'].map(parseInt)//[1,NaN,NaN ...
- amazeui学习笔记二(进阶开发4)--JavaScript规范Rules
amazeui学习笔记二(进阶开发4)--JavaScript规范Rules 一.总结 1.注释规范总原则: As short as possible(如无必要,勿增注释):尽量提高代码本身的清晰性. ...
- JavaScript 学习笔记(二)
JavaScript 学习笔记(二) 文章目录 JavaScript 学习笔记(二) 一 JSON 1. JSON 对象 什么是JSON对象 JSON对象与Javascript对象的区别 在JavaS ...
- GEE(Google Earth Engine) 最基础代码学习笔记二 —— JavaScript 语言
GEE(Google Earth Engine) 学习笔记二 Javascript 语言 1. 注释 print('Hello World!'); 如果要注释,则在代码前面加//,比如: // pri ...
- JavaScript学习笔记(十五)
JavaScript学习笔记(十五) 事件 事件是DOM(文档对象模型)的一部分.事件流就是事件发生顺序,这是IE和其他浏览器在事件支持上的主要差别. 一.事件流 1.冒泡型事件 IE上的解决方案就是 ...
- Mr.J-- jQuery学习笔记(二十一)--模拟微博页面
先看之前的节点操作方法:Mr.J-- jQuery学习笔记(二十)--节点操作方法 Mr.J-- jQuery学习笔记(五)--属性及属性节点 Mr.J-- jQuery学习笔记(十一)--事件委托 ...
- JavaScript学习笔记(六)--数组
数组初始化 我们都知道,数组是用于保存多个值的集合,在数组中,值被称为元素,值可以是任意的数据类型.在Javascript中,创建数组通常有两种方式:字面量和构造函数. 字面量 数组的元素可以是任意的 ...
- JavaScript学习笔记:创建、添加与删除节点
JavaScript学习笔记:创建.添加与删除节点 文章目录 JavaScript学习笔记:创建.添加与删除节点 一.DOM对象节点类型 二.创建节点 1.创建元素节点 2.创建文本节点 3.创建属性 ...
- JavaScript 学习笔记(第三天)
JavaScript 学习笔记(第三天) 一.数组 1.1.数组的基础 1.2.数据类型分类 1.3.创建数组 1.3.1.字面量创建一个数组 1.3.2.内置构造函数创建数组 1.4.数组的基本操作 ...
- JavaScript学习笔记(九)(验证框架,layer弹出层)
JavaScript学习笔记(九) 一.jQuery Validate验证框架 1.引入相关插件路径 2. 修改一些规则 3. 自定义验证规则 4.异步验证 整体代码 二.layer弹出层 1.引入相 ...
最新文章
- arduino 温度调节器_多点测平均温度实现智能控制(arduino-ds18b20)
- 实例介绍,如何在开发中将各层日志归类输出.
- Xmpp实现简单聊天系列 --- ②用户注册和登陆
- List集合的迭代器方法
- SQL Server如何查看存储过程的执行计划
- 统计指定目录下的视频时长
- MongoDB的排除查询$ne缺陷
- 电灯泡实验应该怎么做_英文论文润色应该怎么做
- 利用vs 分析DMP文件、pdb文件定位release下的异常崩溃
- 本特利传感器330103-00-05-10-02-00
- 二元二次方程例题_二元二次方程练习题.doc
- iOS 单元测试 Tests 和 UITests
- 小米手机系统服务组件是干什么的_2799 元!小米 1 亿像素拍照手机来了,还有 MIUI 系统的小米手表...
- WinEdt10.3 激活
- [转]firefox浏览器油猴脚本-让网页背景成苹果蓝,保护眼睛
- 矩阵的Jordan分解实例
- Word中的图片设置嵌入式之后显示不全问题
- Chrome 出现“您未安装Flash Player播放器或者版本过低”问题
- Android Studio 安卓微信底部界面(带消息红点)代码
- Android 百度在线语音识别
热门文章
- 西电计组实验一 存储器实验
- 使用DeepWalk从图中提取特征
- keil stm32标准库放在哪里_STM32(1)——使用Keil MDK以及标准外设库创建STM32工程...
- java中for(int a:list)
- element-UI el-dialog组件按ESC键关闭不了弹窗
- 现代密码学(五) 数论和密码学困难性假设
- 遇见一只黑猫,她说Python是个怪物
- 基于keil5 的stm32F103C8T6的ST-LINK V2的仿真器使用
- 【高等数学】伯努利方程及其求解方法
- 怎么用色环搭配颜色?色环搭配常用色彩组合有哪些?