JavaScript小细节点罗列(2)
break 语句和 continue 语句
break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行。
break语句用于跳出代码块或循环。
var i = 0;
while(i < 100) {
console.log('i 当前为:' + i);
i++;
if (i === 10) break;
}
continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环。
var i = 0;
while (i < 100){
i++;
if (i % 2 === 0) continue;
console.log('i 当前为:' + i);
}
注意除了break,continue语句之外,还有一个return语句表示从被调函数返回到主调函数继续执行,返回时可附带一个返回值,由return后面的参数指定。return后函数就结束了,后面的语句不再执行.
标签(label)
JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签可以是任意的标识符,但不能是保留字,语句部分可以是任意语句。
标签通常与break语句和continue语句配合使用,跳出特定的循环。
top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) break top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
变量提升(Hoisting)
Hoisting 的作用范围是随着函数作用域的。我理解在这里尚未讲到函数作用域,不过可以提一句提醒读者注意,然后链接至作用域的部分进一步探讨;
“Hoisting 只对
var
声明的变量有效”,不尽然如此。变量声明的提升并非 hoisting 的全部,JavaScript 有四种让声明在作用域内获得提升的途径(按优先级):
-语言定义的声明,如 this 和 arguments。你不能在作用域内重新定义叫做 this 的变量,是因为 this 是语言自动定义的声明,并且它的优先级最高,也就是被 Hoisting 到最顶上了,没人能覆盖它
-形式参数。虽然我们无需用 var 来修饰形式参数,但是形式参数的确也是变量,并且被自动提升到次高的优先级
-函数声明。除了 var 以外,function declaration 也可以定义新的命名,并且同样会被 hoisting 至作用域顶部,仅次于前两者
-最后,是本文提到的常规变量,也就是 var 声明的变量
整数和浮点数
JavaScript 内部,所有数字都是以64位浮点数形式储存,即使整数也是如此。所以,1与1.0是相同的,是同一个数。
这就是说,JavaScript 语言的底层根本没有整数,所有数字都是小数(64位浮点数)。容易造成混淆的是,某些运算只有整数才能完成,此时 JavaScript 会自动把64位浮点数,转成32位整数,然后再进行运算。
由于浮点数不是精确的值,所以涉及小数的比较和运算要特别小心。
0.1 + 0.2 === 0.3
// false
0.3 / 0.1
// 2.9999999999999996
(0.3 - 0.2) === (0.2 - 0.1)
// false
精度最多只能到53个二进制位,这意味着,绝对值小于等于2的53次方的整数,即-253到253,都可以精确表示。
Math.pow(2, 53)
// 9007199254740992
Math.pow(2, 53) + 1
// 9007199254740992
Math.pow(2, 53) + 2
// 9007199254740994
Math.pow(2, 53) + 3
// 9007199254740996
Math.pow(2, 53) + 4
// 9007199254740996
上面代码中,大于2的53次方以后,整数运算的结果开始出现错误。所以,大于2的53次方的数值,都无法保持精度。由于2的53次方是一个16位的十进制数值,所以简单的法则就是,JavaScript 对15位的十进制数都可以精确处理。
Math.pow(2, 53)
// 9007199254740992
// 多出的三个有效数字,将无法保存
9007199254740992111
// 9007199254740992000
根据标准,64位浮点数的指数部分的长度是11个二进制位,意味着指数部分的最大值是2047(2的11次方减1)。也就是说,64位浮点数的指数部分的值最大为2047,分出一半表示负数,则 JavaScript 能够表示的数值范围为21024到2-1023(开区间),超出这个范围的数无法表示。
如果一个数大于等于2的1024次方,那么就会发生“正向溢出”,即 JavaScript 无法表示这么大的数,这时就会返回Infinity。
Math.pow(2, 1024) // Infinity
Math.pow(2, -1075) // 0
parseInt()
对于那些会自动转为科学计数法的数字,parseInt会将科学计数法的表示方法视为字符串,因此导致一些奇怪的结果。
parseInt(1000000000000000000000.5) // 1
// 等同于
parseInt('1e+21') // 1
parseInt(0.0000008) // 8
// 等同于
parseInt('8e-7') // 8
parseInt方法还可以接受第二个参数(2到36之间),表示被解析的值的进制,返回该值对应的十进制数。默认情况下,parseInt的第二个参数为10,即默认是十进制转十进制。
parseInt('1000', 2) // 8
parseInt('1000', 6) // 216
parseInt('1000', 8) // 512
isFinite()
isFinite方法返回一个布尔值,表示某个值是否为正常的数值。
isFinite(Infinity) // false
isFinite(-Infinity) // false
isFinite(NaN) // false
isFinite(-1) // true
with语句
它的作用是操作同一个对象的多个属性时,提供一些书写的方便。
var obj = {
p1: 1,
p2: 2,
};
with (obj) {
p1 = 4;
p2 = 5;
}
// 等同于
obj.p1 = 4;
obj.p2 = 5;
注意,如果with区块内部有变量的赋值操作,必须是当前对象已经存在的属性,否则会创造一个当前作用域的全局变量。
var obj = {};
with (obj) {
p1 = 4;
p2 = 5;
}
obj.p1 // undefined
p1 // 4
位运算符
二进制或运算符(or):符号为|,表示若两个二进制位都为0,则结果为0,否则为1。
二进制与运算符(and):符号为&,表示若两个二进制位都为1,则结果为1,否则为0。
二进制否运算符(not):符号为~,表示对一个二进制位取反。
异或运算符(xor):符号为^,表示若两个二进制位不相同,则结果为1,否则为0。
左移运算符(left shift):符号为<<
右移运算符(right shift):符号为>>
带符号位的右移运算符(zero filled right shift):符号为>>>
void 运算符
void运算符的作用是执行一个表达式,然后不返回任何值,或者说返回undefined。
下面是一个更实际的例子,用户点击链接提交表单,但是不产生页面跳转。
<a href="javascript: void(document.form.submit())">
提交
</a>
圆括号的作用
圆括号不是运算符,而是一种语法结构。它一共有两种用法:一种是把表达式放在圆括号之中,提升运算的优先级;另一种是跟在函数的后面,作用是调用函数。
Number(Object)
简单的规则是,Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组。
Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
之所以会这样,是因为Number背后的转换规则比较复杂。
第一步,调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。
第二步,如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果toString方法返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。
第三步,如果toString方法返回的是对象,就报错。
String(Object)
String方法的参数如果是对象,返回一个类型字符串;如果是数组,返回该数组的字符串形式。
String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
String方法背后的转换规则,与Number方法基本相同,只是互换了valueOf方法和toString方法的执行顺序。
先调用对象自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
如果toString方法返回的是对象,再调用原对象的valueOf方法。如果valueOf方法返回原始类型的值,则对该值使用String函数,不再进行以下步骤。
如果valueOf方法返回的是对象,就报错。
原生错误类型
SyntaxError
对象是解析代码时发生的语法错误。ReferenceError
对象是引用一个不存在的变量时发生的错误。angeError
对象是一个值超出有效范围时发生的错误。主要有几种情况,一是数组长度为负数,二是Number对象的方法参数超出范围,以及函数堆栈超过最大值。TypeError
对象是变量或参数不是预期类型时发生的错误。比如,对字符串、布尔值、数值等原始类型的值使用new命令,就会抛出这种错误,因为new命令的参数应该是一个构造函数。URIError
对象是 URI 相关函数的参数不正确时抛出的错误,主要涉及encodeURI()、decodeURI()、encodeURIComponent()、decodeURIComponent()、escape()和unescape()这六个函数。eval
函数没有被正确执行时,会抛出EvalError错误。该错误类型已经不再使用了,只是为了保证与以前代码兼容,才继续保留。
var err1 = new Error('出错了!');
var err2 = new RangeError('出错了,变量超出有效范围!');
var err3 = new TypeError('出错了,变量类型无效!');
err1.message // "出错了!"
err2.message // "出错了,变量超出有效范围!"
err3.message // "出错了,变量类型无效!"
finally 代码块
try...catch结构允许在最后添加一个finally代码块,表示不管是否出现错误,都必需在最后运行的语句。
function cleansUp() {
try {
throw new Error('出错了……');
console.log('此行不会执行');
} finally {
console.log('完成清理工作');
}
}
cleansUp()
// 完成清理工作
// Error: 出错了……
map()
map方法不仅可以用于数组,还可以用于字符串,用来遍历字符串的每个字符。但是,不能直接使用,而要通过函数的call方法间接使用,或者先将字符串转为数组,然后使用。
var upper = function (x) {
return x.toUpperCase();
};
[].map.call('abc', upper)
// [ 'A', 'B', 'C' ]
// 或者
'abc'.split('').map(upper)
// [ 'A', 'B', 'C' ]
其他类似数组的对象(比如document.querySelectorAll方法返回DOM节点集合),也可以用上面的方法遍历。
map方法还可以接受第二个参数,表示回调函数执行时this所指向的对象。
var arr = ['a', 'b', 'c'];
[1, 2].map(function(e){
return this[e];
}, arr)
// ['b', 'c']
如果数组有空位,map方法的回调函数在这个位置不会执行,会跳过数组的空位。
Array(2).map(function (){
console.log('enter...');
return 1;
})
// [, ,]
reduce(),reduceRight()
reduce方法和reduceRight方法依次处理数组的每个成员,最终累计为一个值。
它们的差别是,reduce是从左到右处理(从第一个成员到最后一个成员),reduceRight则是从右到左(从最后一个成员到第一个成员),其他完全一样。
这两个方法的第一个参数都是一个函数。该函数接受以下四个参数。
累积变量,默认为数组的第一个成员
当前变量,默认为数组的第二个成员
当前位置(从0开始)
原数组
[1, 2, 3, 4, 5].reduce(function(x, y){
console.log(x, y)
return x + y;
});
// 1 2
// 3 3
// 6 4
// 10 5
//最后结果:15
Object.keys(),Object.getOwnPropertyNames()
Object.keys方法和Object.getOwnPropertyNames方法都用来遍历对象的属性。
Object.keys方法的参数是一个对象,返回一个数组。该数组的成员都是该对象自身的(而不是继承的)所有属性名。
Object.getOwnPropertyNames方法与Object.keys类似,也是接受一个对象作为参数,返回一个数组,包含了该对象自身的所有属性名。
对于一般的对象来说,Object.keys()和Object.getOwnPropertyNames()返回的结果是一样的。只有涉及不可枚举属性时,才会有不一样的结果。Object.keys方法只返回可枚举的属性,Object.getOwnPropertyNames方法还返回不可枚举的属性名。
var a = ['Hello', 'World'];
Object.keys(a) // ["0", "1"]
Object.getOwnPropertyNames(a) // ["0", "1", "length"]
JavaScript小细节点罗列(2)的更多相关文章
- JavaScript小细节点罗列
共勉! 属性访问表达式 众所周知,JavaScript为属性的访问定义了两种语法方式: 表达式.标识符 // 表达式(指定对象) 标识符(指定需要访问的属性的名称) 表达式[表达式] //表达式1(指 ...
- JavaScript小细节点罗列(1)
共勉! 属性访问表达式 众所周知,JavaScript为属性的访问定义了两种语法方式: 表达式.标识符 // 表达式(指定对象) 标识符(指定需要访问的属性的名称) 表达式[表达式] //表达式1(指 ...
- css小细节罗列
有空时候把一些常见可能不是每个人都知道的css小细节总结了下,共勉. 1.line-height 众多周知,line-height是行高的意思,我们时常会使用类似line-height:24px;这样 ...
- php课程---Json格式规范需要注意的小细节
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. 易于人阅读和编写.同时也易于机器解析和生成. 它基于JavaScript Programming Lan ...
- HTML 标签小细节
简书地址:https://www.jianshu.com/p/03a23aa28a34 今天重新学习了一下HTML中标签的用法,补充并记录一下自己新学到的知识. a中的href href Contai ...
- Vue.js 和 MVVM 的小细节
Vue.js 和 MVVM 的小细节 转载 作者:流云诸葛 链接:www.cnblogs.com/lyzg/p/6067766.html MVVM 是Model-View-ViewModel 的缩写, ...
- Oracle Sales Cloud:管理沙盒(定制化)小细节2——使用对象触发器更新数字字段
在上一篇 "管理沙盒(定制化)小细节1" 的随笔中,我们使用公式法在 "业务机会" 对象(单头)上建立了 "利润合计" 字段,并将它等于 & ...
- Oracle Sales Cloud:管理沙盒(定制化)小细节1——利用公式创建字段并显示在前端页面
Oracle Sales Cloud(Oracle 销售云)是一套基于Oracle云端的CRM管理系统.由于 Oracle 销售云是基于 Oracle 云环境的,它与传统的管理系统相比,显著特点之一便 ...
- Oracle Sales Cloud:报告和分析(BIEE)小细节2——利用变量和过滤器传参(例如,根据提示展示不同部门的数据)
在上一篇随笔中,我们建立了部门和子部门的双提示,并将部门和子部门做了关联.那么,本篇随笔我们重点介绍利用建好的双提示进行传参. 在操作之前,我们来看一个报告和分析的具体需求: [1] 两个有关联的提示 ...
随机推荐
- gulp的安装以及使用详解,除了详细还是详细
安装gulp: 1. 创建本地包管理环境: 使用npm init命令在本地生成一个package.json文件,package.json是用来记录你当前这个项目依赖了哪些包,以后别人拿到你这个项目后, ...
- Alpha冲刺(3/10)——追光的人
1.队友信息 队员学号 队员博客 221600219 小墨 https://www.cnblogs.com/hengyumo/ 221600240 真·大能猫 https://www.cnblogs. ...
- [Umbraco] 创建第一个页面
如何创建一个页面,很简单. 进入settings,首先右键点击“Document Types”, 在出现的菜单点击"Create",在弹出的窗口中 Master Document ...
- Google Protocol Buffers 入门
Google Protocol Buffers 是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化.它很适合做数据存储或 RPC 数据交换格式.可用于通讯协议.数据存储等领域的 ...
- MySQL笔记(3)---文件
1.前言 第二章简单记录了一下InnoDB存储引擎的一个基本内容,介绍了保证高效插入的Insert Buffer,change Buffer和确保数据安全的write ahead log以及doubl ...
- flex布局中transform出错
在flex布局下,若应用transform 的动画的子元素没有使用进行定位,则动画过程中,子元素将相对display:flex的元素进行static定位 动画结束后位置正常: 修复代码只需要posit ...
- This Gradle plugin requires Studio 3.0 minimum
从github上下载的项目遇到一个问题:Error:This Gradle plugin requires Studio 3.0 minimum 意思就是说studio版本不高,导入的项目的版本是3. ...
- 全网最详细的CentOS7里安装MySQL时出现No package mysql-server available错误的解决办法(图文详解)
不多说,直接上干货! 直接yum install mysql的话会报错,原因在于yum安装库里没有直接可以用的安装包,此时需要用到MariaDB了,MariaDB是MySQL社区开发的分支,也是一个增 ...
- 三:理解Page类的运行机制(例:在render方法中生成静态文件)
我这里只写几个常用的事件1.OnPreInit:此事件后将加载个性化信息和主题2.OnInit:初始化页面中服务器控件的默认值但控件的状态没有加载,没有创建控件树3.OnPreLoad:控件完成状态和 ...
- docker namespaces
https://docs.docker.com/engine/security/userns-remap/#prerequisites 注:以下验证环境为centos7.5 docker 18.09. ...