JavaScript入门①-基础知识筑基


01、JavaScript基础知识

JavaScript(缩写:JS)是一种具有面向对象能力的、解释型的程序语言,基于对象和事件驱动,具有相对安全性的客户端脚本语言。JavaScript是一门完备的 动态编程语言,当应用于 HTML 文档时,可为网站提供动态交互特性,是前端开发最主要、正式的编程语言。

ECMAScript 是由 ECMA 国际标准化组织 制定的一套脚本语言的标准化规范,JavaScript算是他的实现,作为基础语法规范,构成了JavaScript的核心。再加收浏览器提供的DOM(HTML网页内容)操作API、浏览器BOM操作API,共同组成了 JavaScript。

1.1、语法规范

JS代码以行为单位,(半角)分号;结尾。

??注释://

  • 单行注释://开头。
  • 多行注释:/*多行注释 */(同css)

??代码风格:

  • 区分大小写,字母、数字、下划线组成,不能数字开头,不能是关键字。
  • 小驼峰命名(推荐):initialColor

??关键字: 内置的关键词:如var、do、else、enum、eval、false、for、if、void、function、switch...

??语句块:花括号 { 代码块 }

1.2、引用方式

  • 行内JS:元素标签内部的JS代码。
  • 内部JS:定义在 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
    
    • var作用域在整个函数
    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
    */
    

    ??版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀

相关