type
定义脚本语言类型,可空 ,默认为JavaScript类型
支持的MIME类型包括text/javascript 、 text/ecmascript、 application/javascript 和application/ecmascript
async
异步并行 加载,只针对外部JS资源
多个async
脚本加载完成的顺序不确定
defer
等HTML解析完成再执行JS,在DOMContentLoaded之前执行,只针对外部JS资源
多个脚本资源顺序加载
??脚本加载策略 :
如果脚本无需等待页面解析,且无依赖独立运行,那么应使用 async
。
如果脚本需要等待页面解析,且依赖于其它脚本,应使用 defer
,将关联的脚本按所需顺序置于 HTML 中。
基础语法
02、变量申明var/let/const
变量 ,就是一个用于存放数值的容器,比如年龄=20
,“年龄”就是变量,“20”是他的树值。JS是一种弱类型语言,不需要指明数据类型,用var
或 let
关键字申明即可。
??申明方式 :
申明并赋值,1步完成:var str="hello world";
先申明,再赋值,2步完成。var str1; str1="hello world";
// 默认值为undefined
??动态数据类型 :JavaScript 是一种“动态类型语言”,意味着一个变量可以被赋值为各种类型数据值,通过typeof
判断数据类型。
let age;
console.log(age); //undefined
age =20;
console.log(typeof age); //number
age='年芳二十';
console.log(typeof age); //string
var
let (IE11 ES6)
const (IE11 ES6)
说明
变量申明
变量申明
只读常量 申明:申明时必须初始化值,不可更改
作用域
全局(整个文档)或整个函数体 内
块级 作用域{}
包含的区域
块级 作用域{}
命名规范
推荐:小驼峰命名
同var
推荐:全大写+下划线,const MAX_SPEED
默认值
undefined
undefined
必须赋值
变量提升
提升 所有var申明的变量,可以先使用后申明(不推荐),把var变量申明提升到代码头部,??注意 不包括赋值
不会提升,顺序执行 :必须先申明,后使用。存在暂时性死区
let foo=(foo+55)
第二个foo未申明报错
不会提升,顺序执行 :必须先申明,后使用。
全局属性
在全局环境时,会成为顶级对象的属性(不可配置属性),作为全局变量存在。var age=3; //this.age;window.age
无
无
重复申明
可以重复 申明,覆盖前面的,有点太随意了
不可重复申明 ,作用域内重复申明会报错 ● 包括var、const申明的变量 ● 子块可重新申明let,不同的作用域了 ● 子块中用var变量会重复,var会提升
不可重复申明 ,会提示错误,同let
申明多个
支持:var s1=1,st=2;
支持:let s1,s2=2;
支持:const s1=1,s2=2;
性能
一般
一般
编译器会做常量替换优化,提升代码效率
总结
??有点粗犷,不推荐
??更严谨,推荐使用
??不仅更严谨,性能还好,优先推荐!!!
暂时性死区 :由于没有了变量提升,及块级作用域,let、const变量只能在申明后才能用,在这之前不可用,称为“暂时性死区”。
2.1、作用域
特别注意的是 var
作用域在整个文档或函数内,整个文档也可认为是一个特殊的顶级函数。
如下经典的for循环示例,var
的变量提升导致输出结果诡异。
for (var i = 1; i <= 5; i++) {
setTimeout(function () { //setTimeout为异步执行函数
console.log(i); //输出6 6 6 6 6
}, 0);
}
//换成let,则输出:1 2 3 4 5
//换成const,输出1,然后报错 Assignment to constant variable
function foo() {
var x = 1; //x作用域在foo函数体内,包括嵌套函数bar也可以访问
function bar() {
var y = 2; //y作用域只在函数体bar
console.log(x); // 1
console.log(y); // 2
}
bar();
console.log(x); // 1 (`x` 在作用域内)
console.log(y); // Uncaught ReferenceError: y is not defined
}
foo();
console.log(x); // Uncaught ReferenceError: x is not defined
console.log(y); // Uncaught ReferenceError: y is not defined
let作用域仅限{}
块,可以是函数的块function{}
、循环的块for{}
,或者就一个孤独的块{}
。
let s1;
let s1; //Uncaught SyntaxError: Identifier 's1' has already been declared
let x = 1; //后面块内的 var x会被变量提升,导致重复变量定义报错
{
var x = 2; //Uncaught SyntaxError: Identifier 'x' has already been declared
}
2.2、变量提升
变量提升 :JS引擎是先解析代码,获取所有被var
申明的变量,然后再逐行执行。只提升用var
显示申明的变量,会把所有var的申明提升到全局代码的顶部先执行,??注意 只提升申明,不包括赋值。
console.log(sname); //undefined 只提升了x的变量申明,值为默认值
var sname = "sam";
var x=1;
function print() {
console.log(sname); // sam
console.log(window.sname); //sam 全局文档中申明的var变量,会作为 window 的全局变量属性
console.log(this.sname); //sam 这里的this 指向 全局对象window
}
print();
??隐式全局变量 :无申明变量(str="hello";
),自动提升为隐式全局变量(不论在什么地方),类似var变量,除了没有变量提升。so,??尽量不要这么使用,在严格模式下('use strict';
)这样写是会报错的。
x = 0; //未申明变量,成为隐式全局变量
function f() {
y = 1; //当执行该函数时,未申明变量,成为隐式全局变量
var z = 2; //z是函数内部申明的变量,作用域只在函数体内
}
f();
console.log(x, y); // 0 1
console.log(window.x, window.y); // 0 1
console.log(z); //Uncaught ReferenceError: z is not defined
2.3、解构赋值
解构赋值 是ES6新增的语法,可以一次性给多个变量赋值,提高了编程效率,赋值操作更简洁。具体方式就是:将属性/值从对象/数组中取出,赋值给其他变量的一种赋值方式 。有两种解构赋值的语法形式:
数组解构 :类似数组的写法,从数组中按顺序赋值,这里数组可以是其他可迭代 数据。
对象解构 :类似对象的写法,从对象中按属性名赋值。
//变量一个个赋值
let x1 = 1, x2 = 2, x3 = 3, x4 = 4;
// 用数组解构赋值
let [y1, y2, y3, y4] = [1, 2, 3, 4];
[x1, x2] = [x2, x1]; //用来交换x1、x2的值,不用第三方变量
// 从对象解构赋值
let { c, d } = { a: 0, c: 1, d: 2 };
03、基础数据类型
ECMAScript 有 6 种基本类型 ,Undefined
、Null
、Boolean
、Number
、String
、Symbol
(符号),其他就是都是Object 对象类型了,如Array
、object
、Map
、Date
、function
等。
数据类型
描述
Number
数值 :整数、小数(浮点型) ● 都是64位浮点类型存储的,最高精度17位,所以1和1.0是相等的。 ● 浮点数计算时(小数位)可能不准确,不建议用浮点数做判断。 ● 存储时会自动转换整数的浮点数值,如1.0转换为1。
let myAge = 17;
Boolean
布尔类型 :有两个值true
、false
let isFirstBlood=true;
null
空值 关键字,表示空缺、空值,其类型为object ,表示一个空对象的指针。undefined
继承自null
,等值比较时返回true。
注意判断object类型时须排除null。
Undefined
未定义 :只有一个值undefined
,表示未定义或不存在 ● 未赋值的变量默认为undefined
。 ● 调用函数时未传递必须参数,则为undefined
。 ● 函数没有返回值,默认返回undefined
。
String
字符串 :单引号、双引号括起来,用加号+
连接字符串。 ● 不可变 :JS的字符串一旦创建不可变,所有更改都会创建新的字符串 ● 每一个字符元素是16 位的无符号整数值
Symbol ES6
符号类型,具有唯一性 和不变性 ,常用于对象属性名
const fooSym = Symbol('foo')
bigint
新添加的数据类型(ES2020)
object对象
对象 :引用类型,各种值的组合
?Array
数组对象
var list1=[1,2,3];
?JSON对象
对象:var jobj={name:"zhang",age:1};
?function
函数,本身也是对象
function f1(){/*...*/}
??注意 不要将基本类型中的布尔值 true / false 与值为 true/false 的 Boolean 对象弄混了,基本类型Boolean是一个对象。
console.log(typeof 1); //number
console.log(typeof true); //boolean
console.log(typeof null); //object
console.log(typeof undefined); //undefined
console.log(typeof 'abc'); //string
console.log(null == undefined); //true 值比较
console.log(null === undefined); //false 恒等比较
//boolean
const x = new Boolean(false); //new Boolean()创建了基本类型Boolean的对象,就不是一个平平无奇的值类型了。
console.log(typeof x); //object
console.log(x.valueOf()); //false valueOf()方法获取对象的基本数据的值
console.log(Boolean(undefined)); //false
console.log(Boolean(null)); //false
console.log(Boolean(NaN)); //false
console.log(Boolean(0)); //false
console.log(Boolean("")); //false
console.log(Boolean(1)); //true
console.log(Boolean(-100)); //true
console.log(Boolean("abc")); //true
3.1、Number数字
Number 的属性、方法:
属性/方法
描述
示例
??静态属性/方法
Number.NaN
NaN是一个特殊的Number值,即非数值(Not a Number) ● NaN 和任何值都不相等,包括它自己,和任何值计算都为NaN ● Math
、parseInt
函数执行失败会返回NaN
同window.NaN
Number.MAX_VALUE
最大数值(静态属性),值接近于 1.79E+308
Number.MIN_VALUE
最接近 0 的正值,而不是最小的负值,约为 5E-324
Number. isNaN() IE??
判断是否等于NaN,window.isNaN
是判断是否非数值,坑!
只有NaN才返回true
Number.isInteger () IE??
是否为整数
Number.parseFloat () IE??
解析浮点数 ,从第一个非空字符解析获取数字,识别第一个小数点
同window.parseFloat()
Number.parseInt () IE??
解析整数 ,从第一个非空字符解析获取数字,支持进制参数
同window.parseInt()
??构造函数
Number()
转换为数字 (忽略空格)。Number()转换数据不同于parseint、parseFloat,要求必须为合法数字,要求更严格,不成功便成仁。
Number(true) //1
??实例属性/方法
toFixed (小数位数)
转换为指定小数位数的字符,多了会四舍五入,不足用0补位
n1.toFixed(2)
toString ()
转字符串,参数可以指定基数(进制)
n2.toString(2)
//2进制
??注意浮点数的精度 :0.1+0.2 //输出 0.3000000000000000**4**
。由于浮点数的精度问题,永远不要用浮点数值去做条件判断。这种错误是由于IEEE 754标准导致的。
Number.parseFloat("123.4a5"); //123.4
Number.parseInt("123.4a5"); //123
//注意,两个方法是不同的,全局的window.isNaN()是判断是否非数值。
window.isNaN("a") //true
Number.isNaN("a") //false //这属于JS坑爹的设计,两个含义完全不同
console.log(Number("")); //0
console.log(Number("123abc")); //NaN,不同于parseint、parseFloat
console.log(Number("12.12.12")); //NaN,不同于parseint、parseFloat
console.log(Number.parseFloat("12.12.12")); //12.12
let n1=1.336,n2=100;
n1.toFixed(2) //1.34
n2.toFixed(2) //100.00
window.parseFloat (string):从字符串的第一位(空字符会被忽略)开始,如果是数字(正号+
、负号-
、数字0-9
、第一个小数点.
、科学计数法e/E
)则转数字,直到非数字或结束。
console.log(parseFloat("123abc")); //123
console.log(parseFloat("abc123")); //NaN
console.log(parseFloat("11.11")); //11.11
console.log(parseFloat("11.11.33")); //11.11
window.parseint (string):同parseFloat,除了不识别小数点。
console.log(parseInt("123abc")); //123
console.log(parseInt("abc123")); //NaN
console.log(parseInt("11.11")); //11
3.2、String字符串
String:字符串对象,提供各种字符串操作。
属性/方法
描述
示例
??构造函数
String()
支持任意值转换为字符串,包括null
、undefined
,都是直接加引号,很粗暴!??可以用来判断null、undefined
String(null) //"null"
??实例属性/方法
length
字符串长度
"abc".length; // 3
charAt (index)
返回指定位置的字符
indexOf (char)
返回字符的索引位置,从前往后找,lastIndexOf
是从后往前找
s1.indexOf("12")
substr (start,length?)
截取字符串:指定起始位置 、长度 ,无length
到结尾(下同)
s1.substr(2)
substring (start,end?)
截取字符串:指定起始位置 、结束位置
slice (start,end?)
截取字符串:起始位置 、结束位置 ,同substring
,区别是支持负数 (倒数),(slice /sla?s/ 切片)
str.slice(0,-1);//截取0到倒数第二位置的字符
split (separator,limit?)
按照分隔符分割字符串为数组
(split /spl?t/ 分裂)
trim ()
移除首尾 的空白字符,返回新字符,不会改变原有字符。
trimStart ()
同上,值移除开头的空白字符,还有移除末尾的trimEnd
()
padStart (len,str)
从头补齐字符长度到len
,str为去替补的字符,没有则空格
"12".padStart(5,'0')
padEnd (len,str)
补齐字符长度,从尾部开始
replace (old, new)
字符替换,str.replace("台湾","台湾省")
,支持正则和函数
repeat (n)
创建一个重复n次的新字符串
"12".repeat(2) //1212
toLowerCase ()
字符转小写,大写是toUpperCase()
includes (str)
判断是否包含指定的字符串
startsWith (str)
判断是否以指定字符开头,endsWith ()判断结尾
search(str)
字符搜索或正则匹配搜索
match(regexp)
正则匹配搜索字符
??字符串的不变性 :字符串一经创建不会改变。 let str="abc"; str="123";
这里的不改变 ,不是字符变量str
不能修改,是指字符串"abc"
本身不可更改,修改str
会创建新的字符。所以,字符的操作都不会影响原来的字符串值,而是创建新的字符串。
字符连接创建新字符 :字符的连接,如+
,会创建新的字符串。
??模板字符串 (IE??):${var}
+反引号 `` 包装
板字符串可以包含特定语法(${expression}
)的占位符,由一个内置函数负责计算表达式并输出最终的字符串。
let x=1,y=2;
console.log(`sum: ${x} + ${y} = ${x+y}`); //sum: 1 + 2 = 3
??JavaScript 特殊/转义字符 :在字符串中使用的特殊符号
字符
描述
\0
Null 字节
\b
退格符
\f
换页符
\n
换行符
\r
回车符
\t
Tab (制表符)
\v
垂直制表符
\'
单引号
\"
双引号
\\
反斜杠字符(\)
3.3、类型( 隐式 )转换
隐式类型转转换,是自动进行的,也叫自动类型转换。
值
字符串
数字
布尔值
undefined
"undefined"
NaN
false
null
"null"
0
false
true
"true"
1
true
false
"false"
0
false
""(空字符)
""
0
false
"1.5"
"1.5"
1.5
true
"one"
"one"
NaN
true
0
"0"
0
false
-1
"-1"
-1
true (非0数字都true)
1
"1"
1
true
NaN
"NaN"
NaN
false
[](空数组)
0
true
[5]一个数字
里面的数字5
true
["a"][1,2]其他数组
NaN
true
{...}对象
NaN
true
??隐式转换总结 :
转boolean :undefined、null、NaN、0、空字符转bool都为false ;非0数字(包括负数)、非空字符(包括”true“、”false“)、对象、空数组[] 转boolean
都为true 。
转数字 :非空字符串都是数字(忽略空格)的转对应数字,否则NaN;null、空字符转数字为0。
转字符串 :任意类型转字符串加引号,包括undefined、null。
+运算 :字符串+任意类型(包括空字符)均转换为字符串 ;boolean、数字转数值进行相加。
-
、*
、/
、%
运算:都是隐式转换为数值运算。
==、>、<
比较运算符 :不同的值类型转数字;都是字符比较码值;如果存在对象,先转换为原始值。
console.log("-1" - 1); // -2
console.log(2 > true); // true
console.log("one" + true); // onetrue
console.log("1.5" * 2); // 3
console.log("1.5" + 2); // 1.52
console.log([5] / 2); // 2.5
??显示类型转换 就是调用各种方法、类型构造函数进行显示的数据转换。
toString ():基本每种数据类型都提供了toString()方法,转换为字符串,除开null和undefined不可使用,会报错。
类型构造函数 :Boolean()、Number()、String()的类型函数,都可以转换对应数据类型。
valueOf ():valueOf()方法可以转换对象为一个基本数据值。
其他如parseInt ()、parseFloat ()...等方法。
3.4、值类型与引用类型
??堆和栈 :
栈(stack) :提供代码执行环境,并存放值类型、变量标识符。速度快,空间有限(不同浏览器不同)。
堆(heap) :存放引用类型数据,速度慢,空间大。
值类型(基本类型)
对象/引用类型
数据类型
undefined、null、Boolean、Number、String、Symbol
Array、object、window,function等 包装类型:String、Number、Boolean; 单体内置对象:Global、Math
存储位置
存储在栈中 (变量标识符、变量值),占用空间固定
存储在堆中 ,占用空间不固定。变量标识符存储在栈区,值为地址指针,指向存储在堆区的对象数据。
属性方法
不能添加任何属性、方法。
可以动态添加属性和方法
复制
复制变量值
复制地址指针(变量值是对象的指针),指向同一对象
参数传递
值传递,不影响原有变量
引用地址传递,共用同一个对象
垃圾回收
函数执行完就回收了
没有任何引用时,才会被垃圾回收机制收回
类型验证
typeof
:typeof 0; //number
instanceof
:[] instanceof Array //true
Object.prototype.toString.call({}) //[object Object]
==比较
值类型是值比较
引用类型比较引用地址,所以要用恒等===
比较
04、运算/操作符
4.1、?算数运算符
运算符
描述
示例
+
加
-
减
*
乘
/
除
%
取余数
6%3; //=0
**
指数,幂运算,等同于Math.pow(a,b)
3**2; //=Math.pow(3,2)=9
++
自加1,符号在前面的先运算,再赋值 ,在后面的反之
x=++y; //y=1+y; x=y;
x=y++; //x=y;y=1+y;
--
自减1,同上
??运算符优先级: [ ++,--,!] > [*,/,% ] > [ +,- ]
var x=1; //经典面试题
console.log(x+x++ + ++x); //1+1+(1+2)=5
?? +
加运算符会隐式转换 :+运算 就是字符相加、数字相加两种情况
boolean、数字相加会隐式转换为数值进行相加。
字符串 + 非字符串会隐式转换为字符串。
console.log(true+false); //1
console.log(true+3); //4
console.log(true+"1"); //true1
console.log("123"+123); //123123
console.log("123"+[1,2,3]); //1231,2,3
??-
,*
,/
,%
隐式转换数值 :都是数学运算转数字。减、乘、除、取余 运算都是数学运算,会隐式转换为数字再运算。
console.log("123"-"12"); //111
console.log("123"-12); //111
console.log("123"-1-true); //121
console.log("123"/true); //123
console.log("123"/2); //61.5
4.2、??赋值运算符
运算符
描述
示例
=
赋值运算符,一个神圣的仪式
+=
加法赋值
x+=y //x=x+y
-=
减法赋值
x-=y //x=x-y
*=
乘法赋值
x*=y //x=x*y
/=
除法赋值
x/=y //x=x/y
%=
取余赋值
a%=3 //a=a%3
4.3、??比较运算符
运算符
描述
示例/备注
>,<,>=,<=
大于,小于,大于等于,小于等于
==
相等比较,比较变量的值,而不管其类型
"1"==1; //true
===
恒等比较,比较类型和值
无类型转换
!=
!=
不等于比较
!==
!==
不恒等比较
无类型转换
比较运算符会隐式转换为数值 !
都是字符,转为码值进行比较,
两个不同类型比较,隐式转为数值,然后进行比较。
引用类型 永远不相等,虽然其内部的数据一模一样,因为比较的是引用地址。
推荐恒等 ,由于 ==
、!=
比较会隐式转换,会遇到较多奇葩问题,在开发中,我们一般使用严格比较恒等 ===
!==
。
NaN 与任何值比较,都是false, Infinity 只等于它自身。console.log(NaN==NaN); //false
null 和 undefined, 他们直接相等,和其他原始类型比较,不相等。
console.log("123">"45"); //false 都是字符比较字符码值
console.log("123">45); //true 转换为数值比较
console.log("123"==123); //转数值比较,true
console.log(""==false); //true 转为数值比较
console.log("false"==false); //false 转为数值比较
console.log("true"==true); //false 转为数值比较
console.log([1,2,3]==[1,2,3]); //false,数组是对象
4.4、?逻辑运算符
运算符
描述
示例/备注
!
!
逻辑非 运算符
!false //true
&&
&&
、|| 也叫短路运算符 :从左往右判断,符合要求就不继续执行了逻辑与 &&
=同时满足:返回第一个为false
的值,否则最后一个值
1 && 2 && 3 //返回3
1 && 2 && false && 3 //返回false
||
逻辑或 =满足一个即可:返回第一个为true
的值,否则最后一个值
1 || 2 || false //返回1
逻辑运算符会隐式转换为boolean
值。
短路运算符 &&
、||
常用来判断都为真、至少有一个为真:
let user = { name: "sam", score: 98, age: 12 };
if (user.age <= 12 && user.score > 95)
console.log(`${user.name} 是一个少年天才!`);
4.5、??其他操作符
运算符
描述
示例
?:
三元表达式 :判断条件 ?条件为真 :条件为假
age = 4 > 2 ? 4 : 2; //4
??=
逻辑空赋值运算符 : (x ??= y) 仅在 x 是(null 或 undefined) 时对其赋值y
x??="default";
?. ||
可选链运算符 ,不为空(null 或 undefined)时才执行。可以没有 ||,返回undefined
page=res?.data?.size ||1;obj?.[prop]; obj.func?.()
void
运行表达式,返回一个 undefined
void alert("void")
&,|,~,^,<<,>>
二进制位的运算,32位数字的位运算
delete
删除 一个对象的属性、数组键值,删除后会变为undefined
delete objt.pro
typeof
获取数据类型,typeof (operand)
,括号省略。
typeof null; //object
in
判断属性是否在对象中
"length" in [] //true
instanceof
判断对象是否指定的类型,用于引用类型、自定义类型
[] instanceof Array //true
new
new Object()
创建对象实例
superIE??
调用一个对象父类的函数,在子类中调用
supper.print();
05、逻辑语句
if/switch条件判断
if
条件语句,根据条件执行。if
可单独使用,也可以跟else if
(0个或多个,中间)、else
(0个或1个,放最后)。
if (条件) { /*代码*/ }
else if(条件) { /*代码*/ }
else if(条件) { /*代码*/ }
else { /*代码*/ } //可以不要else部分,单独if
switch
定值 条件分支,值的判断是用的===
恒等比较,多用于枚举值、固定的常量值。注意 每一个case后需要用break,以防止穿透(继续往后执行)。
switch (表达式) {
case 值1:
/*代码*/;
break; //返回,结束switch,防止无意义的穿透执行
case 值2:
case 值3: //可以多case合并一块
/*代码*/;
break;
default: //前面的case都没有命中时执行
/*代码*/
}
try.catch异常处理
用 try...catch ...finally 语句捕获异常,throw 语句抛出一个异常。
JS代码如果发生了异常,则不会再执行后面的代码了,就需要做好异常捕获处理。
finally
语句块为可选,不管是否抛出异常都会执行,常用来做一些清理收尾工作。
throw
抛出异常,可以是自定义的值、对象,可以用Error
对象包装一个错误信息。
function print(para) {
if (para <= 0) {
throw "参数para必须大于0(para= "+para+")";
throw new Error("参数para必须大于0(para= "+para+")");
}
console.log(para);
}
print(2); //如果这里参数用-2,则会抛出异常,这里的异常没人管,后面的代码就不会执行了
try{ //try包装要执行的代码
print(-2);
}
catch(e){ //catch捕获try中抛出的异常并处理,参数为捕获到的异常信息,如果没有异常则跳过catch语句
console.log("发生错误:" + e);
}
finally{
console.log("执行完毕!") //始终会被执行的代码,用于一些清理收尾工作
}
break/continue
break :结束循环 ,停止本层循环,跳出本层循环,大家都别干了!
continue :结束本次循环, 暂停本次循环,不执行后面的代码了,继续下一次循环,我不想干了,你们继续!
while(true) { }
while
循环,先判断,符合条件才执行,会循环的判断条件 》 执行 ,所以必须注意结束循环的控制,不然就是死循环了。
while(条件表达式){
/*循环代码*/
//条件控制代码,别忘了
}
do{ } while (true)
do...white
循环,先执行 》 再判断 。同while,需注意循环的控制,避免死循环。
do{
/*循环代码*/
//条件控制代码,别忘了
}while(条件表达式)
for(i,i
循环执行逻辑控制语句:
for(初始化语句;判断条件语句;控制条件语句){
/*循环代码*/
}
for(let i=1;i<=10;i++){ //循环1到10
if(i>6)
break; //跳出并结束循环
if(i%2==1)
continue; //如果是奇数,返回继续下一次循环
console.log(i);
}
for(in){ }可枚举属性
for...in 循环,对一个对象(不仅仅是数组)进行循环遍历,遍历其所有 可枚举的属性(索引下标、属性),包括继承来的。
let arr=[1,2];
arr.uname="arr";
arr.print=function(){console.log(this.length)};
for(let i in arr){
console.log(i+":"+arr[i]);
}
/*输出:
0:1
1:2
uname:arr
print:function(){console.log(this.length)}
*/
?慎用 for(in)
:for(in)是循环遍历的是所有可枚举的(enumerable)属性,对于数组、可迭代集合一般使用for(of)
。
for(of) {}集合值迭代
for…of (IE??)语法是ES6新引入的语法,用于遍历可迭代(iterable)对象,只遍历数组对象元素。包括字符串String、数组Array、集合Set、字典Map、arguments 对象、DOM NodeList 对象等。
和for...in
最大的区别就是,for...of
迭代的是集合的数据值,而不是可枚举属性(索引)。
let arr=[1,2];
arr.uname="arr";
arr.print=function(){console.log(this.length)};
for(let i of arr){
console.log(i); //1 2
}
forEach()数组方法
forEach 作用于数组对象,用于遍历数组对象的每一个元素,并对每一个元素执行回调(callback)函数。
语法:ArrayObject.forEach (callback(currentValue, index, arr), thisValue))
let arr = [1, 2];
arr.uname = "arr";
arr.print = function () { console.log(this.length) };
arr.forEach(function (item, index) {
console.log(index + ":" + item);
});
/*输出:
0:1
1:2
*/
??版权申明 :版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀