• JavaScript学习(二)


    JavaScript学习

    学习自狂神说:https://www.bilibili.com/video/BV1JJ41177di

    学习前端的要点:

    1. 视图
    2. 逻辑
    3. 事件
    4. 通信

    1、基础语法

    • <script></script>标签一定是围堵标签,不能是自闭和标签

    • JavaScript严格区分大小写

    • console.log(); 在控制台打印变量,相当于System.out.println();

    • Infinity:无穷大

    typeof(Infinity)
    > "number"
    
    • NaN六亲不认,任何与NaN进行的判断都为false,只能通过isNaN();来进行判断是否为NaN;
    • ==:类型不同,值相同,为true(类型不一致,会先进行类型转换,在判断值)
    • ===:类型相同,值相同,为true
    NaN === NaN
    > false
    isNaN(NaN)
    > true
    1 == "1"
    > true
    1 === "1"
    > false
    
    • 浮点数问题

    尽量避免使用浮点数进行运算,存在精度问题!

    console.log((1/3) === (1-2/3))
    > false
    console.log((1/3) - (1-2/3) < 0.00000001)
    > true
    console.log(1/3)
    > 0.3333333333333333
    console.log(1 - (2/3))
    > 0.33333333333333337
    
    • js中数组下标越界了,不会报异常,是:undefined
    • 数组用:[]
    • 对象用:{}

    原始数据类型:

    • number:浮点数、整数、NaN
    • string
    • null
    • boolean:true、false
    • undefined

    引用数据类型:对象

    2、严格检查模式

    
    /*
    【前提】:IDEA需要支持 ES6 语法
         'use strict':严格检查模式,预防JavaScript的随意性产生的一些问题
         局部变量建议都使用 let 去定义~
     */
    
    <script>
        'use strict'; //  必须写在第一行,否则浏览器不会报错!
        
        let i = 1;
        
        // 对象的定义
        var person = {
            "name": "sunzhongjie",
            "age": 21,
            "tags": ['java', '前端', '运维', 'js']
        }
    </script>
    

    3、字符串 string

    • 正常字符我们使用单双引都可以

    • 注意转义字符

    /'
    /n
    /t
    console.log("u4e2d") // Unicode字符
    > 中
    undefined
    console.log("x41") // ASCII字符
    > A
    
    • 多行字符串编写(Tab上面的键)
    var msg = `nihao 
    HEllo world!
    你好!`
    
    • 模板字符串 ${} (ES6的新特性)
    'use strict';
    
    let name = "sunzhongjie";
    let age = 21;
    
    let msg = `你好,世界,我叫${name},我今年${age}`;
    
    console.log(msg);
    // 你好,世界,我叫sunzhongjie,我今年21
    
    
    • 字符串长度
    str.length
    
    • string的不可变性

    方法:

    • substring():[begin, end)
    • charAt(index)
    • indexOf(char)
    • toUpperCase()
    • toLowerCase()

    4、数组

    Array可以包含任意的数据类型

    • indexOf():获取指定元素的索引
    • slice():通过下标对数组进行截取
    var arr = [1, 2, null, "abc", true];
    arr.slice(2);
    > [null, "abc", true]
    
    arr.slice(3);
    > ["abc", true]
    
    arr.slice(2, 5);
    > [null, "abc", true]
    
    arr.indexOf(null);
    > 2
    
    • push():压入到尾部
    • pop():弹出尾部的一个元素
    arr.push("123", 12.2);
    > 7
    arr
    > [1, 2, null, "abc", true, "123", 12.2]
    
    arr.pop();
    > 12.2
    
    arr
    > [1, 2, null, "abc", true, "123"]
    
    • unshift():压入到头部
    • shift():弹出头部的一个元素
    arr
    > [1, 2, null, "abc", true, "123"]
    
    arr.unshift(undefined, NaN);
    > 8
    
    arr
    > [undefined, NaN, 1, 2, null, "abc", true, "123"]
    
    arr.shift();
    > undefined
    
    arr
    > [NaN, 1, 2, null, "abc", true, "123"]
    
    • reverse()
    • sort()
    arr = new Array("A", "B", "C");
    > ["A", "B", "C"]
    
    arr.reverse();
    > ["C", "B", "A"]
    
    arr.sort();
    > ["A", "B", "C"]
    
    • concat():拼接数组,返回一个新的数组

    注意:concat()并没有修改数组,只是返回一个新的数组

    arr.concat([1,2,3]);
    > ["A", "B", "C", 1, 2, 3]
    arr
    > ["A", "B", "C"]
    
    • 连接符 join():打印拼接数组,使用特定的字符串连接
    arr
    > ["A", "B", "C"]
    
    arr.join('#');
    > "A#B#C"
    

    5、对象

    若干个键值对
    对象中的键默认都是 string类型,值可以是任意类型的对象

    • 对象的定义(JSON)
    'use strict';
    
    let person = {
        "name":"sunzhongjie",
        "age":21,
        "gender":"true"
    }
    
    • 动态的删除属性 delete
    delete person.gender;
    
    person
    > {name: "sunzhongjie", age: 21}
    
    • 动态的添加属性,直接给新属性添加值即可
    person.gender = "男";
    > "男"
    
    person
    > {name: "sunzhongjie", age: 21, gender: "男"}
    
    • 判断这个属性值是否在这个对象中 xxx in xxx
    gender in person
    VM354:1 Uncaught ReferenceError: gender is not defined
        at <anonymous>:1:1
    (anonymous) @ VM354:1
    
    "gender" in person
    > true
    
    "toString" in person
    > true
    
    • 判断一个属性是否是这个对象自身拥有的:hasOwnProperty("参数")
    person.hasOwnProperty("name");
    > true
    person.hasOwnProperty("toString");
    > false
    

    6、流程控制

    • 判断
    'use strict';
    let age = 3;
    if (age > 2) {
        
    } else if (age < 4) {
        
    } else {
        
    }
    
    • 循环
    'use strict';
    
    let arr = [12, 21, 34, 45, 123, 9789, 12390];
    
    // 普通for循环
    for (let i = 0; i < arr.length; i++) {
        console.log(arr[i]);
    }
    
    // forEach循环 (ES 5.1特性)
    arr.forEach(function (num) {
        console.log(num);
    })
    
    
    // 增强for循环
    for (let index in arr) {
        console.log(arr[index]);
    }
    

    7、Map和Set

    ES6的新特性~

    var map = new Map([['tom', 20], ['jack', 19]]);
    console.log(map.get("tom"));
    map.set("admin", "123456");
    console.log(map);
    
    var set = new Set([1,2,3,2,2]);
    console.log(set);
    
    set.add(5,4);
    set.delete(4);
    console.log(set);
    console.log(set.has(2));
    

    8、Iterator

    • 遍历Set和Map
    var map = new Map([['tom', 20], ['jack', 19]]);
    for (let value of map) {
        console.log(value);
    }
    
    var set = new Set([1, 2, 3, 2, 2]);
    for (let value of set) {
        console.log(value);
    }
    

    9、可变长参数

    问题:arguments 包含所有的参数,我们有时候想使用多余的参数来进行附加操作。
    需要排除已有的参数

    ES6的新特性:rest
    rest参数只能写在最后面,用 ... 标识

    function f(a, b, ...rest) {
        console.log("a=>" + a);
        console.log("b=>" + b);
        console.log("rest=>" + rest);
    }
    

    10、变量的作用域

    内部函数可以访问外部函数,反之不行!

    在JavaScript中,var定义的变量实际是有作用域的。

    假设在函数体中声明,则在函数体外不可以使用。

    function test() {
        var x = 1;
    
        x = x + 1;
    }
    
    x = x + 1; 
    // Uncaught ReferenceError: x is not defined
    

    假设,内部函数变量和外部函数变量,重名!

    函数查找变量从自身函数开始,由 “内” 向 “外” 查找

    function test() {
        var x = 1;
    
        function test2() {
            var x = 'a';
            console.log('inner:' + x);  // inner:a
     
        }
        test2();
        console.log('outer:' + x);      // outer:1
    }
    
    test();
    

    提升变量的作用域

    function test() {
    
        var x = '1' + y;
        console.log(x);
    
        var y = 'y';
    }
    
    test();
    
    结果:1undefined
    

    说明:js执行引擎,自动提升了 y 的声明,但是不会提升变量 y 的赋值,相当于

    function test() {
        var y;
    
        var x = '1' + y;
        console.log(x);
    
        y = 'y';
    }
    
    test();
    

    这个是在JavaScript建立之初就存在的特性。

    养成规范:所有的变量定义都放在函数的头部,不要乱放,便于代码维护;

    全局对象:window

    var str = "xxx";
    alert(str);
    window.alert(window.x);
    

    alert()函数本身也是一个 window 的变量

    var x = 123;
    
    window.alert(x);
    
    var tmp_alert = alert;
    
    window.alert = function () {
    
    }
    
    window.alert('原先alert失效');
    
    alert = tmp_alert;
    
    window.alert('alert');
    

    JavaScript 实际上只有一个全局作用域,任何变量(函数也可以视为变量),假设没有在函数作用范围内找到,就会向外查找,如果在全局作用域都没有找到,报错:ReferenceError

    规范

    由于我们所有的全局变量都会绑定到我们的 window 对象上,如果不同的js文件,使用了相同的全局变量,会造成冲突 --> 如何能减少冲突?

    // 定义自己的唯一全局变量
    var RainSzj = {};
    // 赋值
    RainSzj.name = "sunzhongjie";
    
    RainSzj.add = function (a, b) {
        return a + b;
    }
    

    把自己的代码全部放入自己定义的唯一空间名字中,降低全局命名冲突问题。

    局部作用域 let

    function f() {
    
        for (var i = 0; i < 10; i++) {
            console.log(i);
        }
        console.log(i); // 11
    }
    
    f();
    

    ES6 let 关键字,解决局部作用域冲突问题!

    function f() {
    
        for (let i = 0; i < 10; i++) {
            console.log(i);
        }
        console.log(i); 
        // Uncaught ReferenceError: i is not defined
    }
    
    f();
    

    建议用 let 关键字去定义局部作用域的变量

    常量 const

    在ES6之前,怎么定义常量:只用用全部大写字母命名的变量就是常量;建议不要修改这样的值。

    var PI = 3.1415927;
    console.log(PI);
    
    PI = 123; // 但依旧可以修改
    console.log(PI);
    

    在ES6中引入了常量关键字:const;

    const PI = 3.1415927;
    console.log(PI);
    
    PI = 123; // Uncaught TypeError: Assignment to constant variable.
    console.log(PI);
    

    11、方法

    定义方法

    方法就是把函数放在对象的里面,对象只有两个东西:属性和方法。

    var obj = {
        'name':'sunzhongjie',
        'birth':1999,
        'age': function () {
            var today = new Date().getFullYear();
            return today - this.birth;
        }
    }
    
    // 调用属性
    console.log(obj.name);
    
    // 调用方法,一定要加上括号
    console.log(obj.age());
    

    this. 代表什么? 拆开上面的代码

    function getAge() {
        var today = new Date().getFullYear();
        return today - this.birth;
    }
    
    
    var obj = {
        'name':'sunzhongjie',
        'birth':1999,
        'age': getAge // 这里不需要括号
    };
    

    谁调用它,谁就是:this

    > obj.name;
    < "sunzhongjie"
    > obj.age;
    < ƒ getAge() {
            var today = new Date().getFullYear();
            return today - this.birth;
        }
    > obj.age();
    < 21
    getAge();
    < NaN // window
    

    在 Java中,this是无法指向的,是默认指向调用它的那个对象;

    apply 函数

    是所有的函数公有的

    在js中可以控制 this 的指向

        function getAge() {
            var today = new Date().getFullYear();
            return today - this.birth;
        }
    
    
        var obj = {
            'name': 'sunzhongjie',
            'birth': 1999,
            'age': getAge // 这里不需要括号
        };
    
        // this 指向了 obj,参数为空
        getAge.apply(obj, []);
    
    > getAge.apply(obj, []);
    < 21
    

    12、Date对象

    typeof 关键字

    > typeof 123;
    < "number"
    > typeof 'adf';
    < "string"
    > typeof NaN;
    < "number"
    > typeof undefined;
    < "undefined"
    > typeof Math;
    < "object"
    > typeof Math.abs;
    < "function"
    > typeof {};
    < "object"
    > typeof [];
    < "object"
    > typeof Math.abs();
    < "number"
    

    基本使用

    var now = new Date(); // Mon Jan 20 2020 21:00:20 GMT+0800 (中国标准时间)
    
    now.getFullYear(); // 年
    now.getMonth();    // 月 0 ~ 11 月
    now.getDate();     // 日
    now.getDay();      // 星期几
    now.getHours();    // 时
    now.getMinutes();  // 分
    now.getSeconds();  // 秒
    
    now.getTime();   // 时间戳 全世界统一,自 1970年1月1日 00:00:00 到现在的毫秒数
    console.log(new Date(new Date().getTime())); // 事件戳 转为 时间
    

    转换

    var time = new Date();
    undefined
    time;
    Mon Jan 20 2020 21:13:22 GMT+0800 (中国标准时间)
    time.to
    undefined
    time.toDateString();
    "Mon Jan 20 2020"
    time.toGMTString();
    "Mon, 20 Jan 2020 13:13:22 GMT"
    time.toISOString();
    "2020-01-20T13:13:22.165Z"
    time.toLocaleString();
    "2020/1/20 下午9:13:22"
    time.toLocaleTimeString();
    "下午9:13:22"
    time.toLocaleDateString();
    "2020/1/20"
    

    13、JSON对象

    JSON是什么?

    • JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。
    • 简洁和清晰的层次结构(键值对)使得 JSON 成为理想的数据交换语言。
    • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

    在JavaScript中,一切皆为对象,任何 js 支持的类型都可以用 JSON来表示;

    格式:

    • 对象 和 Map用:{}
    • 数组和List用:[]
    • 所有的键值对,都用 key:value

    JS对象与JSON字符串的转换

    let user = {
        'name': 'sunzhongjie',
        'age': 21,
        'gender': 'male'
    }
    
    // 对象转为JSON字符串
    // {"name":"sunzhongjie","age":21,"gender":"male"}
    let json_user = JSON.stringify(user);
    console.log(json_user);
    
    // JSON字符串转为对象
    let obj = JSON.parse('{"name":"sunzhongjie","age":21,"gender":"male"}');
    console.log(obj);
    

    14、面向对象编程

    类:模板

    对象:具体的实例

    在JavaScript中,需要换一下思维!

    原型

    let student = {
        name: "zhangsan",
        age: 10,
        study: function () {
            console.log(this.name + ",study....");
        }
    };
    
    let wu = {
        name: "wangwu",
    };
    
    // 指定原型对象
    wu.__proto__ = student;
    

    class继承

    ES6中引入的

    1. 定义一个类,属性和方法
    // 定义一个人类
    class Person {
        constructor(name) {
            this.name = name;
        }
    
        eat() {
            console.log(this.name + ",我正在吃饭...");
        }
    }
    
    let person = new Person("张三");
    
    1. 继承
    // 定义一个学生类
    class Student extends Person{
        constructor(name, id) {
            super(name);
            this.id = id;
        }
    
        getId() {
            console.log(this.name + "的ID是:" + this.id);
        }
    }
    
    let student = new Student("李华", 100);
    

    原型链,无上限

    15、操作BOM对象(重点)

    16、操作DOM对象(重点)

    核心

    浏览器网页就是一个Dom树形结构!

    • 更新节点
    • 遍历节点
    • 删除节点
    • 添加节点

    要操作一个Dom节点,就必须要先获得这个Dom节点

    获得Dom节点

    <div class="div">
        <h2>h2~~~</h2>
        <p id="p1">p1~</p>
    
        <p class="p2">p2~</p>
    </div>
    
    // 对应的CSS选择器
    let p1 = document.getElementById("p1");
    let p2 = document.getElementsByClassName("p2");
    let h2 = document.getElementsByTagName("h2");
    
    // 获取父节点下的所有子节点
    let divs = document.getElementsByClassName("div")[0];
    
    // divs.firstChild;
    // divs.lastChild;
    

    这是原生代码,之后我们都是用 jQuery

    更新节点

    • innerText:修改文本的值
    • innerHTML:可以解析HTML文本标签

    删除节点

    删除节点的步骤:先获取父节点,再通过父节点删除自己

    <div id="father">
        <h2>二级标题</h2>
        <p id="p1">段落一</p>
    
        <p class="p2">段落二</p>
    </div>
    
    <script>
        // 删除 段落一 结点
        let self = document.getElementById("p1");
        let father = p1.parentElement;
    
        father.removeChild(self);
    	// 删除是一个动态的过程,以下不可取!
        father.removeChild(father.children[0]);
        father.removeChild(father.children[1]);
        father.removeChild(father.children[2]);
    
    </script>
    

    注意:删除多个节点的时候,children 是在时刻变化的,删除节点的时候一定要注意!

    插入节点

    我们获得了某个DOM节点,假设这个DOM节点是空的,我们通过 innerHTML 就可以增加一个元素,但是如果这个DOM节点已经存在元素了,我们就不能这么干了!会产生覆盖。

    <p id="js">JavaScript</p>
    <div id="list">
        <p id="se">JavaSE</p>
        <p id="ee">JavaEE</p>
        <p id="me">JavaME</p>
    </div>
    <script>
    
        // 标签的移动
        let list = document.getElementById('list');
        let js = document.getElementById('js');
        list.appendChild(js);
    
        // 创建一个新的标签
        let newP = document.createElement('p');
        newP.setAttribute('id', 'Linux');
        // newP.id = 'Linux';
        newP.innerText = "Linux";
    
        list.appendChild(newP);
    
        // 改变 body 的 background-Color
        let body = document.getElementsByTagName("body")[0];
        // body.style.backgroundColor = "green";
        body.setAttribute("style", "background-color: green;");
    
    
    </script>
    

    17、操作表单(验证)

    • 使用MD5算法进行密码加密,需引入
    <!--MD5工具类-->
    <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <!--MD5工具类-->
        <script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script>
    
    </head>
    <body>
    
    <form action="#" method="post" onclick="return check();">
        <span>用户名:</span>
        <input type="text" name="username" id="username">
        <span>密码</span>
        <input type="password" id="input-password">
    	<!--如果不使用隐藏域,提交时,会回显一长串密码-->
        <input type="hidden" name="password" id="password">
    
        <input type="submit">
    </form>
    
    
    <script>
    
        function check() {
            let uname = document.getElementById('username');
            let md5_pwd = document.getElementById('password');
            let input_pwd = document.getElementById("input-password");
    
            // pwd.value = md5(pwd.value);
    
            // 提升用户体验
            md5_pwd.value = md5(input_pwd.value);
            return true;
        }
    
    </script>
    
    </body>
    </html>
    

    1579604945619

    1579604823911

    18、jQuery

    公式:$(selector).action()

    jQuery操作事件

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    
        <script src="lib/jquery-3.4.1.js"></script>
    </head>
    <style>
        #divMove {
             500px;
            height: 500px;
            border: 1px solid red;
        }
    </style>
    
    <script>
        // 等待页面加载完成后,响应事件
        $(function () {
            $('#divMove').mousemove(function (e) {
                $('#mouseMove').text('X:' + e.pageX + ', Y:' + e.pageY);
            });
        });
    </script>
    
    <body>
    
    mouse: <span id="mouseMove"></span>
    
    <div id="divMove">
    移动鼠标试试!
    </div>
    
    </body>
    </html>
    

    jQuery操作DOM

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="UTF-8"/>
        <title>jQuery操作DOM</title>
    
        <script src="lib/jquery-3.4.1.js"></script>
    </head>
    <body>
    
    <ul id="test_ul">
        <li id="js">JavaScript</li>
        <li name="python">Python</li>
        <li name="java">Java</li>
    </ul>
    
    <script>
        // 属性选择器 获取值
        $('#test_ul li[name=python]').text();
        // 设置值
        $('#test_ul li[name=python]').text('人工智能');
    
        $('#test_ul').html();
    
        // $('#test_ul').html('<strong>123</strong>');
    
        $('#test_ul li[name=python]').css('color', 'red');
    
    </script>
    </body>
    </html>
    

    元素的显示和隐藏:本质 display:none

    $('#test_ul li[name=python]').hide();
    
    $('#test_ul li[name=python]').show();
    

    小技巧

    1. 如何巩固JS(看jQuery的源码,看游戏源码)
    2. 巩固HTML、CSS(扒网站,全部down下来,然后对应修改看效果)

    好看的前端样式

    docsify

    ant

    友人c

    layer:弹窗组件

    Element-ui

    vuepress

  • 相关阅读:
    JAVA学习---文件和流
    JAVA学习---集合和工具类
    JAVA学习---异常
    python-time模块
    python-并发编程
    python-网络编程
    python-并发编程之进程
    python-面向对象之多态
    python-面向对象之反射
    python-面向对象之封装
  • 原文地址:https://www.cnblogs.com/rainszj/p/13036644.html
Copyright © 2020-2023  润新知