JavaScript-JS高级

1、创建类和对象
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script>
        // (1)通过class关键字创建类,类名首字母大写
        // (2)类里面有个constructor函数,可以接受传递进来的参数,同时返回实例对象
        // (3)constructor函数只要new生成实例时,就会自动调用这个函数,不写这个函数,类也会自动生这个函数
        // (4)生成实例new不能省略
        // (5)注意语法规范,创建类 类名后面不能加小括号,生成实例 类名后面加小括号,构造函数不需要加function
        // 1、创建类class 创建一个明星类
        class Star{
            constructor(uname,age) {
                this.uname = uname;
                this.age = age;
            }
        }
        // 2、利用类创建对象new
        let ldh = new Star('刘德华',18);
        let zxy = new Star('张学友',20);
        console.log(ldh);
        console.log(zxy);
    </script>
</body>
</html>
2、类中添加方法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    class Star{
        constructor(uname,age) {
            this.uname = uname;
            this.age = age;
        }
        sing(song){
            console.log(this.uname + song);
        }
    }
    let ldh = new Star('刘德华',18);
    let zxy = new Star('张学友',20);
    // 类里面的函数不需要写function
    // 多个函数方法之间不需要添加逗号分隔
    ldh.sing("冰雨");
    zxy.sing("李香兰");
</script>

</body>
</html>
3、super关键字

image-20220313230438392

image-20220314000839522

4、构造函数原型prototype

image-20220314214018669

5、对象原型_ proto _

image-20220314214733754

6、constructor构造函数

image-20220314221112776

7、原型链

image-20220314225418011

8、扩展内置对象方法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    Array.prototype.sum = function(){
        let sum = 0;
        for (let i = 0;i < this.length;i++){
            sum += this[i];
        }
        return sum;
    }
    let arr = [1,2,4,6,20,35];
    console.log(arr.sum());
</script>
</body>
</html>
9、call()
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <script>
        function f() {
            console.log("原始调用");
            console.log(this);
        }

        function fn() {
            console.log("call方法")
            console.log("我是刘德华");
            console.log(this);
        }
        let ldh = {
            name:'刘德华'
        }
        // 1、call() 可以调用函数
        // fn.call()
        // 2、call() 可以改变这个函数的this指向
        f();
        fn.call(ldh,408,903);
    </script>
</body>
</html>

image-20220314233735950

10、借用父构造函数继承属性
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    // 1、父构造函数
    function Father(uname,age) {
        this.uname = uname;
        this.age = age;
    }
    // 2、子构造函数
    function Son(uname,age,scroce) {
        Father.call(this,uname,age,scroce);
        this.scroce = scroce;
    }
    let son = new Son('刘德华',18,100);
    console.log(son);
</script>

</body>
</html>

image-20220315144808430

11、类的本质

image-20220315150523453

12、迭代(遍历)数组forEach方法
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    // forEach 迭代(遍历)数组
    let arr = [1,28,3];
    let sum = 0;
    arr.forEach(function (value, index, array) {
        console.log('索引号:'+index+' 的值为:'+value);
        console.log("数组本身为:",array);
        sum += value;
    })
    console.log("该数组的和为:",sum);
</script>
</body>
</html>

image-20220315151746193

13、筛选数组filter方法

image-20220315152248376

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    // filter 筛选数组,筛选出数组中偶数的值
    let arr = [11,22,33,44,55,66,88,99,77];
    let newArr = arr.filter(function (value,index) {
        return value % 2 === 0;
    })
    console.log(newArr);
</script>
</body>
</html>

//结果:[22,44,66,88]
14、some方法(一真即真)

image-20220315152735477

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let arr = ['pink','yellow','xiaoebaba','red'];
    let flag = arr.some(function (value) {
        return value === "xiaoebaba";
    })
    console.log(flag);
</script>
</body>
</html>

//结果:true
15、every方法(一假即假)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let arr = ['pink','yellow','xiaoebaba','red'];
    let flag = arr.every(function (value) {
        return value === "xiaoebaba";
    })
    console.log(flag);
</script>
</body>
</html>

//结果:false
16、利用数组新增方法操作数据
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        table {
            width: 400px;
            border: 1px solid #000;
            border-collapse: collapse;
            margin: 0 auto;
        }

        td,
        th {
            border: 1px solid #000;
            text-align: center;
        }

        input {
            width: 50px;
        }

        .search {
            width: 600px;
            margin: 20px auto;
        }
    </style>
</head>

<body>
<div class="search">
    按照价格查询: <input type="text" class="start"> - <input type="text" class="end"> <button class="search-price">搜索</button> 按照商品名称查询: <input type="text" class="product"> <button class="search-pro">查询</button>
</div>
<table>
    <thead>
    <tr>
        <th>id</th>
        <th>产品名称</th>
        <th>价格</th>
    </tr>
    </thead>
    <tbody>
    </tbody>
</table>
<script>
    // 利用新增数组方法操作数据
    var data = [{
        id: 1,
        pname: '小米',
        price: 3999
    }, {
        id: 2,
        pname: 'oppo',
        price: 999
    }, {
        id: 3,
        pname: '荣耀',
        price: 1299
    }, {
        id: 4,
        pname: '华为',
        price: 1999
    }, ];

    // 1、获取相应元素
    let tbody = document.querySelector('tbody');
    let search_price = document.querySelector('.search-price');
    let start = document.querySelector('.start');
    let end = document.querySelector('.end');
    let search_pro = document.querySelector('.search-pro');
    let product = document.querySelector('.product');

    // 2、把数据渲染到页面
    setData(data);
    function setData(myData){
        tbody.innerHTML = '';
        myData.forEach(function (value) {
            let tr = document.createElement('tr');
            tr.innerHTML = '<td>'+value.id+'</td><td>'+value.pname+'</td><td>'+value.price+'</td>';
            tbody.appendChild(tr);
        })
    }

    // 3、根据价格筛选渲染到页面
    search_price.addEventListener('click',function () {
        let newData = data.filter(function (value) {
            return  value.price >= start.value && value.price <= end.value;
        });
        setData(newData);
    })

    // 4、根据商品名筛选渲染到页面
    search_pro.addEventListener('click',function () {
        let arr = [];
        data.some(function (value) {
            if (value.pname === product.value){
                arr.push(value);
                return true;
            }
        })
        setData(arr);
    })
</script>
</body>

</html>
17、forEach、some和filter的区别

(1)如果查询数组中唯一的元素,用some方法更合适

(2)some遇到return true会终止遍历,迭代效率更高

18、trim方法(字符串)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="text"><button>确定</button>
<div></div>
    <script>
        // 利用trim方法去掉两侧空格
        let ipt = document.querySelector('input');
        let btn = document.querySelector('button');
        let div = document.querySelector('div');
        btn.addEventListener('click',function () {
            let str = ipt.value.trim();
            if (str === ''){
                alert('请输入内容!');
            }else {
                div.innerHTML = str;
            }
        })
    </script>
</body>
</html>

image-20220315170108768

19、Object.defineProperty()方法(对象)

image-20220315171006884

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    let obj ={
        id:1,
        phone:1234567890
    };
    Object.defineProperty(obj,'address',{
        value:'广东省广州市',// value设置默认的值,默认为undefined
        writable:false,    // writable设置是否可以重写,默认为false,不允许重写
        enumerable:true,  // enumerable设置是否可以被枚举,默认为false,不允许被枚举
        configurable:false // configurable设置是否可以被删除或者是否可以再次修改特性,默认为false
    })
    console.log(obj);
</script>
</body>
</html>

image-20220315172430695

20、函数的定义方式
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        //  函数的定义方式
        // 1. 自定义函数(命名函数) 
        function fn() {};
        // 2. 函数表达式 (匿名函数)
        var fun = function() {};
        // 3. 利用 new Function('参数1','参数2', '函数体');
        var f = new Function('a', 'b', 'console.log(a + b)');
        f(1, 2);
        // 4. 所有函数都是 Function 的实例(对象)
        console.dir(f);
        // 5. 函数也属于对象
        console.log(f instanceof Object);
    </script>
</body>
</html>
21、函数的调用方法
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 函数的调用方式

        // 1. 普通函数
        function fn() {
            console.log('人生的巅峰');

        }
        // fn();   fn.call()
        // 2. 对象的方法
        var o = {
            sayHi: function() {
                console.log('人生的巅峰');

            }
        }
        o.sayHi();
        // 3. 构造函数
        function Star() {};
        new Star();
        // 4. 绑定事件函数
        // btn.onclick = function() {};   // 点击了按钮就可以调用这个函数
        // 5. 定时器函数
        // setInterval(function() {}, 1000);  这个函数是定时器自动1秒钟调用一次
        // 6. 立即执行函数
        (function() {
            console.log('人生的巅峰');
        })();
        // 立即执行函数是自动调用
    </script>
</body>

</html>
22、函数内的this指向

image-20220315174034733

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <button>点击</button>
    <script>
        // 函数的不同调用方式决定了this 的指向不同
        // 1. 普通函数 this 指向window
        function fn() {
            console.log('普通函数的this' + this);
        }
        window.fn();
        // 2. 对象的方法 this指向的是对象 o
        var o = {
            sayHi: function() {
                console.log('对象方法的this:' + this);
            }
        }
        o.sayHi();
        // 3. 构造函数 this 指向 ldh 这个实例对象 原型对象里面的this 指向的也是 ldh这个实例对象
        function Star() {};
        Star.prototype.sing = function() {

        }
        var ldh = new Star();
        // 4. 绑定事件函数 this 指向的是函数的调用者 btn这个按钮对象
        var btn = document.querySelector('button');
        btn.onclick = function() {
            console.log('绑定时间函数的this:' + this);
        };
        // 5. 定时器函数 this 指向的也是window
        window.setTimeout(function() {
            console.log('定时器的this:' + this);

        }, 1000);
        // 6. 立即执行函数 this还是指向window
        (function() {
            console.log('立即执行函数的this' + this);
        })();
    </script>
</body>

</html>
23、apply方法(函数)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 改变函数内this指向  js提供了三种方法  call()  apply()  bind()
        // 2. apply()  应用 运用的意思
        var o = {
            name: 'andy'
        };
        function fn(arr) {
            console.log(this);
            console.log(arr); // 'pink'
        };
        fn.apply(o, ['pink']);
        // 1. 也是调用函数 第二个可以改变函数内部的this指向
        // 2. 但是他的参数必须是数组(伪数组)
        // 3. apply 的主要应用 比如说我们可以利用 apply 借助于数学内置对象求数组最大值 
        // Math.max();
        var arr = [1, 66, 3, 99, 4];
        var arr1 = ['red', 'pink'];
        // var max = Math.max.apply(null, arr);
        var max = Math.max.apply(Math, arr);
        var min = Math.min.apply(Math, arr);
        console.log(max, min);
    </script>
</body>

</html>
24、bind方法(函数)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 改变函数内this指向  js提供了三种方法  call()  apply()  bind()
        // 3. bind()  绑定 捆绑的意思
        var o = {
            name: 'andy'
        };
        function fn(a, b) {
            console.log(this);
            console.log(a + b);
        };
        var f = fn.bind(o, 1, 2);
        f();
        // 1. 不会调用原来的函数   可以改变原来函数内部的this 指向
        // 2. 返回的是原函数改变this之后产生的新函数
        // 3. 如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向此时用bind
    </script>
</body>
</html>
25、bind方法的应用
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <button>点击</button>
    <button>点击</button>
    <button>点击</button>
    <script>
        // 1. 不会调用原来的函数   可以改变原来函数内部的this 指向
        // 2. 返回的是原函数改变this之后产生的新函数
        // 3. 如果有的函数我们不需要立即调用,但是又想改变这个函数内部的this指向此时用bind
        // 4. 我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒钟之后开启这个按钮
        // var btn1 = document.querySelector('button');
        // btn1.onclick = function() {
        //     this.disabled = true; // 这个this 指向的是 btn 这个按钮
        //     // var that = this;
        //     setTimeout(function() {
        //         // that.disabled = false; // 定时器函数里面的this 指向的是window
        //         this.disabled = false; // 此时定时器函数里面的this 指向的是btn
        //     }.bind(this), 3000); // 这个this 指向的是btn 这个对象
        // }
        var btns = document.querySelectorAll('button');
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function() {
                this.disabled = true;
                setTimeout(function() {
                    this.disabled = false;
                }.bind(this), 2000);
            }
        }
    </script>
</body>
</html>
26、call、apply、bind的异同

image-20220315182916369

27、闭包的应用-点击li输出索引号
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        <li>我是第一个</li>
        <li>我是第二个</li>
        <li>我是第三个</li>
        <li>我是第四个</li>
        <li>我是第五个</li>
    </ul>

<script>
    let lis = document.querySelector('ul').querySelectorAll('li');

    // 传统方法
    // for (let i = 0; i < lis.length; i++){
    //     lis[i].index = i;
    //     lis[i].addEventListener('click',function () {
    //         console.log(this.index);
    //     })
    // }

    // 利用闭包(立即函数)
    for (let i = 0;i < lis.length;i++){
        (function (i) {
            lis[i].addEventListener('click',function () {
                console.log(i);
            })
        })(i)
    }
</script>
</body>
</html>
28、闭包的应用-定时器中的闭包
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <ul class="nav">
        <li>榴莲</li>
        <li>臭豆腐</li>
        <li>鲱鱼罐头</li>
        <li>大猪蹄子</li>
    </ul>
    <script>
        // 闭包应用-3秒钟之后,打印所有li元素的内容
        var lis = document.querySelector('.nav').querySelectorAll('li');
        for (var i = 0; i < lis.length; i++) {
            (function(i) {
                setTimeout(function() {
                    console.log(lis[i].innerHTML);
                }, 3000)
            })(i);
        }
    </script>
</body>

</html>
29、浅拷贝
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝引用.
        // 深拷贝拷贝多层, 每一级别的数据都会拷贝.
        var obj = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            }
        };
        var o = {};
        // for (var k in obj) {
        //     // k 是属性名   obj[k] 属性值
        //     o[k] = obj[k];
        // }
        // console.log(o);
        // o.msg.age = 20;
        // console.log(obj);

        console.log('--------------');
        Object.assign(o, obj);
        console.log(o);
        o.msg.age = 20;
        console.log(obj);
    </script>
</body>

</html>
30、深拷贝
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <script>
        // 深拷贝拷贝多层, 每一级别的数据都会拷贝.
        var obj = {
            id: 1,
            name: 'andy',
            msg: {
                age: 18
            },
            color: ['pink', 'red']
        };
        var o = {};
        // 封装函数 
        function deepCopy(newobj, oldobj) {
            for (var k in oldobj) {
                // 判断我们的属性值属于那种数据类型
                // 1. 获取属性值  oldobj[k]
                var item = oldobj[k];
                // 2. 判断这个值是否是数组
                if (item instanceof Array) {
                    newobj[k] = [];
                    deepCopy(newobj[k], item)
                } else if (item instanceof Object) {
                    // 3. 判断这个值是否是对象
                    newobj[k] = {};
                    deepCopy(newobj[k], item)
                } else {
                    // 4. 属于简单数据类型
                    newobj[k] = item;
                }

            }
        }
        deepCopy(o, obj);
        console.log(o);

        var arr = [];
        console.log(arr instanceof Object);
        o.msg.age = 20;
        console.log(obj);
    </script>
</body>

</html>
31、正则表达式

元字符

代表特殊含义的元字符

\d : 0-9之间的任意一个数字  \d只占一个位置
\w : 数字,字母 ,下划线 0-9 a-z A-Z _
\s : 空格或者空白等
\D : 除了\d
\W : 除了\w
\S : 除了\s
 . : 除了\n之外的任意一个字符
 \ : 转义字符
 | : 或者
() : 分组
\n : 匹配换行符
\b : 匹配边界 字符串的开头和结尾 空格的两边都是边界 => 不占用字符串位数
 ^ : 限定开始位置 => 本身不占位置
 $ : 限定结束位置 => 本身不占位置
[a-z] : 任意字母 []中的表示任意一个都可以
[^a-z] : 非字母 []中^代表除了
[abc] : abc三个字母中的任何一个 [^abc]除了这三个字母中的任何一个字符

代表次数的量词元字符

* : 0到多个
+ : 1到多个
? : 0次或1次 可有可无
{n} : 正好n次;
{n,} : n到多次
{n,m} : n次到m次
32、验证用户名是否输入正确
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        span {
            color: #aaa;
            font-size: 14px;
        }
        .right {
            color: green;
        }
        .wrong {
            color: red;
        }
    </style>
</head>
<body>
    <input type="text" class="uname"> <span>请输入用户名</span>
    <script>
        let ipt = document.querySelector('.uname');
        let span = document.querySelector('span');
        let reg = /^[a-zA-Z0-9-_]{6,16}$/;
        ipt.addEventListener('blur',function(){
            if(reg.test(this.value)){
                span.className = 'right';
                span.innerHTML = '用户名输入格式正确!';
            }else{
                span.className = 'wrong';
                span.innerHTML = '用户名输入格式错误!!';
            }
        })
    </script>
</body>
</html>
33、正则表达式中的替换
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        textarea {
            width: 300px;
            height: 100px;
            border: 1px solid #ccc;
        }
    </style>
</head>

<body>
    <textarea name="" id="message"></textarea> <button>提交</button>
    <div></div>
    <script>
        // 替换 replace
        // var str = 'andy和red';
        // // var newStr = str.replace('andy', 'baby');
        // var newStr = str.replace(/andy/, 'baby');
        // console.log(newStr);
        // /表达式/[switch]  switch也称为修饰符,按照什么模式来匹配,有三种值:
        // g:全局匹配
        // i:忽略大小写
        var text = document.querySelector('textarea');
        var btn = document.querySelector('button');
        var div = document.querySelector('div');
        btn.onclick = function() {
            div.innerHTML = text.value.replace(/激情|gay/g, '**');
        }
    </script>
</body>
</html>

image-20220316002017082

posted @ 2022-03-31 20:05  小鹅爸爸  阅读(6)  评论(0编辑  收藏  举报