JavaScript知识点梳理

* html + css + js 实现网页内容结构 , 表现 , 行为的分离
    * html + css = 静态网页
    * html + css + js = 动态网页 dhtml
    * javaee 动态网页

1) javascript : 基于对象和事件驱动的脚本语言,是一种编程语言
    * 编程语言: 变量,判断,循环 实现动态功能效果
    * 基于对象: 语法与java面向对象语法类似,但没有完全实现面向对象的特征
    * 事件驱动: js可以编写许多功能(函数,方法),可以不需要其他函数调用
                 可以通过浏览器的一些操作(点击,移动鼠标,按下键盘)触发js函数功能 (事件驱动)
    * 脚本语言: js不能独立执行,需要配合html,运行在浏览器上。
    
    * java源代码不能直接运行,需要通过编译产生字节码文件(检测语法),通过 jvm加载并运行程序
    * js是一种解释性语言,没有编译过程,运行过程中边运行边解释(语法错误,逻辑错误10/0)
    
2) js组成:
    * ECMAScript js引擎 语法标准
    * DOM document object model 通过js操作html
    * BOM browser object model  通过js操作浏览器(刷新浏览器,关闭浏览器,打开新浏览器,前进,后退)

3) js编写
    a) 在html网页的<script>中嵌入编写js代码
        <script type="text/javascript">
            alert('我是一个js应用');
        </script>
    b) 将上述<script>中的代码原封不动的复制到.js结尾的文件中,使用<script>标签引入html
    
    * 补充:
        * 引入和嵌入不能使用同一个<script>
        * 引入时,<script>的起始和结束必须完善

4) 基本语法:
    (4.1) 变量: 
        * 是一个容器,可以装载数据
        * 当前行产生了数据,需要在后面的代码行中使用,就需要将数据先装入变量。
        * 变量使用就2种 装数据,取数据。
        
        * 要想使用变量,需要先声明(定义)变量 : 类型 名称 ;
        
        * 弱类型变量:
            * js中的变量是弱类型变量
            * 在定义变量时,无法确定变量未来装载数据的类型
            * 使用var关键字定义
                var i ;  // String i ; int i ; double i ;
                
            * 扩展:
                弱类型变量具体类型有变量装载的数据决定,装入整形,变量类型就是整形。
                弱类型变量可以装载任意类型的数据
                    var i = 10 ;
                    i = "duyi" ;
                    i = true ;
    (4.2) 数据类型 (6种)
        1. 数字类型 : number
            * 包括整形和浮点型
            * var i = 10 ;
            * var i = 3.14 ;
        2. 字符串类型: string
            * js没有字符和字符串之分
            * 字符串可以使用单引号或双引号包含
            * var s = "duyi" ;
            * var s = 'duyi' ;
        3. 布尔类型:  boolean
            * 只有true、false 2个值
        4. 对象类型:  object
            * null也是一种的特殊的对象值(对象的引用不存在)
            * 产生对象
                var obj = new Object();  创建了一个没有属性和功能的对象
                var obj = {} ;             创建了一个没有属性和功能的对象    
            * 自定义属性
                * 使用对象的属性时,如果没有就自动创建。
            * 使用对象属性
                * obj.uname = 'duyi' ;
                * alert(obj.uname ) ;//弹框 显示obj.uname属性值
            
            * 扩展:创建对象的同时初始化属性
                var obj = {
                    uname:'dmc',
                    age:17,
                    sex:'男'
                };
        5. 值未定义类型:undefined
            * 只有1个值 undefined
            * 定义了一个变量/属性,但没有赋值,默认值就是undefined
        
        6. 函数类型: function
            * 方法也是一个独立的数据
            * 后面详细讲
        
        * 扩展: 使用typeof关键字 获得变量数据的类型
            var i = 10 ;
            console.log(typeof i ) 浏览器控制台打印结构 [类似于 System.out.println();]
            
    (4.3)运算符
        1. 算数运算符: + - * / % ++ -- 
            5/2 -> 2.5
        2. 赋值运算符: = += -= *= 
        3. 比较运算符: > < == !=  === !==
            * == 与 === 区别
            * == 忽略类型比较
            * === 带类型比较
        4. 逻辑运算符: ! && ||
            * 只有短路与和短路或
            * & | 就表示位运算
        5. 条件运算符(三目,三元) : boolean结果?值1:值2
    (4.4) 分支判断
        * if判断条件不仅仅可以是boolean结果,也可以是其他类型的结果
        * 0表示false,非0表示true    if( i != 0 )  --> if(i)
        * null表示false                if( obj != null) --> if(obj)
        * undefined表示false
        
        * switch与java类似。
    
    (4.5) 循环
        * while和do-while语法逻辑与java相同
        * 循环的判断题条件与if一样,除了boolean结果,也可以是其他类型
        
        * for循环注意i初始化
            for(var i=0;i<10;i++){}
            
        * 扩展: for-in循环
            * 可以循环遍历数组中的元素,也可以循环遍历对象的属性(类似于反射机制)
            for(int num : nums){}
            for( i in array){
                //array表示遍历的数组,i表示每次遍历获得的数组下标,可以根据下标获得数组的值
                console.log(i+','+array[i]);
            }
            for( p in obj){
                //obj表示遍历的对象,p表示每次遍历获得的对象属性名,可以根据属性名获得属性值
                console.log(p+','+obj[p]);  //user['uname'] === user.uname
            }
    (4.6) 数组    
        * 可以存储一组数据
        * 创建数组
            1. var array = new Array();     //创建一个长度为0的数组
            2. var array = [] ;                //创建一个长度为0的数组
        * 数组的使用
            * array[0] = 10 ;  赋值时,如果原来没有该位置,就开辟这个位置,且length=1
            * array[1] = 10 ;
            * array[10] = 10 ; 为小标为10的元素赋值成功,length=11 ,其中[2]...[9]位置的元素值undefined
        * 扩展:初始化
            * var array = new Array(10);   //创建10个长度的数组,10个元素默认值为undefined
            * var array = new Array(1,2,3,4); //设置初始元素
            * var array = [1,2,3,4] ;       //设置初始元素
        * 数组属性
            array.length 获得数组元素的长度。
        * 数组方法:
            array.push(); 向数组的末尾增加一个元素 (java中使用list集合造了栈Stack-Vector-List.push())
            array.pop();  移除数组中最后一个元素  (push + pop = 栈)
            concat(array2) ; 连接两个数组元素
            join('+'); 将数组中的元素使用指定符号组成字符串
            reverse(); 数组反转
    (4.7) 字符串
        * 与java类似,有许多字符串操作的方法
        * 常用方法: var str = "duyi is good" ;
            str.length ; 字符数量(属性)
            str.indexOf()
            str.lastIndexOf()
            str.substring()
            str.replace('a','A')
            str.split(',')
            str.startsWith()
            str.endsWith()
            str.toLowerCase()
            str.toUpperCase()
            str.concat()  
            str.charAt()
    (4.8) 日期
        * var date = new Date();获得日期对象,存储当前系统日期
        date.getTime();    自1970-01-01 获得毫秒数
        date.setTime(); 设置一个新日期的毫秒数
        date.getFullYear(); 2021
        date.getMonth() ;   月索引 4+1=5
        date.getDate() ;    14日
        date.getDay()  ;    星期索引,从星期日开始(0)
        date.getHours();    13点
        date.getMinutes();  54分
        date.getSeconds();  30秒
    (4.9) Math
        Math.abs() 绝对值
        Math.min(n1,n2) 返回最小的数
        Math.max(n1,n2) 返回最大的数
        Math.pow(m,n) 返回m的n次幂
        Math.ceil()  向上取整
        Math.floor() 向下取整
        Math.random() 产生[0.0-1.0)随机数
            Math.random()*10 ==> [0,10)
            Math.random()*5+5 ==>[5,10)
        Math.round()  四舍五入
    (4.10) 其他常用的方法
        parseInt(3.14) 将浮点数转换成整数 3
        parseInt("120") 将符合数字格式的字符串转换成的数字  120
            "120"+1="1201" , parseInt("120")+1=121
            * 注意:  parseInt("120abc") 将数字开头的字符串中,开头的数字部分转换成数字  120
                      只能开头。如果不是以数字开头的字符串,转换后获得NaN 表示"不是一个数字"
        parseFloat("3.14a")将符合浮点数格式的字符串转换成浮点数 3.14
        eval() 将符合某种格式的字符串按照那种格式转换或执行
            eval('1+2+3'); -->6
            var arr = eval('[1,2,3,4,5]'); ---> 转换成数组
                      
    (4.11)函数:
        * 表示一个行为,一个动作,一个操作,一个功能 。 类似于java的方法。
        * 创建函数(3种)
            方式1: 
                function sum(num1,num2){
                    return num1+num2 ;
                }
                
                * 不用像java一样指定返回类型,可以根据需求,使用return返回所需要的数据即可。
                * 参数列表的变量无序使用var修饰
            方式2:
                var sum = function(num1,num2){
                    return num1+num2 ;
                }
                * 当前函数被称为匿名函数
                * 函数也是一种数据类型,所以函数就是函数类型的数据
                    * 既然函数是一个数据,就可以存入变量
                * 变量名即为函数名。
            方式3:
                var sum = new Function("num1","num2","return num1+num2 ");
        * 调用函数
            fn1();
            fn2(10,20);
            var result = fn3();
            var result = fn4(10,20);
        
        * 扩展: 预编译问题(提升)
            浏览器执行js是,会对函数和变量的声明有一个提升声明操作
            //可以调用
            a();
            function a(){}
            -----
            //不可以调用
            //知道有一个叫a变量,但不知道变量的值,所以无法调用
            a();
            var a = function(){};
            
            * 扩展: 使用let关键修饰变量,阻止提升
                //可执行
                console.log(x);
                var x ;
                ---
                //不可执行
                console.log(x);
                let x ;
                
        * 扩展:函数传参
            * 在java中,定义方法时参数列表有几个变量,调用方法时就需要传递对应数量的实参
            * 在js中,传递参数的实参数量可以与函数形参数量不一致
                function sum(num1,num2){}
                sum(10,20)
                    * num1=10,num2=20
                sum(10);
                    * num1=10,num2=undefined
                sum(10,20,30,40)
                    * num1=10,num2=20,?=30,?=40
                    * 每一个函数都内置了一个arguments数组对象(不用定义,直接使用)
                    * 该数组对象装载所有的参数
                    * 可以通过遍历获取
        * 扩展: 变量的作用域
            * 在函数中定义的变量,称为局部变量。只能在函数中使用
            * 在函数外定义的变量,称为全局变量,所有函数中都可以使用。
            * 在函数中直接初始化,未使用var定义的变量,也是全局变量
                function f1(){
                    i = 20 ;
                    console.log(i);
                }

                function f2(){
                    console.log(i);
                }
        
        * 扩展:函数类型的参数和返回值
            * js的数据类型中有一种类型:函数类型
            * 函数类型的数据就是:函数
            * 函数也是一种数据
            * 调用函数时可以传递整形数据,字符串类型的数据,能不能传递函数类型的数据呢?     能
            * 调用函数后,可以返回整形数据,字符串类型的数据,能不能返回函数类型的数据呢?  能
            * 函数类型的参数如何使用。 函数类型的返回值如何使用
                //var f1 = 值 ;
                var f1 = function(){ console.log('duyi') };
                var n1 = 10 ;

                function f2(param){
                    //如果传递的是一个函数
                    //param存储的就是一个函数
                    //和f1存储一个函数是不是一个概念?
                    //f1中存储的函数怎么使用,f1相当于函数名  f1();
                    //param中存储的函数,param相当于函数名 param();
                    
                    param();

                    return f1 ;
                }

                var f3 = f2(f1);
                //f3变量存储的就是返回来的函数,f3相当于函数名 f3();
                f3();
        * 扩展:自调用函数
            * 定义函数同时就执行函数,不需要单独的调用代码。
                (
                    function f1(num){
                        console.log('duyi is good');
                        console.log(num);
                    }
                )(10);
        * 扩展:函数作为构造函数+this关键字创建对象 
            //像一个模板
            function Car(cno,cname,color,price){
                this.cno = cno ;
                this.cname = cname ;
                this.color = color ;
                this.price = price ;
            }
            // var car1 = {cno:1003,cname:'qq',color:'red',price:60000};
            // var car2 = {cno:1004}
            var car1 = new Car(1001,'bmw','red',300000); //此时构造器中的this关键字表示car1
            var car2 = new Car(1002,'benz',black',400000);//此时构造器中的this关键字表示car2
            
            * 注意: this就表示创建的对象
            
            * 注意: 构造对象时,如果属性的类型是一个函数类型,那么这个属性就是方法
                var car = {
                    cname:'bmw',
                    getCname:function(){
                        return this.cname ;
                    }
                }
                ---
                function Car(cno,cname,color,price){
                    this.cno = cno ;
                    this.cname = cname ;
                    this.color = color ;
                    this.price = price ;
                    this.getCname = function(){
                        return this.cname ;
                    }
                }
            
            * 注意: 对象的原型链
                * 使用构造器创建了2个对象
                * 2个对象中获得的方法属性值是不同的
                    var f1 = car1.getCname ;
                    var f2 = car2.getCname ;

                    console.log(f1 == f2);
                * 从功能而言,2个对象的相同方法做的是一样的式,执行的是相同的函数代码
                * 如果相同的代码产生了2份,耗内存。
                * 可以使用对象的原型链实现单例函数处理(类似于java的static)
                    Car.prototype.getCname = function(){
                        return this.cname ;
                    }

5) 事件:
    * 通过操作浏览器或浏览器中的内容触发一个js函数调用。
    * 事件分类
        a) 浏览器事件
            * 需要配合后面js-bom
            * 打开浏览器
            * 关闭浏览器
        b) 鼠标事件
            * onclick 鼠标左键单击事件
                * 在某一个(按钮)标签上,按一下鼠标就会触发点击事件,就可以调用指定的函数
                * 浏览器内部使用观察者模式实现事件响应
                <button οnclick="t1()" οndblclick="t2()">按钮1</button>
                <button >按钮1</button>
            * ondblclick 鼠标左键双击事件
            * oncontextmenu 鼠标右键单击事件
            * onm ousedown 鼠标按下
            * onm ouseup 鼠标抬起
            * onm ousemove 鼠标移动
            * onm ouseover 鼠标移入某块区域
            * onm ouseout 鼠标移出某块区域
            * onm ousewheel 鼠标滚轮事件
        c) 键盘
            * 一般都是针对于可以输入,可选择的表单标签
            * onkeydown 键盘按键按下
            * onkeyup 键盘按键抬起
        d) 表单标签
            * onfocus 表单组件获得焦点事件
            * onblur 表单组件失去焦点
            * onselect 选择组件内容 
            * onchange 改变组件内容
            * onsubmit 表单组件提交请求时触发事件(一般在请求前验证请求数据是否合法)
                * 从操作而言,点击按钮才开始提交的
                * 但从编码而言,最终提交的不是按钮,是<form>表单
                * 这个提交事件是属于表单的
                * 在事件函数中通过返回值true、false来继续请求或终止请求
            * 注意:
                * 上述事件在标签中有对应的事件属性
                * 在浏览器内部处理事件的机制
                    * 浏览器通过请求获得网页内容 (请求服务器,请求本地)
                    * 浏览器就会加载并处理网页内容
                    * 在处理过程中,会发现当前这个标签设置了一个事件属性(onsubmit)
                        * 第一件事,将该标签装入对应的观察者集合中
                        * 第二件事,根据事件属性的值,生成一个函数
                            οnsubmit="t2()" 
                            从html角度而言,"return t2()" 是一个字符串值
                            浏览器内部 new Function("return t2()"); === function xx(){ return t2() };
                    * 当浏览器中在该标签上触发指定的事件时,马上就会通知观察者,观察者就会调用指定的函数
                    * 所以如果t2这个函数返回了一个false,这个false返回给了内部创建的函数,而没有返回给浏览器
                    * 最终需要在内部函数中再返回一次,返回给浏览器。
6) DOM : 文档对象模型
    * 作用: 通过操作js对象,间接影响html内容,效果。
    * dom原理:见图
    * 浏览器中内置document对象,所有标签对应的标签对象都会按照标签的子父关系存储在document中。
        * 可以从document中获得要操作的标签对象
        * 可以通过标签对象操作对应的标签
    
    (6.1) 标签整体操作
        a) 创建标签对象
            var div = document.createElement("div");
                * 新创建的表现并没有显示在浏览器上,因为没有指定其显示的位置(子父关系)
        
        b) 放置标签对象
            parentElement.appendChild(childElement); 
                * 将子标签对象放置在父标签对象的末尾
                * 子标签也会显示在父标签的结尾
                    <ul>
                        <li>1</li>
                        <li>2</li>
                        <li>3</li>
                        就是ul的结尾
                    </ul>
                * 扩展: 
                    document.body 获得body标签对应的对象    
            parentElement.insertBefore(newElement , oldElement);
                * 扩展: 在html中触发事件函数时,可以通过传递this表示当前的标签对象
                    <button οnclick="t1(this)">增加一个input标签</button>
            * 注意: 不是只能放置新创建标签,可以放置任何能得到的标签
        
        c) 删除标签对象
            parentElement.removeChild(childElement);
        
        d) 获得标签对象
            var e = document.getElementById(id); 
                * 根据标签id属性值,找到第一个符合条件的标签对象
            
            var eArray = document.getElementsByTagName(tagName);
                * 根据标签的名字,找到所有符合条件的标签
                * 扩展:
                    parentElement.getElementsByTagName(tagName);
                        * 在指定的父级标签中,找到符合条件的子标签。
                        <body>
                            <a></a>
                            <div>
                                <a></a>
                            </div>
                        </body>
            
            var eArray = document.getElementsByClassName(className);
                * 根据标签class属性值,找到所有符合条件的标签。
                
            var eArray = document.getElementsByName(name) ;
                * 根据标签的name属性值,找到所有符合条件的标签 (表单标签)
                
            * 扩展:document.querySelector(css选择器)   --> jquery
            -----
            * 已经找到了一个标签对象 (sourceElement)
            var eArray = sourceElement.children ;
                * 获得已知标签的所有子标签对象
                
            var e = sourceElement.parentNode ;
                * 获得已知标签的父级标签对象
                
            var e = sourceElement.nextElementSibling;
                * 获得已知标签的下一个兄弟标签对象
                
            var e = sourceElement.previousElementSibling;
                * 获得已知标签的上一个兄弟标签对象
            
            -----
            * 特殊情况
            selectElement.options
                <select>
                    <option></option>
                    <option></option>
                </select>
            table.rows
            table.cells
            row.cells
            document.body
            
    (6.2) 标签个体操作
        a) 操作标签属性
            i) 绝大多数情况下,标签有什么属性,标签对象就有什么属性
                <input name="" value="" />
                ---
                input.name , input.value 
            ii) 有些标签属性和标签对象属性不一致
                <input class="" />
                ---
                input.className=""
            iii) 有些标签没有,但标签对象有的属性
                div.tagName  获得标签名,获得的都是大写字母 div.tagName == 'DIV'
                div.innerHTML 获得标签内容    “<a>百度</a>”
                div.innerText 获得标签内的文本内容 “百度”
                    <div>
                        <a>百度</a>
                    </div>
            iv) 有些标签属性值和标签对象属性值不同
                <input readonly="readonly" disabled="disabled" checked="checked" selected="selected" />
                ---
                input.readOnly=true/false
            v) 有些标签属性对应的标签对象属性需要使用驼峰命名法
                <input readonly="">
                ---
                input.readOnly=true
                
        b) 操作标签事件
            * 从html设置事件而言,事件类似于标签的一个属性,只不过属性值是一个函数
                <input name="" value="" οnclick="t1()" />
                ---
                input.name , input.value
                input.onclick = function(){
                    //coding
                }
                ===>
                new Function("t1()");
                ===>
                function (){
                    t1();
                }
            
            * 扩展: 事件绑定
                * 可以在一个标签上增加多个相同的事件:事件绑定
                * btn.addEventListener('click',function(){ coding... });
            * 了解: 阻止事件冒泡,阻止事件的默认行为
        c) 操作标签样式
            * 样式不能直接使用标签对象处理
            * 需要通过标签对象获得一个样式对象
                var style = div.style ;  获得了标签的行内样式属性,可以设置行内样式也可以获得行内样式
                var style = getComputedStyle(div); 获得的样式对象只能获得所有样式不能设置样式
            * 通过这个样式对象处理样式
                i) 大多数情况下,css有的属性,样式对象也有
                    div{width:100px;height:100px;color:red;}
                    ---
                    style.width , style.height , style.color 
                ii) 有些css样式属性由多个单词使用-组合而成:background-color,margin-top,border-bottom-width
                    对应的样式对象属性就是去掉-,多个单词符合驼峰命名法
                    style.backgroundColor , style.marginTop , style.borderBottomWidth
7) BOM
    * 浏览器对象模型
    * js引擎内置了一个对象window对象 --- bom对象
    
    (7.1) window子对象
        a) window.document
        b) window.location 获取/设置浏览器url
            * 通过location改变url,从而实现发送新的请求
            * window.location.href = 'http://www.baidu.com'
        c) window.history 获取浏览器url访问记录,一般用来实现后退,前进等功能
            * window.history.go(-1);
        d) window.event 事件对象 
            * 在触发事件时会产生事件对象
            * event对象的获得存在浏览器兼容问题
                * 有些浏览器(IE,Chrome)可以通过window.event直接获得事件对象
                * 有些浏览器(FF)触发事件函数时,以参数形式传递event对象
                function t3(event){
                    var e = event || window.event ;
                    console.log(e);
                    coding...
                }
            i)   可以通过event获得触发鼠标事件时的 坐标(x,y)
                * 以浏览器左上角为0,0原点
                * event.clientX , eventClientY
            ii)  可以通过event对象获得键盘事件时的按键码(一般我们需要知道回车操作:13)
                * event.keyCode 获得按键码
            iii) 可以通过event对象阻止冒泡,阻止默认行为
                * 取消冒泡:e.cancelBubble=true ;
                * 取消默认行为: 只需要在函数中return false就可以了。
    (7.2) window常用的方法
        注意: 所有window的使用都可以省略window.
            * document,event,location
        a) window.alert(); 显示提示框
        b) window.confirm(); 显示询问框
            * 会根据选择的“确认”或“取消”返回一个boolean
        c) window.open(); 发送请求,在一个新窗口显示
            * open('http://www.baidu.com');
            * 可以像超链接一样,请求的内容在指定的窗口展示
                open(url,target) ;
                open('http://www.baidu.com","_self/_blank/_parent");
            * open(url,"_blank","width=500,height=500,left=100,top=100")
        d) 定时器
            var timer = window.setTimeout(function(){
                //延迟1000毫秒执行(一次)
            },1000);
                * timer称为定时器对象,可以用来阻止定时器
            window.clearTimeout(timer);
            
            
            var timer = window.setTimeout(function(){
                //每隔1000毫秒执行(n次)
            },1000);
            window.clearInterval(timer);
    (7.3)
        * 在js中我们所谓的全局变量和函数其实也是有所属,属于window对象
            function t1(){
                var i = 10 ; //i变量属于t1函数,只能在t1函数中使用
            }
            var obj = {i:10} ; //此时i称为obj对象的属性 obj.i, 表示i属于obj对象
            var obj = {eat:function(){}} ;//此时function函数称为obj对象方法,属于obj对象
            -----------
            var i = 10 ;     //此时i称为全局变量,所有的函数都可以使用,不在属于某一个函数
            function t2(){} //t2,t3函数也不属于某一个对象,我们认为是一个独立的功能
            function t3(){}
            
            * 其实这些全局变量和我们认为的独立函数也属于某一个对象,window
            
            i , t2()
            window.i , window.t2()
    (7.4) window事件
        window.onload = function(){}
        * 浏览器初始化事件,当浏览器加载完毕网页内容时,就会触发当前的事件函数

以上便是javascript必知必会内容,是java后端学习网页展示的基础,大家有什么问题可以在评论区提问,感觉有帮助的可以点个赞和关注,谢谢大家

上一篇:CSAPP缓冲区溢出攻击实验(上)


下一篇:DIV水平垂直居中的CSS兼容写法