continue语句用于立即终止本轮循环,返回循环结构的头部,开始下一轮循环。

break语句用于跳出代码块或循环。

标签(label)

JavaScript 语言允许,语句的前面有标签(label),相当于定位符,用于跳转到程序的任意位置,标签的格式如下。

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

上面代码为一个双重循环区块,break命令后面加上了top标签(注意,top不用加引号),满足条件时,直接跳出双层循环。如果break语句后面不使用标签,则只能跳出内层循环,进入下一次的外层循环。

continue语句也可以与标签配合使用。

top:
for (var i = 0; i < 3; i++){
for (var j = 0; j < 3; j++){
if (i === 1 && j === 1) continue top;
console.log('i=' + i + ', j=' + j);
}
}
// i=0, j=0
// i=0, j=1
// i=0, j=2
// i=1, j=0
// i=2, j=0
// i=2, j=1
// i=2, j=2

上面代码中,continue命令后面有一个标签名,满足条件时,会跳过当前循环,直接进入下一轮外层循环。如果continue语句后面不使用标签,则只能进入下一轮的内层循环。

本质上,数组属于一种特殊的对象。typeof运算符会返回数组的类型是object

var arr = ['a', 'b', 'c'];

Object.keys(arr)
// ["0", "1", "2"]

上面代码中,Object.keys方法返回数组的所有键名。可以看到数组的键名就是整数0、1、2。

对象的每个成员都必须指定键名。

数值键名被自动转为了字符串

对象有两种读取成员的方法:点结构(object.key)和方括号结构(object[key])。但是,对于数值的键名,不能使用点结构。

 String()
String函数可以将任意类型的值转化成字符串,转换规则如下。 (1)原始类型值 数值:转为相应的字符串。
字符串:转换后还是原来的值。
布尔值:true转为字符串"true",false转为字符串"false"。
undefined:转为字符串"undefined"。
null:转为字符串"null"。
String(123) // "123"
String('abc') // "abc"
String(true) // "true"
String(undefined) // "undefined"
String(null) // "null"
(2)对象 String方法的参数如果是对象,返回一个类型字符串;如果是数组,返回该数组的字符串形式。 String({a: 1}) // "[object Object]"
String([1, 2, 3]) // "1,2,3"
String方法背后的转换规则,与Number方法基本相同,只是互换了valueOf方法和toString方法的执行顺序。 先调用对象自身的toString方法。如果返回原始类型的值,则对该值使用String函数,不再进行以下步骤。 如果toString方法返回的是对象,再调用原对象的valueOf方法。如果valueOf方法返回原始类型的值,则对该值使用String函数,不再进行以下步骤。 如果valueOf方法返回的是对象,就报错。 下面是一个例子。 String({a: 1})
// "[object Object]" // 等同于
String({a: 1}.toString())
// "[object Object]"
上面代码先调用对象的toString方法,发现返回的是字符串[object Object],就不再调用valueOf方法了。 如果toString法和valueOf方法,返回的都是对象,就会报错。 var obj = {
valueOf: function () {
return {};
},
toString: function () {
return {};
}
}; String(obj)
// TypeError: Cannot convert object to primitive value
下面是通过自定义toString方法,改变返回值的例子。 String({
toString: function () {
return 3;
}
})
// "3" String({
valueOf: function () {
return 2;
}
})
// "[object Object]" String({
valueOf: function () {
return 2;
},
toString: function () {
return 3;
}
})
// "3"
上面代码对三个对象使用String函数。第一个对象返回toString方法的值(数值3),第二个对象返回的还是toString方法的值([object Object]),第三个对象表示toString方法先于valueOf方法执行
var arr = [1, 2, 3];
arr.0 // SyntaxError

清空数组的一个有效方法,就是将length属性设为0。

var arr = [ 'a', 'b', 'c' ];

arr.length = 0;
arr // []

如果人为设置length大于当前元素个数,则数组的成员数量会增加到这个值,新增的位置都是空位。

var a = ['a'];

a.length = 3;
a[1] // undefined

上面代码表示,当length属性设为大于数组个数时,读取新增的位置都会返回undefined

如果人为设置length为不合法的值,JavaScript 会报错。

// 设置负值
[].length = -1
// RangeError: Invalid array length

 pow(x,y) 方法返回 x 的 y 次幂。

由于数组本质上是一种对象,所以可以为数组添加属性,但是这不影响length属性的值。

var a = [];

a['p'] = 'abc';
a.length // 0 a[2.1] = 'abc';
a.length // 0

上面代码将数组的键分别设为字符串和小数,结果都不影响length属性。因为,length属性的值就是等于最大的数字键加1,而这个数组没有整数键,所以length属性保持为0

如果数组的键名是添加超出范围的数值,该键名会自动转为字符串。

var arr = [];
arr[-1] = 'a';
arr[Math.pow(2, 32)] = 'b'; arr.length // 0
arr[-1] // "a"
arr[4294967296] // "b"

上面代码中,我们为数组arr添加了两个不合法的数字键,结果length属性没有发生变化。这些数字键都变成了字符串键名。最后两行之所以会取到值,是因为取键值时,数字键名会默认转为字符串。

检查某个键名是否存在的运算符in,适用于对象,也适用于数组。

var arr = [ 'a', 'b', 'c' ];
2 in arr // true
'2' in arr // true
4 in arr // false

上面代码表明,数组存在键名为2的键。由于键名都是字符串,所以数值2会自动转成字符串。

for…in 循环和数组的遍历

for...in循环不仅可以遍历对象,也可以遍历数组,毕竟数组只是一种特殊对象。

var a = [1, 2, 3];

for (var i in a) {
console.log(a[i]);
}
// 1
// 2
// 3

但是,for...in不仅会遍历数组所有的数字键,还会遍历非数字键。

var a = [1, 2, 3];
a.foo = true; for (var key in a) {
console.log(key);
}
// 0
// 1
// 2
// foo

上面代码在遍历数组时,也遍历到了非整数键foo。所以,不推荐使用for...in遍历数组。

数组的遍历可以考虑使用for循环或while循环。

var a = [1, 2, 3];

// for循环
for(var i = 0; i < a.length; i++) {
console.log(a[i]);
} // while循环
var i = 0;
while (i < a.length) {
console.log(a[i]);
i++;
} var l = a.length;
while (l--) {
console.log(a[l]);
}

上面代码是三种遍历数组的写法。最后一种写法是逆向遍历,即从最后一个元素向第一个元素遍历。

var colors = ['red', 'green', 'blue'];
colors.forEach(function (color) {
console.log(color);
});
// red
// green
// blue
,如果最后一个元素后面有逗号,并不会产生空位。也就是说,有没有这个逗号,结果都是一样的。
数组的空位是可以读取的,返回undefined

使用delete命令删除一个数组成员,会形成空位,并且不会影响length属性。

var a = [1, 2, 3];
delete a[1]; a[1] // undefined
a.length // 3

上面代码用delete命令删除了数组的第二个元素,这个位置就形成了空位,但是对length属性没有影响。也就是说,length属性不过滤空位。所以,使用length属性进行数组遍历,一定要非常小心。

数组的某个位置是空位,与某个位置是undefined,是不一样的。如果是空位,使用数组的forEach方法、for...in结构、以及Object.keys方法进行遍历,空位都会被跳过。

 var a = [, , ,];

 a.forEach(function (x, i) {
console.log(i + '. ' + x);
})
// 不产生任何输出 for (var i in a) {
console.log(i);
}
// 不产生任何输出 Object.keys(a)
// []
如果某个位置是undefined,遍历的时候就不会被跳过。 var a = [undefined, undefined, undefined]; a.forEach(function (x, i) {
console.log(i + '. ' + x);
});
// 0. undefined
// 1. undefined
// 2. undefined for (var i in a) {
console.log(i);
}
// 0
// 1
// 2 Object.keys(a)
// ['0', '1', '2']
类似数组的对象
如果一个对象的所有键名都是正整数或零,并且有length属性,那么这个对象就很像数组,语法上称为“类似数组的对象”(array-like object)。 var obj = {
0: 'a',
1: 'b',
2: 'c',
length: 3
}; obj[0] // 'a'
obj[1] // 'b'
obj.length // 3
obj.push('d') // TypeError: obj.push is not a function
上面代码中,对象obj就是一个类似数组的对象。但是,“类似数组的对象”并不是数组,因为它们不具备数组特有的方法。对象obj没有数组的push方法,使用该方法就会报错。 “类似数组的对象”的根本特征,就是具有length属性。只要有length属性,就可以认为这个对象类似于数组。但是有一个问题,这种length属性不是动态值,不会随着成员的变化而变化。 var obj = {
length: 0
};
obj[3] = 'd';
obj.length // 0
上面代码为对象obj添加了一个数字键,但是length属性没变。这就说明了obj不是数组。 典型的“类似数组的对象”是函数的arguments对象,以及大多数 DOM 元素集,还有字符串。 // arguments对象
function args() { return arguments }
var arrayLike = args('a', 'b'); arrayLike[0] // 'a'
arrayLike.length // 2
arrayLike instanceof Array // false // DOM元素集
var elts = document.getElementsByTagName('h3');
elts.length // 3
elts instanceof Array // false // 字符串
'abc'[1] // 'b'
'abc'.length // 3
'abc' instanceof Array // false
上面代码包含三个例子,它们都不是数组(instanceof运算符返回false),但是看上去都非常像数组。 数组的slice方法可以将“类似数组的对象”变成真正的数组。 var arr = Array.prototype.slice.call(arrayLike);
除了转为真正的数组,“类似数组的对象”还有一个办法可以使用数组的方法,就是通过call()把数组的方法放到对象上面。 function print(value, index) {
console.log(index + ' : ' + value);
} Array.prototype.forEach.call(arrayLike, print);
上面代码中,arrayLike代表一个类似数组的对象,本来是不可以使用数组的forEach()方法的,但是通过call(),可以把forEach()嫁接到arrayLike上面调用。 下面的例子就是通过这种方法,在arguments对象上面调用forEach方法。 // forEach 方法
function logArgs() {
Array.prototype.forEach.call(arguments, function (elem, i) {
console.log(i + '. ' + elem);
});
} // 等同于 for 循环
function logArgs() {
for (var i = 0; i < arguments.length; i++) {
console.log(i + '. ' + arguments[i]);
}
}
字符串也是类似数组的对象,所以也可以用Array.prototype.forEach.call遍历。 Array.prototype.forEach.call('abc', function (chr) {
console.log(chr);
});
// a
// b
// c
注意,这种方法比直接使用数组原生的forEach要慢,所以最好还是先将“类似数组的对象”转为真正的数组,然后再直接调用数组的forEach方法。 var arr = Array.prototype.slice.call('abc');
arr.forEach(function (chr) {
console.log(chr);
});
// a
// b
// c

Array.property.forEach.call({2,3},function(){})//将数组的方法给对象使用;

Number()
使用Number函数,可以将任意类型的值转化成数值。 下面分成两种情况讨论,一种是参数是原始类型的值,另一种是参数是对象。 (1)原始类型值 原始类型值的转换规则如下。 // 数值:转换后还是原来的值
Number(324) // 324 // 字符串:如果可以被解析为数值,则转换为相应的数值
Number('324') // 324 // 字符串:如果不可以被解析为数值,返回 NaN
Number('324abc') // NaN // 空字符串转为0
Number('') // 0 // 布尔值:true 转成 1,false 转成 0
Number(true) // 1
Number(false) // 0 // undefined:转成 NaN
Number(undefined) // NaN // null:转成0
Number(null) // 0

Number函数将字符串转为数值,要比parseInt函数严格很多。基本上,只要有一个字符无法转成数值,整个字符串就会被转为NaN

parseInt('42 cats') // 42
Number('42 cats') // NaN
(2)对象

简单的规则是,Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组。

Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
 (2)对象

 简单的规则是,Number方法的参数是对象时,将返回NaN,除非是包含单个数值的数组。

 Number({a: 1}) // NaN
Number([1, 2, 3]) // NaN
Number([5]) // 5
之所以会这样,是因为Number背后的转换规则比较复杂。 第一步,调用对象自身的valueOf方法。如果返回原始类型的值,则直接对该值使用Number函数,不再进行后续步骤。 第二步,如果valueOf方法返回的还是对象,则改为调用对象自身的toString方法。如果toString方法返回原始类型的值,则对该值使用Number函数,不再进行后续步骤。 第三步,如果toString方法返回的是对象,就报错。 请看下面的例子。 var obj = {x: 1};
Number(obj) // NaN // 等同于
if (typeof obj.valueOf() === 'object') {
Number(obj.toString());
} else {
Number(obj.valueOf());
}
上面代码中,Number函数将obj对象转为数值。背后发生了一连串的操作,首先调用obj.valueOf方法, 结果返回对象本身;于是,继续调用obj.toString方法,这时返回字符串[object Object],对这个字符串使用Number函数,得到NaN。 默认情况下,对象的valueOf方法返回对象本身,所以一般总是会调用toString方法,而toString方法返回对象的类型字符串(比如[object Object])。所以,会有下面的结果。 Number({}) // NaN
如果toString方法返回的不是原始类型的值,结果就会报错。 var obj = {
valueOf: function () {
return {};
},
toString: function () {
return {};
}
}; Number(obj)
// TypeError: Cannot convert object to primitive value
上面代码的valueOf和toString方法,返回的都是对象,所以转成数值时会报错。 从上例还可以看到,valueOf和toString方法,都是可以自定义的。 Number({
valueOf: function () {
return 2;
}
})
// 2 Number({
toString: function () {
return 3;
}
})
// 3 Number({
valueOf: function () {
return 2;
},
toString: function () {
return 3;
}
})
// 2
上面代码对三个对象使用Number函数。第一个对象返回valueOf方法的值,第二个对象返回toString方法的值,第三个对象表示valueOf方法先于toString方法执行。 String()
 Boolean()
Boolean函数可以将任意类型的值转为布尔值。 它的转换规则相对简单:除了以下五个值的转换结果为false,其他的值全部为true。 undefined
null
-0或+0
NaN
''(空字符串)
Boolean(undefined) // false
Boolean(null) // false
Boolean(0) // false
Boolean(NaN) // false
Boolean('') // false
注意,所有对象(包括空对象)的转换结果都是true,甚至连false对应的布尔对象new Boolean(false)也是true(详见《原始类型值的包装对象》一章)。 Boolean({}) // true
Boolean([]) // true
Boolean(new Boolean(false)) // true
所有对象的布尔值都是true,这是因为 JavaScript 语言设计的时候,出于性能的考虑,如果对象需要计算才能得到布尔值,对于obj1 && obj2这样的场景,可能会需要较多的计算。为了保证性能,就统一规定,对象的布尔值为true。
 自动转换为字符串
JavaScript 遇到预期为字符串的地方,就会将非字符串的值自动转为字符串。具体规则是,先将复合类型的值转为原始类型的值,再将原始类型的值转为字符串。 字符串的自动转换,主要发生在字符串的加法运算时。当一个值为字符串,另一个值为非字符串,则后者转为字符串。 '5' + 1 // '51'
'5' + true // "5true"
'5' + false // "5false"
'5' + {} // "5[object Object]"
'5' + [] // "5"
'5' + function (){} // "5function (){}"
'5' + undefined // "5undefined"
'5' + null // "5null"
 自动转换为数值
JavaScript 遇到预期为数值的地方,就会将参数值自动转换为数值。系统内部会自动调用Number函数。 除了加法运算符(+)有可能把运算子转为字符串,其他运算符都会把运算子自动转成数值。 '5' - '2' // 3
'5' * '2' // 10
true - 1 // 0
false - 1 // -1
'1' - 1 // 0
'5' * [] // 0
false / '5' // 0
'abc' - 1 // NaN
null + 1 // 1
undefined + 1 // NaN
上面代码中,运算符两侧的运算子,都被转成了数值。 注意:null转为数值时为0,而undefined转为数值时为NaN。 一元运算符也会把运算子转成数值。 +'abc' // NaN
-'abc' // NaN
+true // 1
-false // 0

,虽然arguments很像数组,但它是一个对象。数组专有的方法(比如sliceforEach),不能在arguments对象上直接使用。

如果要让arguments对象使用数组方法,真正的解决方法是将arguments转为真正的数组。下面是两种常用的转换方法:slice方法和逐一填入新数组。

var args = Array.prototype.slice.call(arguments);

// 或者
var args = [];
for (var i = 0; i < arguments.length; i++) {
args.push(arguments[i]);
}

3)callee 属性

arguments对象带有一个callee属性,返回它所对应的原函数。

var f = function () {
console.log(arguments.callee === f);
} f() // true

2018.5.2(7:20到的办公室开始早课 阮一峰的JS) 所有的默默努力都是为了让自己看起来毫不费力的更多相关文章

  1. 2018年5月20日--西安icpc邀请赛打铁总结

    2018年5月20日--西安icpc邀请赛打铁总结  事后诸葛亮 大致回顾一下比赛,29号的热身赛和30号的正式赛. 热身赛总共三道题,一个小时,没有AC一道题目. A题是一个几何题目,审题时犯了一个 ...

  2. 2018年排名前20的数据科学Python库

    Python 在解决数据科学任务和挑战方面继续处于领先地位.业已证明最有帮助的Python库,我们选择 20 多个库,因为其中一些库是相互替代的,可以解决相同的问题.因此,我们将它们放在同一个分组. ...

  3. 2018年1月20日上海MVP线下技术分享会纪实

    1月20日正值大寒节气,在微软MVP朱兴亮的组织牵头下,上海MVP自发举办了题为<跟社区专家一起聊聊混合云.领域驱动.区块链和数字营销>的技术交流会.四名来自上海的MVP分别在自己擅长的技 ...

  4. 2018年11月20日 远交近攻 list1

    list 列表用法 li=[1,2,3,"abc"] #列表中的元素,可以为数字或者字符串或者布尔值或者就是列表等,所有都能放进去 #列表中也能嵌套列表 pi=[1,2,3,[2, ...

  5. 2018年5月20日--西安icpc邀请赛试题一览

    热身赛 正式赛 A题,样例不代表后台数据,出题人把题意和后台数据代表的意思搞差了! B: C: D-E F f-G G G-H H-I I-J J-k K-2

  6. 5.3日,7:20开始 阮一峰js的早课学习

    Infinity - Infinity // NaN Infinity / Infinity // NaN Infinity + Infinity // Infinity Infinity * Inf ...

  7. 高并发大容量NoSQL解决方案探索

    大数据时代,企业对于DBA也提出更高的需求.同时,NoSQL作为近几年新崛起的一门技术,也受到越来越多的关注.本文将基于个推SRA孟显耀先生所负责的DBA工作,和大数据运维相关经验,分享两大方向内容: ...

  8. 【LeetCode】78. Subsets 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 回溯法 日期 题目地址:https://leet ...

  9. [python爬虫] Selenium定向爬取海量精美图片及搜索引擎杂谈

    我自认为这是自己写过博客中一篇比较优秀的文章,同时也是在深夜凌晨2点满怀着激情和愉悦之心完成的.首先通过这篇文章,你能学到以下几点:        1.可以了解Python简单爬取图片的一些思路和方法 ...

随机推荐

  1. 通过JSONP实现完美跨域

    通过JSONP实现完美跨域 三水清 2010-06-11 20:17:47 以前我经常在博客说JSONP,例如我的WordPress天气插件就是通过JSONP来调用的天气数据,今天就说说通过JSONP ...

  2. Neural Networks for Machine Learning by Geoffrey Hinton (4)

    一种能够学习家谱关系的简单神经网络 血缘一共同拥有12种关系: son, daughter, nephew, niece, father, mother, uncle, aunt, brother, ...

  3. Eclipse 构建Maven项目--普通web项目

    一.Maven项目的新建 1.鼠标右键---->New----->Maven Project 2.直接点下一步 3.选中 maven-archetype-webapp 后点击下一步 4. ...

  4. 使用MyEclipse 2014构建Maven项目的两种方法

    前提: MyEclipse已配置Maven,具体步骤见http://blog.csdn.net/haishu_zheng/article/details/51492491 方法一: 1 File--& ...

  5. 【云计算】OpenShift容器服务参考

    https://docs.openshift.com/enterprise/latest/using_images/db_images/mysql.html 红帽发布OpenShift Dedicat ...

  6. megalo -- 网易考拉小程序解决方案

    megalo 是基于 Vue 的小程序框架(没错,又是基于 Vue 的小程序框架),但是它不仅仅支持微信小程序,还支持支付宝小程序,同时还支持在开发时使用更多 Vue 的特性. 背景 对于用户而言,小 ...

  7. (转)nio 字符集

    字符集 概述 根据 Sun 的文档,一个 Charset 是“十六位 Unicode 字符序列与字节序列之间的一个命名的映射”.实际上,一个 Charset 允许您以尽可能最具可移植性的方式读写字符序 ...

  8. Visual Studio Image Library

    The Visual Studio Image Library Visual Studio 2013   The Visual Studio Image Library contains applic ...

  9. HTTP状态码具体解释

    HTTP状态码(HTTP Status Code)是用以表示网页serverHTTP响应状态的3位数字代码.它由 RFC 2616 规范定义的,并得到RFC 2518.RFC 2817.RFC 229 ...

  10. My SqL 语法大全

    一.SQL速成  结构查询语言(SQL)是用于查询关系数据库的标准语言,它包括若干关键字和一致的语法,便于数据库元件(如表.索引.字段等)的建立和操纵.  以下是一些重要的SQL快速参考,有关SQL的 ...