是时候把JS的知识点总结下,而且会持续施工,每一个知识点若是有更深刻的技术探讨和知识会陆续添加进去。javascript
ECMAScirpt中的变量,函数名,操做符都区分大小写。java
标识符指的多是:express
变量名数组
函数名浏览器
属性名安全
函数的参数app
标识符的名称:less
第一个字符只能是字母,下划线_,或者美圆符号$;函数
其余的能够是字母,数字,下划线_,或者美圆符号$。oop
按照惯例,标识符名称应使用驼峰法,即首字母小写,剩下的每一个单词首字母大写。
不能把关键字、保留字、TRUE、FALSE、NULL做为标识符名称。
//单行注释 /* 多行注释 多行注释 */
ES5引入了严格模式,严格模式下,某些旧版本(ES3)的一些不肯定行为将获得处理,而对某些不安全的操做也会抛出错误。支持严格模式的浏览器:IE10+ Firefox 4+ Safari 5.1+ Opera 12+ Chrome
//在整个脚本中引入严格模式,则在script标签顶部或者*.js文件顶部添加以下代码便可。 "use strict"; //在指定函数中引入严格模式: function f1(){ "use strict"; //TODO... };
TODO : 引入了严格模式与没引入严格模式的js文件如何解决冲突以及共存?
ES中的语句以一个分号结尾,省略分号虽然有效但不推荐。
var sum = 1 + 2;
// 关键字 break case catch continue debugger default delete do instanceof else new finally return for switch function this if throw in try typeof var void while with
// ES3定义的保留字 abstract boolean byte char class const debugger double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile //ES5中非严格模式下的保留字缩减为这些: class enum extends super const export import //ES5中严格模式下的相对非严格模式增长的保留字,其中let与yield是新增的。 implements interface let package private protected public static yield //实际开发中,建议将ES3定义的保留字外加新增的let与yield做为参考。
须要注意的是,ES5的严格模式下,eval
与arguments
也不能做为标识符与属性名,不然会抛出错误。
ES中的变量是松散类型的,即变量能够保存任何类型的数据。
定义变量使用var
操做符,后跟变量名(即一个标识符),
使用var
操做符定义的变量会成为该做用域下的局部变量,该变量在函数退出以后就会被销毁:
var a; //定义一个名为a的变量,值是undefined var b = null; //定义一个名为b的变量,值为null(空) var c = 'percy'; //定义一个名为c的变量,值为字符串“percy”
function f1(){ var name = 'jon'; //函数f1()下的局部变量 alert(name); } f1(); //jon alert(name); //外部不能直接访问函数的内部变量
//使用一条语句定义多个变量,用逗号分隔便可。 var name='jon', age=25, isMarried=false;
ES中有
5种简单数据类型(基本数据类型):Undefined
、Null
、Boolean
、Number
、String
1种复杂数据类型:Object
typeof
操做符返回值:
undefined
——给定的值未定义;
boolean
——给定的值是布尔值;
string
——给定的值是字符串;
number
——给定的值是数值;
object
——给定的值是对象或者null
;
function
——给定的是函数;
function f2(){ console.log('Hi!'); } var name = 'jon'; var age = 25; alert(typeof f2); //function alert(typeof name); //string alert(typeof age); //number
只有一个值:undefined
var name; /*var name = undefined;*/ //无需把变量显式设置undefined值 alert(name == undefined); //true
变量的值为undefined与未声明的变量并不同,但使用typeof
操做符均会返回undefined,但输出值时未声明的变量会产生错误:
var job; //该变量已声明但未赋值,默认值为undefined // var name2; 该变量并未声明 alert(typeof job); //测试变量类型,输出undefined alert(typeof name2); //测试变量类型,即便变量未声明也会输出undefined //输出值时 alert(job); //undefined alert(name2); //产生错误:Uncaught ReferenceError: name2 is not defined
只有一个值:null
;undefined
值派生自null
值,因此用==
测试二者时会返回true
;null
值表示一个空对象指针,因此使用typeof
操做符时会返回object
;
若是建立的变量未来用于保存对象,那么初始声明该变量时应把值设置为null
;
var name = null; alert(typeof name); //object
有两个值:true
、false
;
//注意Boolean类型字面值是区分大小写的,True、False以及其余大小写混合的形式均不属于Boolean类型值; var isBoy = true; var isGirl = false;
Boolean()
函数把其余值转为Boolean值var name = 'jon'; var nameBool = Boolean(name); //true
转换规则以下表:
数据类型 | 转为true的值 | 转为false的值 |
---|---|---|
Boolean | true | false |
String | 任何非空字符串 | ""(空字符串) |
Number | 任何非零数值(包括无穷大) | 0,NaN |
Object | 任何对象 | null |
Undefined | 不适用 | undefined |
转换规则对于流程控制语句自动执行相应的Boolean转换很是重要:
var name = 'jon'; if(name){ //name转换为true,执行下面的语句 alert('name is defined!'); }
包含整数和浮点数(双精度数值),NaN
。
var intN1 = 123; //十进制整数 var intN2 = 013; //十进制的11 var intN3 = 018; //无效的八进制,会被转成十进制的18,而且在严格模式下回抛出错误 var intN4 = 0xB; //十六进制,会被转为十进制的11 alert(-0 == +0); //true,ES中正零相等于负零;
var fN1 = 0.1; var fN2 = 1.1; var fN3 = .1; //不推荐 var fN4 = 1. //被解析为整数1 var fN5 = 1.0; //被解析为整数1 var fN6 = 1.05e5; //e表示法,即科学记数法,会被解析成105000,即1.05乘以10的7次方 var fN7 = 3e-6; //会被解析成0.000003
浮点数的精确度远远不如整数,因此永远不要用计算浮点数来进行条件测试:
if(a + b = 0.3){ //不要作这样的测试! //DO STH... }
console.log(Number.MIN_VALUE); //ES能表示的最小数,结果是5e-324 console.log(Number.MAX_VALUE); //ES能表示的最大数,结果是1.7976931348623157e+308 /* 若一次运算中,计算结果超过了ES的最大或最小数,那么这个结果会被转换成特殊的Infinity或-Infinity,该值没法参与运算;如下两个属性也保存着上述两个值; */ alert(Number.NEGATIVE_INFINITY); //-Infinity alert(Number.POSITIVE_INFINITY); //Infinity
肯定某个结果是否为有穷的(是否位于ES能表示的最大与最小数之间的有效数值),使用isFinite()
函数;
var a = 10.4e-8; alert(isFinite(a)); //true,该数值在有效范围以内
用于表示一个原本要返回数值的操做数没有返回数值的状况,这样就不会抛出错误;
ES中0除以0都会返回NaN;(其余数值除以0会返回Infinity或者-Infinity)
任何涉及NaN的运算操做也会返回NaN;
NaN不等于任何值,包括它本身;
alert(NaN == NaN); //false
isNaN()
函数,接受一个参数,肯定该参数是否“不是数值”,若是该参数是数值或者能转换成数值,则会返回false
,不然返回true
;
alert(isNaN(1)); //false alert(isNaN('2')); //false,能够把字符串2转换成数值2 alert(isNaN(true)); //false,能够把布尔值true转换成数值1,若是false则转换成0 alert(isNaN('1024cl')); //true,数值与字符串不能转换成数值 alert(isNaN('true')); //true,字符串*均*不能转换成数值 alert(isNaN(NaN)); //true,NaN自己不是有效的数值
Number()
,parseInt()
,parseFloat()
Number()
的转换例子:
alert(Number(1)); //1 alert(Number(true)); //转换成1 alert(Number(false)); //转换成0 alert(Number(null)); //转换成0 alert(Number(undefined)); //NaN alert(Number("")); //空字符串转换成0 alert(Number("12")); //转换成12 alert(Number("034")); //忽略前导0,转换成34 alert(Number("12ab")); //NaN alert(Number("0x11")); //有效的十六进制会转换成十进制的17
更经常使用的parseInt()
与parseFloat()
例子:
alert(parseInt(1)); //1 alert(parseInt(11.91)); //11 alert(parseInt(true)); //NaN alert(parseInt(false)); //NaN alert(parseInt(null)); //NaN alert(parseInt(undefined)); //NaN alert(parseInt("")); //NaN alert(parseInt("12")); //12 alert(parseInt("034")); //34 alert(parseInt("12ab")); //忽略数值后的无效字符,转换为12 alert(parseInt("ab12")); //NaN alert(parseInt("0x11")); //17
//在转换八进制的字符串包含的数值中,ES3与ES5有时会存在分歧: alert(parseInt("067")); //ES3中会输出55 alert(parseInt("067")); //ES5中会忽略前导0,并转换成10进制的67
基于上面的问题,做为最佳实践,使用parseInt()
始终应该加入第二个参数,即须要转换时须要使用的进制数:
alert(parseInt("076",8)); //62 alert(parseInt("076",10)); //76 alert(parseInt("0xAA",16)); //170 alert(parseInt("AA",16)); //170 alert(parseInt("AA")); //NaN
//parseFloat()只会解析十进制数值,因此没有第二个参数 alert(parseFloat("1.2.3")); //只会解析左起第一个小数点,因此该数值会被转换成1.2 alert(parseFloat("0xAA")); //十六进制数值始终会被转换成0 alert(parseFloat(11.1)); //11.1 alert(parseFloat("443abc")); //443,忽略后面的无效字符 alert(parseFloat("443.3aa")); //443.3,忽略后面的无效字符 alert(parseFloat("3.33e7")); //33300000 alert(parseFloat("0757.2768")); //忽略前导0,757.2768
即字符串,由0或多个16位Unicode字符组成的字符序列;
//能够由单引号或双引号包裹,且左右引号必须匹配 var s1 = 'name1'; var s2 = "name2";
String数据类型包含一些特殊的字符字面量,也叫转义序列,用于表示非打印字符,或者有其余用途的字符:
字面量 | 含义 |
---|---|
n | 换行 |
t | 制表 |
b | 空格 |
r | 回车 |
f | 进纸 |
\ | 斜杠 |
' | 单引号('),在用单引号表示的字符串中使用,例如'I 'm JonHo' |
" | 双引号("),在用双引号表示的字符串中使用,例如"I "m JonHo" |
xnn | 以十六进制代码nn表示的一个字符,其中n为0~F,例如,x41表明A |
unnnn | 以十六进制代码nnnn表示的一个Unicode字符,其中n为0~F,例如,u03a3表示希腊字符∑ |
上述的字符字面量能够出如今字符串的任意位置,而且也会被做为字符来解析:
var sign = "sign is : \u011f"; console.log(sign); /*sign is : ğ*/ console.log(sign.length); //11,说明六个字符长的转义序列只会表示一个字符,占一个索引位置;
toString()
:var name = 'Jon'; alert(name.toString()); //"Jon" var age = 25; alert(age.toString()); //字符串"25" var isMarried = false; alert(isMarried.toString()); //字符串"false" //null与undefined没有toString()方法 alert(null.toString()); //NaN alert(undefined.toString()); //NaN //转换数值的状况下,能够传入一个参数,即输出数值的基数 var num = 10; alert(num.toString()); //默认十进制输出,10 alert(num.toString(2)); //二进制输出,1010 alert(num.toString(8)); //八进制输出,12 alert(num.toString(10)); //十进制输出,10 alert(num.toString(16)); //十六进制输出,A
在不知道转换的值是否为null
或undefined
的状况下,可使用转型函数String()
,该函数能把任何类型的值转为字符串:
若是传入的值有toString()
方法,则调用该方法并返回相应的结果;
若是传入的值是null
,则返回"null";
若是传入的值是undefined
,则返回"undefined";
var value1 = 10; var value2 = true; var value3 = null; var value4; alert(String(value1)); // "10" alert(String(value2)); // "true" alert(String(value3)); // "null" alert(String(value4)); // "undefined"
ES中的Object(对象)就是一组数据和功能的集合。
Object类型是全部其余类型的基础,因此Object类型的因此属性和方法也会存在于其余具体的对象中。
var o1 = new Object(); //建立一个自定义对象
Object实例拥有的属性和方法
属性/方法 | 解析 |
---|---|
constructor | 保存着用于建立对象的函数。对于前面的例子而言,构造函数(constructor)就是Object()。 |
hasOwnProperty(propertyName) | 用于检查给定的属性(propertyName)在当前的对象实例中(而不是在实例的原型中)是否存在。propertyName必须以字符串形式指定。 |
isPrototypeOf(object) | 用于检查传入的对象是不是传入对象的原型。(?) |
propertyIsEnumerable(propertyName) | 检查给定的属性(propertyName)是否能用for-in语句枚举。propertyName必须以字符串形式指定。 |
toLocaleString() | 返回对象的字符串表示,该字符串与执行环境的地区对应。 |
toString() | 返回对象的字符串表示。 |
valueOf() | 返回对象的字符串、数值或布尔值表示。一般与toString()方法的返回值相同。 |
包括 一元操做符,位操做符,布尔操做符,乘性操做符,加性操做符,关系操做符,相等操做符,条件操做符,赋值操做符,逗号操做符。
//前置型操做符 var n1 = 25; ++n1; var n2 = 25; --n2; //前置型操做符会在求值前被执行 var age = 25; var anotherAge = --age + 2; console.log(age); //24 (在下一句执行以前已经执行了自减) console.log(anotherAge); //26 (24+2)
//后置型操做符 var n1 = 25; n1++; //后置型操做符会在被求值以后才执行,注意如下问题 var n1 = 2; var n2 = 20; var n3 = n1-- + n2; console.log(n3); //计算n3时使用了原始值计算,因此输出22 var n4 = n1 + n2; console.log(n4); //计算n4时,n1已经被递减,因此输出21
上述的4个操做符能够用于整数,浮点数,字符串,布尔值,对象运算;
var s1 = "2"; console.log(++s1);//转换为数值2再参与运算,输出3 var s2 = "a"; console.log(++s2);//值为NaN,没法参与运算 var s3 = false; console.log(++s3);//转换为数值0再参与运算,输出1, **true则转换为1** var s4 = 2.1; console.log(--s4); //参与减一运算,注意浮点数舍入错误问题,输出1.1 console.log(++s4); //参与加一运算,注意浮点数舍入错误问题,输出2.1 var s5 = { valueOf: function(){ return -1; } }; console.log(++s5); //先调用对象的valueOf()方法,取得一个可供操做的值,而后把该值应用于前述规则;若是结果是NaN,则调用toString()方法后再应用前述规则。对象变量变成数值变量,这里输出0 console.log(++s5); //输出1
即+
和-
;
对非数值应用一元加和减操做符时,会像Number()转型函数同样对这个值执行转换
/*一元加操做符*/ var s1 = "01"; var s2 = "1.1"; var s3 = "z"; var b = false; var f = 1.1; var o = { valueOf: function() { return -1; } }; s1 = +s1; //1 s2 = +s2; //1.1 s3 = +s3; //NaN b= +b; //0 f= +f; //1.1 o= +o; //-1 /*一元减操做符*/ //一元减操做符主要用来表示负数 var n1 = 1; n2 = -n1; //-1
非(NOT)
,与(AND)
,或(OR)
!
返回一个布尔值, 而后再对其求反
alert(!false); //true alert(!"blue"); //false alert(!0); //true alert(!NaN); //true alert(!""); //true alert(!12345); //false alert(!undefined); //true alert(!null); //true var i = function(){}; alert(!i); //false
&&
有两个操做数, 只有两个操做数都返回true时, 才返回true; 不然返回false
var i = function(){}; var j = function(){console.log("funciton j")}; alert(i && true); //true alert(i && false); //false alert(true && i); //function(){} alert(false && i); //false alert(i && j); //function(){console.log("funciton j")}; //若是有一个操做数是null, NaN或undefined, 则返回该三者之一 alert(null && false); //null alert(null && true); //null alert(null && i); //null
/*逻辑与属于短路操做, 即若是第一个操做数能决定结果,就不会再对第二个操做数求值*/ var f = true; var r = (f && cc); //cc未声明 alert(r); //这一句不会执行,由于上面的cc未声明. Uncaught ReferenceError: cc is not defined(…) //若是f为false,则会执行并返回false, 由于第一个操做数已是false, 因此就不会再对后面的操做数求值了 var f = false; var r = (f && cc); //cc未声明 alert(r); //false
||
有两个操做数, 只要有一个操做数都返回true, 就会返回true;
var i = function(){}; var j = function(){console.log("funciton j")}; alert(i || true); //function(){}; alert(i || false); //function(){}; alert(i || j); //function(){}; alert(true || i); //true alert(false || i); //function(){}; alert(null || false); //false alert(null || true); //true alert(null || i); //function(){}; //若是两个操做数都是null, NaN, undefined, 则会返回一样的结果.
//逻辑或也属于短路操做 var f = true; var r = (f || cc); //cc未声明 alert(r); //会执行true var f = false; var r = (f || cc); //cc未声明 alert(r); //这一句不会执行,由于上面的cc未声明. Uncaught ReferenceError: cc is not defined(…)
/*正常开发中, 可使用逻辑与来避免为变量赋null或undefined值*/ var o = preferredObject || backupObject; //backupObject提供一个后备值, 若是preferredObject不包含指望的有效值的状况下, backupObject会被赋值给o, 不然在常常状况下, preferredObject赋值给o.
*
, 乘法,用于计算两个值的乘积
alert(2 * 2); //4 alert(2 * -2); //-4 alert(NaN * 2); //NaN alert(Infinity * 0); //NaN alert(Infinity * 1); //Infinity alert(Infinity * -1); //-Infinity alert(Infinity * Infinity); //Infinity //在操做数不是数值的状况下, 后台会调用Number()将其转换为数值,而后在进行运算
/
, 除法,第二个操做数除第一个操做数
alert(2 / 2); //1 alert(2 / -2); //-1 alert(2 / NaN); //NaN alert(Infinity / Infinity); //NaN alert(0 / Infinity); //0 alert(Infinity / 0); //Infinity alert(0 / 0); //NaN alert(0 / 2); //0 alert(2 / 0); //Infinity alert(-2 / 0); //-Infinity //在操做数不是数值的状况下, 后台会调用Number()将其转换为数值,而后在进行运算
+
, 加法
alert(1 + 2); //3 alert(NaN + 1);//NaN alert(Infinity + Infinity); //Infinity alert(-Infinity + (-Infinity)); //-Infinity alert(Infinity + (-Infinity)); //NaN alert(0 + 0); //0 alert(-0 + (-0)); //0 alert(0 + (-0)); //0 alert(1+'2'); //12, 字符串拼接
//注意加法操做中的数据类型错误 var num1 = 5; var num2 = 10; var message = "The sum of 5 and 10 is " + num1 + num2; alert(message); // 获得的结果是 : "The sum of 5 and 10 is 510" //应该像下面这样使用括号 var num1 = 5; var num2 = 10; var message = "The sum of 5 and 10 is " + (num1 + num2); alert(message); //"The sum of 5 and 10 is 15"
-
, 减法
alert(2 - 1); alert(NaN - 1); //NaN alert(Infinity - Infinity); //NaN alert(-Infinity -(-Infinity)); //NaN alert(Infinity -(-Infinity)); //Infinity alert(-Infinity - Infinity); //-Infinity alert(0 - 0); //0 alert(0 - (-0)); //-0 alert(-0 -(-0)); //0 alert(5 - true); //4, ture to 1 alert(5 - ""); //5, "" to 0 alert(5 - "2"); //3, "2" to 2 alert(5 - null); //5, null to 0
小于<
, 大于>
, 小于等于<=
, 大于等于>=
, 均返回一个布尔值
var r = 5 > 4; //true var r = 5 < 4; //false
//在字符串的比较中, 决定结果的是字符串字母(大小写)的字符编码, 而不是字母的顺序 : alert("app" > "back"); //false alert("app" > "Back"); //true alert("App" > "Back"); //false //因字符编码的顺序不一样, 因此在进行比较时应该把字符串统一转换成大写或者小写再进行比较; alert("App".toLowerCase() > "Back".toLowerCase()); //false //一样的, 数字字符串也会比较的是字符编码 : alert("15" > "4"); //false //把其中一个变成数值类型, 或者使用有效的转型函数转型成数值, 结果就正常了 : alert("15" > 4); //true alert(Number("15") > Number("4")); //true //NaN跟任何数值比较均返回false alert(NaN > 4); //false alert(NaN < 4); //false
相等==
和不相等!=
, 全等===
和不全等!==
相等和不相等在比较前都会先转换操做数, 而后再进行比较
//布尔值会被先转换成0和1 alert(1 == true); //true alert(2 == true); //false alert(0 == false); //true alert("a" == 1); //false var a = "jon"; var b = "percy"; var c = a; alert(a == c); //true, 比较两个对象时, 若是两个对象指向的是同一个对象,则返回true, 不然返回false alert(a == b); //false alert(a == 1); //false alert(null == undefined); //true alert(undefined == 0); //false alert(null == 0); //false alert(5 == "5"); //true alert("NaN" == NaN); //false alert(5 == NaN); //false alert(NaN == NaN); //false, NaN不等于自身
全等和不全等不会像上面的相等和不相等同样进行数据类型转换, 而是直接进行比较 :
alert(55 == "55"); //相等比较下, 会进行数据转换, 因此返回true alert(55 === "55"); //全等比较下, 不会进行数据转换, 因此这里返回false /*注意null和undefined进行全等比较会返回false, 由于他们是相似的值(因此相等比较会返回true)可是属于不一样类型的值*/ alert(null == undefined); //false
//对boolean_expression求值, 若是结果为true则返回true_value(给variable), 不然返回false_value(给variable) variable = boolean_expression ? true_value : false_value;
var num1 = 4; var num2 = 6; var max = (num1 > num2) ? num1 : num2; console.log(max); //6
简单的赋值操做符=
乘/赋值*=
除/赋值/=
模/赋值%=
加/赋值+=
减/赋值-=
左移/赋值<<=
有符号右移/赋值>>=
无符号右移/赋值>>>=
var n = 2; n = n + 2; //4 //能够简化成 n += 2; //其余原理相同
//可用于同时声明多个变量 var a, b, c;
ES指流程控制语句
if(condition){ statement1 }else{ statement2 }
var i = 20; if(i > 25){ console.log("i is greater than 25"); }else{ console.log("i is less than or equal to 25"); } //i is less than or equal to 25
if(condition1){ statement1 }else if(condition2){ statement2 }else{ statement3 }
var i = 25; if(i > 25){ console.log("i is greater than 25"); }else if(i == 25){ console.log("i is equal to 25"); }else{ console.log("i is less than 25"); } //i is equal to 25
do-while语句在对表达式求值以前, 循环体内的代码会被最少执行一次
do{ statement }while(expression)
var i = 2; do{ i += 2; console.log(i); }while(i < 7); //之因此出现8的缘由是, 当i递增到6的时候依然少于7, 因此在判断while里面的条件以前依然会被递增一次 //4, 6, 8
var i = 10; do{ i ++; console.log(i); }while(i < 10); //虽然while里面的条件已经不知足,但do里面的语句仍是会被执行一次, 输出11
与do-while语句相反, while语句会在循环体(expression)内的代码被执行以前, 先对条件求值
while(expression){ statement }
var i = 10; while(i < 20){ i+=2; console.log(i); //12, 14, 16, 18, 20 } console.log("the last i is : " + i); //20
for与while同样, 也是前测试循环语句, 但它能够在执行循环以前初始化变量和定义循环后要执行的代码
for(initialization; expression; post-loop-expression){ statement; }
var c = 10; for(var i = 1; i <= c; i+=2){ console.log(i); } //1, 3, 5, 7, 9
//提早定义好变量, 就能够在for语句里面省略var关键字 var i, c = 10; for(i = 1; i <= 10; i+=3){ console.log(i); //1, 4, 7, 10 } //注意ES里面没有块级做用域, 因此下面的语句能够正常输出 console.log("the last i is : " : i); //10
for-in是精准的迭代语句, 能够用来枚举对象的属性
for(property in expression){ statement }
var arr = ['Jon','Martin','Percy']; for(var i in arr){ console.log(arr[i]); //Jon, Martin, Percy } //注意for-in语句输出的结果顺序是不可预测的 //做为最佳实践, 使用for-in语句时, 应该确认该对象的值不是null或undefined
label语句能够在代码中添加标签, 以便在未来被break或continue引用
label : statement
first : for(var i = 0; i < 10; i+=2){ console.log(i); } //first做为for循环的标签
break与continue语句用于在循环中精确的控制代码的执行;
break会当即退出循环, 强制执行后面的语句
continue也会当即退出循环, 但退出后会从循环的顶部继续执行
//break var n = 0; //初始化计算累积次数的变量 for(var i = 1; i < 10; i++){ //i从1递增到10 if(i % 5 == 0){ //递增过程当中判断i是否能被0整除 break; //是的话当即退出循环,这里在i=5的时候退出了循环 } n++; //每循环一次累积计算次数 } console.log(n); //退出循环以前,循环体执行了4次,因此输出4
//continue var n = 0; //初始化计算累积次数的变量 for(var i = 1; i < 10; i++){ //i从1递增到10 if(i % 5 == 0){ //递增过程当中判断i是否能被0整除 continue; //是的话当即退出循环,这里在i=5的时候退出了循环, 而且回到循环顶部继续执行(在for循环条件未知足以前继续执行) } n++; //每循环一次累积计算次数 } console.log(n); //退出循环以前(for循环结束以前),循环体执行了8次(由于在5被整除的时候退出了循环,致使循环体少执行了一次),因此最终输出8
与label标签配合使用
//break var i, j, n = 0; outerloop: for(i = 0; i < 10; i++){ for(j = 0; j < 10; j++){ if(i == 5 && j ==5){ break outerloop; } n++; } } //正常来讲, i每递增1次, j就会递增10次, 因此n最终值在不受干扰的状况下回等于100 //这里判断若是i和j都等于5的状况下回当即退出循环, 因此循环体最终会退出内部和外部的for循环(退回标签outerloop的位置), 因此最终n会输出55 console.log(n); //55
//continue var i, j, n = 0; outerloop: for(i = 0; i < 10; i++){ for(j = 0; j < 10; j++){ if(i == 5 && j ==5){ continue outerloop; } n++; } } //这里判断若是i和j都等于5的状况下回当即退出循环, 但退回外部的for循环(outerloop标签)的循环以后会继续强制执行外部循环, 因此最终会获得95 console.log(n); //95
with语句做用是将代码的做用域设置到一个特定的对象中
with(expression){ statement; }
//定义with语句的目的主要是简化屡次编写同一个对象的工做 var qs = location.search.substring(1); var hostName = location.hostname; var url = location.href; //使用with语句上面的代码能够改为 with(location){ var qs = search.substring(1); var hostName = hostname; var url = href; } //严格模式下不容许使用with, 不然会报错 //with会致使性能降低, 在大型项目中不建议使用
switch语句
switch(expression){ //若是expression等于value, 则执行后面的statement, 并跳出当前循环 case value : statement break; case value : statement break; case value : statement break; case value : statement break; //若是expression不等于前面任何一个value, 则使用default内的statement代码 default : statement } var i = 2; switch(i){ case 1 : console.log("result is 1"); break; case 2; console.log("result is 2"); break; default : console.log("what is the result?"); } //能够合并两种情形(cast) switch(i){ case 1 : case 2 : console.log("1 or 2"); break; case N... }
函数能够封装任意多条语句, 且能够在不一样地方, 不一样时间调用执行.
使用关键字function
声明,后面跟一组参数以及函数体
function functionName(arg0, arg1, arg2, ...argN){ statements; } //实例 function sayHi(name, age){ console.log("my name is " + name +", age is" + age + "."); } //调用 sayHi("Jon",25); //输出my name is Jon, age is 25.
//使用return语句后面跟要返回的值来实现返回值 function sum(n1, n2){ return n1 + n2; } var r = sum(1 + 2); alert(r); //3
//注意在return后面的语句永远不会执行 function sum(n1, n2){ return n1 + n2; console.log("Hi!"); //永远不会执行 }
//一个函数中能够包含多个return语句 function diff(n1 ,n2){ if(n1 < n2){ return n2 - n1; }else{ return n1 - n2; } } //return能够不带有任何返回值,通常用在须要提早执行函数执行有不须要返回值的状况下. function sayHi(name, message){ return; console.log("Hi! " + name + "," + message); //永远不会调用 } //推荐的作法是要么让函数始终返回一个值, 要么永远不会返回值
ES中的参数不限定数量和数据类型
假设被调用的函数的参数定义了两个, 在调用这个函数时也不强制须要传入两个, 能够少传或多穿而不会报错, 命名的参数只是为了便利, 并非必须的
ES函数的参数内部是一组类数组, 在函数体内能够经过arguments对象来访问这组数组的内容, 访问的时候像访问数组同样, 使用方括号语法arguments[0], arguments[1], arguments[2], arguments[n] ...
//上面的sum函数例子能够写成 function sum(n1, n2){ //return n1 + n2; return arguments[0] + arguments[1]; } sum(1 , 2); //3
//访问arguments的length属性能够知道多少个参数传递给了函数 function howManyArgs(){ console.log(arguments.length); } howManyArgs(); //0 howManyArgs(1); //1 howManyArgs(1,2); //2 //能够利用这一点让函数在接收不一样参数时执行不一样的功能 function doAdd(n1, n2){ if(arguments.length == 1){ console.log(arguments[0] + 2); }else if(arguments.length == 2){ console.log(arguments[0] + arguments[1]); //argument对象能够和命名参数混合使用 //console.log(arguments[0] + n2); //没有问题! } } doAdd(1); //3 doAdd(2,3); //5
arguments的值和对应的命名参数的值会保持同步
function doAdd(n1, n2){ arguments[1] = 10;//注意严格模式下会无效,n2仍然等于undefined console.log(arguments[0] + n2); } doAdd(12,1); //22, 而不是13 //严格模式下重写arguments的值会致使语法错误, 代码不能执行
ES中全部参数传递都是值, 不可能经过引用传递参数
其余语言中能够为一个函数编写两个定义, 只要这两个定义的签名(接受的参数类型和数量)不一样便可
ES中的参数是由包含零个或多个值的数组来表示的, 而没有函数签名, 真正的重载是不可能的
若是定义了两个名字相同的函数, 那么更名字只属于后定义的函数
function add(n){ return n + 10; } function add(n){ return n + 20; } add(1); //21
经过检查传入函数中参数的类型和数量并做出不一样的反应, 能够模拟方法的重载.