1.JS是运行在客户端的一种解释型编程语言,它是一种弱类型的语言。
2.JS的作用:
    用来完成前后端交互、增加用户体验的一些逻辑实现。
3.一个网页是三部分组成:结构(HTML/HTML5)、表现(CSS/CSS3)和形为(JavaScript)。
4.前端开发的核心是:JavaScript。
5.JavaScript的组成:
    1)ECMAScript(标准:ECMA-262):基础语言部分(基础、面向对象等)
    2)DOM(标准:W3C):节点操作
    3)BOM(无标准):浏览器操作
6.JS的特点
    1)松散性
        JS的中变量没有一个明确的类型,也叫弱类型的语言(允许将一块内存看作多种类型)。
    2)对象属性
        对象的属性也可以映射为任意的数据。
    3)继承机制
        JS是基于原型继承的。
7.使用Javascript
    1)使用script标签(只能被当前HTML文件使用)
        <script type="text/javascript" defer="defer" charset="utf-8">
          alert('这是我的第一个JS程序');// alert表示弹出一个警告框
        </script>

        defer:表示所有DOM元素加载完成后,再执行JS代码(现在开发一般不需要)
        charset:字符编码(主要解决汉字乱码问题)(现在开发一般不需要)

        注意:
            a.script标签可以写在网页代码中的任意的地方,因为JS是同步执行的,但为了避免JS阻塞和影响操作DOM,最好写在body后。
            b.如果要输出script结束标签时,必须拆开写:
                alert('</sc'+'ript>');

    2)在a标签的href中写JS代码(实际开发中不建议这种使用,因为会影响到性能)
        <a href="javascript:alert('大家好!')">大家好</a>
        <a href="javascript:var a=10,b=20;alert('结果为:'+(a+b))">计算结果</a>
        <a href="javascript:close();">&times;</a>
        <a href="javascript:void(1);">test</a>
    3)用script标签引入外部JS文件(可以被多个HTML文件使用)
        <script src="01_test.js" type="text/javascript" async="async"></script>

        说明:
            src:引入的外部JS文件的路径和文件名(只能用于引入JS文件)
            async:异步加载JS代码(在加载DOM元素的同时可以运行JS代码)
8.标识符
  所谓标识符,就是指变量、函数、属性的名字,或者函数的参数。
    标识符定义规则:
      1)第一字符必须是一个字母、下划线(_)或一个美元符号($)。
      2)其他字符可以是字母、下划线、美元符号或数字。
      3)不能把关键字、保留字、true、false和null作为标识符。

      关键字:
        break、else、new、var、case、finally 、return 、void、catch、for、switch、while、continue、
        function、this、with、default、if、throw、delete、in、try、do、instanceof、typeof等
      保留字:
        abstract、enum、int、short、boolean、export、interface、static、byte、extends、long、
        super、char、final、native、synchronized、class、float、package、throws、const、goto、
        private、transient、debugger、implements、protected、volatile、double、import、public等

    注意:
        在JS中任意地方是严格区别字母大小写的!!!
9.注释
    1)单行注释
        // 注释内容     一般用于对当前行的代码时进行说明(一般写在代码后面)  (在WebStorm中的快捷键是Ctrl+/)
    2)多行注释 (在WebStorm中的快捷键是Ctrl+Shift+/)
        /*
            注释内容
            注释内容
            ……
        */              也叫作块注释。一般对下面的代码进行整体说明,且说明内容可能较多。

    说明:
        1)注释语句在浏览器中不会被解析执行,仅起说明作用;
        2)在项目中,要习惯去写注释,主要便于后期的项目维护。
10.常量
    常量也叫直接量或字面量,在程序中直接给出具体的数据。
    常量是不可以改变的。
        如:100,true,'abc',null,undefined等
11.变量
    变量就是在内存中开辟一段空间用于存放某个数据。
    变量必须要有变量名,变量名必须遵循标识符的命名规范。

    定义:
        1)只定义变量
            var x;
            var a, b, c;
        2)定义变量且赋值
            var x1 = true;
            var y1 = 100, y2 = null;

        说明:
            1)定义变量时不需要给出数据的类型(松散式语言特点)。
            2)变量可以重复定义,后面会覆盖前面变量。
            3)不用var定义变量也可以,默认是为window对象添加了属性。
                name = '张三'; // 相当于 window.name = '张三';
            4)定义的变量如果没有赋值,系统将自动赋默认值为'undefined'。
            5)一条语句可以以分号结束,也可以不加分号;如果是多条语句写在同一行上,必须用分号隔开。
            6)在书写代码时,除了字符串中可以使用中文标点之外,其它任何地方只能用英文标点符号。
12.数据类型
    数据类型指的是在内存存储的方式。
    分为:
        1)基本数据类型
            number:数值型
                用来表示一个数字,通常可用作进行加减乘除等运算。
                分为整型和浮点型(小数位可以浮动)。
                100(10进制)
                0123(8进制)
                0xae12(16进制)

                isNaN():用来判断是不是不是一个数。
            string:字符型
                用引号(单双引号都可以,它们没区别)引起来的一串字符(可以是数字、字母、标点符号、汉字等),通常用作描述。
                'abc'
                "abc"
                "a\'bc"
            boolean:布尔(逻辑)型
                表示真(true)或假(false)。
            null:空
                表示一个空对象的地址指定指向的为空。
            undefined:未定义
                表示定义了一个变量,但如果没有给这个变量赋值,系统将自动赋值为undefined。
        2)引用数据类型
            object:对象型
                用来申明或存储一个对象(对象,函数、正则、字符、数值等)

                var a = new Number(10);
                var obj = {
                    sno: '007',
                    sname: '张三'
                }
13.运算符
    1)算术运算符
        + - * / %(求余/模) ++(自增) --(自减)
    2)字符串运算符
        +:用于实现字符串连接。
    3)关系运算符
        > < >= <= == === != !==
        返回的结果只能是true或false。
        比较方法:
            a.数值比较,是比较其大小;
            b.字符比较,是比较ASCII码值的大小;
                0->48,A->65,a->97,回车->13,ESC->27
            c.汉字比较,是比较其Unicode编码值的大小
                可以通过charCodeAt()获取编码值。
            d.==和!=只比较值,不比较类型;===和!==既比较值又比较类型

         比较:部分符号<数字<大写字母<小写字母<汉字

    4)逻辑运算符
        逻辑运算符有:!、&&和||三种。返回的值一般是逻辑值true或false,也可能返回其它值。
        !:逻辑非(取反)(单目/一元运算)
            !true -> false   !false -> true
        &&:逻辑与(双目/二元运算)
            只要有一个操作数为false,结果为false。
            注意:
                如果两个中任意一个操作数非逻辑值,第一个操作数的结果为true时,返回第二个操作数的值;
                第一个操作数的结果为false时,返回第一个操作数的值。
        ||:逻辑或(双目/二元运算)
            只要有一个操作数为true,结果为true。
            注意:
                如果两个中任意一个操作数非逻辑值,第一个操作数的结果为true时,返回第一个操作数的值;
                第一个操作数的结果为false时,返回第二个操作数的值。

        短路运算:
            a.&&运算时,如果第一个操作数为false,不需要计算第二个操作数,结果返回false。
            b.||运算时,如果第一个操作数为true,不需要计算第二个操作数,结果返回true。

    5)位运算符
        暂不讲。
    6)三目运算符(条件运算符)
        语法:
            表达式1 ? 表达式2 :表达式3
            如果表达式1成立,返回表达式2的结果;如果不成立,返回表达式3的结果。

        Tips:
            三目运算相当于if语句中的双分支结构。
            如果表达式2或表达式3较为复杂,建议用if语句或switch语句实现。

    运算符优先级:
        运算符                                    描述
        . [] ()                                字段访问、数组下标、函数调用以及表达式分组
        ++ -- - ~ ! delete new typeof void    一元运算符、返回数据类型、对象创建、未定义值
        * / %                                乘法、除法、取模
        + - +                                加法、减法、字符串连接
        << >> >>>                            移位
        < <= > >= instanceof                小于、小于等于、大于、大于等于、instanceof
        == != === !==                        等于、不等于、严格相等、非严格相等
        &                                    按位与
        ^                                    按位异或
        |                                    按位或
        &&                                    逻辑与
        ||                                    逻辑或
        ?:                                    条件(三目运算)
        = += -= *= /= %=                    赋值、运算赋值
        ,                                    多重求值
14.流程控制
    JS是一门既面向过程,也是面向对象的解释型语言。
    面向过程:按照代码书写的顺序依次执行(OOP)。
    JS也是一门结构性语言。
    JS的结构分为顺序结构、分支(条件/选择)结构和循环结构三种。
        顺序结构:按照代码的书写顺序依次执行,一般包含初始化、赋值、输入/输出等语句。
        条件结构:用if或switch语句实现,其中的代码是有条件选择执行的。
        循环结构:某部分代码在指定的条件范围内反复执行,用for/for...in/forEach/while/do...while语句实现。

    1)条件结构
        a.单分支
            语法:
                if(条件)语句;
                或:
                if(条件){
                   语句组;
                }
            如果条件成立,将执行语句或语句组;条件不成立,执行if的下一条语句。

        b.双分支
            语法:
                if(条件)语句1;else 语句2;
                或:
                if(条件){
                   语句组1;
                }else{
                   语句组2;
                }
            如果条件成立,将执行语句1或语句组1;条件不成立,将执行语句2或语句组2。

            注意:else表示“否则”的意思,其后不能写条件。

        c.多分支(三分支及以上的)
            多分支实际上是单分支和双分支的嵌套。
            语法:
                if(条件1){
                    if(条件2){
                       if(条件3){
                         语句或语句组;
                       }
                    }
                }

                或:
                if(条件1){
                   语句1或语句组1;
                }else{
                   if(条件2){
                      语句2或语句组2;
                   }else{
                      语句3或语句组3;
                   }
                }

                或:
                if(条件1){
                   if(条件2){
                     语句1或语句组1;
                   }
                }else{
                   if(条件3){
                      语句1或语句组2;
                   }else{
                      语句1或语句组3;
                   }
                }
                或(简洁写法,推荐):
                if(条件1){
                    语句1或语句组1;
                }else if(条件2){
                    语句2或语句组2;
                }else if(条件3){
                    语句3或语句组3;
                }
                ....
                else{
                    语句n或语句组n;
                }
                如果条件1成立,将执行语句1或语句组1,后面的代码将不会被执行;
                如果条件1不成立,将判断条件2,条件2成立,执行语句2或语句组2……
                如果前面的条件都不满足时,将执行else后面的代码。

        d.情况语句switch
            语法:
                switch(表达式){
                    case 表达式1: 语句1或语句组1;[break;]
                    case 表达式2: 语句2或语句组2;[break;]
                    case 表达式3: 语句3或语句组3;[break;]
                    ...
                    case 表达式n: 语句n或语句组n;[break;]
                    default:语句n+1或语句组n+1;
                }

            说明:执行表达式,如果表达式的结果为case后面的某个对应的值,将执行后面所对应的语句或语句组,如果语句后有break,将终止该情况语句,
                如果没有break,将不再判断条件,继续执行后面的语句,直到遇到break为止;如果条件都不满足,将自动执行default后的语句。

            switch与if的区别:
                switch一般用于能获取结果的简单条件的判断,而if一般用于较为复杂的条件判断;
                if能实现的条件判断,switch不一定能实现,switch能实现的条件判断,if也一定能;
                如果switch和if都能用的情况下,switch一般较简洁些。
    2)循环结构
        I)循环
            a.计数循环(for)
                语法:
                    for([变量初始值];[条件];[步长]){
                        [循环体;]
                        [continue;]
                        [break;]
                    }

                说明:
                    先执行变量初始值,再判断条件,如果条件成立,再循环体,再计算步长,最后再判断条件,条件成立,继续执行循环体……,直到条件不成立,跳出循环为止。

                    该循环的次数是可以计算出来:
                        循环次数=[(终值 - 初值) / 步长] + 1
            b.当型循环(while)
                语法:
                    while(条件){
                        [循环体;]
                        [continue;]
                        [break;]
                    }
                说明:
                    当条件成立时,执行循环体,反之则跳出循环。
            c.直到型循环(do...while)
                语法:
                   do{
                        [循环体;]
                        [continue;]
                        [break;]
                    } while(条件)
                说明:
                    先执行循环体,再判断条件,如果条件成立,继续循环,反之则跳出循环。

                    直到型循环与当型循环的区别:
                        当条件1次都不成立时,直到型循环至少会执行一次循环,而当型循环一次也不执行。
            d.数组和对象遍历(后面再讲)
                for...in
                forEach()

                小结:
                    for只能用于循环次数已知的情况;而while和do...while可以用在循环次数已知或未知的情况,
                一般循环次数已知用for较多;for...in用于遍历数组和对象;forEach()用于遍历数组,for循环也可以遍历数组,但性能较差。
        II)break和continue语句
            break语句可以用在switch语句和循环语句中(forEach循环除外),表示跳出(结束)情况语句或循环。
            continue语句只能用在循环语句(forEach循环除外)中,表示结束本次,继续下一次循环。

            注意:
                a)break和continue语句必须单独存在,后面不能添加其它代码。
                b)break和continue语句一般放在if语句中。

15.函数
    函数就是将具有一定功能的一段JS代码的封装,可以在程序的多个地方被反复调用。
    1)定义函数
        格式一:
            function 函数名([形参列表]){
                函数体;
                [return [<表达式>];]
            }
        格式二:
            var 变量名 = function([形参列表]){
                函数体;
                [return [<表达式>];]
            }
        格式三:
            ;(function([形参列表]){
                函数体;
                [return [<表达式>];]
            })([实参列表]);
            上面的函数叫立即执行函数表达式(IIFE),它会自动调用自身,不被在其它地方被调用,一般用于JS库或JS插件的封装或闭包处理。
    2)函数调用
        函数名([实参列表]);

        Tips:
            函数不会自动执行(IIFE(立即执行函数表达式)除外),必须通过调用才能执行。
    3)return
        函数可以通过return返回结果,如果return没有返回结果,表示结束函数的调用,且返回调用处。
    4)arguments对象
        返回实参列表的一个伪数组。
        一般用在不确定传过来的实参的个数的情况下。
16.对象(object)
    对象,其实就是一种类型,即引用类型。用于将数据和功能组织在一起。
    对象由属性和方法组成,通常用键值对定义。
    1)对象定义
        a)new构建
            new Object([参数]);
        b)字面量定义
            var obj = {
                key: value,// 属性
                fn: function(){ // 方法
                    ...
                }
            }
    2)对象的引用
        a)对象名.属性名
          对象名.方法名([实参列表])
        b)对象名[属性名]
17.数组(Array)
    数组将一组数据组合到一起,并存入到一个变量中,数组是有序排列的,占用一段连续的内存空间。
    一个数组可以存储不同类型的数据。
    1)定义数组
        a.new
            new Array([值列表])
        b.字面量创建
            var arr = [值列表]
    2)获取数组元素值
        数组名[下标] // 下标可以是一个数值型常量,也可以是一个表达式或函数或变量
    3)遍历数组
        一维数组用一个循环实现;二维数组必须用双重循环实现(先行后列)。
        a.for
        b.for...in      // 推荐写法
        c.forEach()
    4)数组的属性和方法
        a.length属性
            获取数组的长度。
        b.方法
            i)push()
                向数组中添加数组到数组最后。
            ii)pop()
                删除数组最后一个元素。
            iii)unshift()
                向数组头部添加数据。
            iv)shift()
                删除数组第一元素。
            v)concat()
                将两个或多个数组组合成一个数组。
            vi)reverse()
                对数组进行倒序处理。
            vii)join()
                将数组转换为字符串。
            viii)splice()
                删除、修改或向数组中添加数据。
18.Function类型
    Function是一个用来构建函数的类(构造函数)。

    函数内部属性
        在函数内部,有两个特殊的对象:arguments和this。
            callee:
                arguments是一个类数组对象,包含着传入函数中的所有参数,主要用途是保存函数参数。
                但这个对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。
                也即是说可以通过arguments.callee调用函数自身,一般用于函数的递归调用。

                函数自己调用自己叫函数的递归调用。

            this指针对象
                在全局中this指向的是window(在JS中没有global这个全局对象,而JS的全局对象是window);
                在函数中this指向的是这个函数执行所操作的当前对象。