Js高级函数 TWO Day

146 阅读1分钟

Js高级:

一.原型链继承:

利用代码的能力实现 面向对象的特性 封装继承

    <script>
        function Person(name, age, height) {
            this.username = name;
            this.age = age;
            this.height = height;
        }

        function Student(name, age, height, color) {
            // 这一行代码解决了继承的问题!!
            // call 借用别人的方法
            // 谁有方法
            // 谁想要借用person方法  this = 实例 = 下面代码的s1
            Person.call(this, name, age, height);//   儿子想要复用父亲的某些代码 父亲方法.call(this,形参1,形参2。)
            // this.name = name;
            // this.age = age;
            // this.height = height;
            this.color = color;
        }

        // const p1 = new Person('奥特之父', 5000, 200);
        const s1 = new Student('迪迦', 2000, 100, 'yellow');

        // console.log(p1);
        console.log(s1);
    </script>
  • 子类strudent 继承了父类 Person的属性

继承案例:

    <script>
        /* 
        封装 代码 实现以下的功能
        1 父亲   Element
          1 属性 dom   this.dom
          2 行为 实例.append(父元素标签的选择器)
        2 儿子1  ElementDouble  div
          1 继承父亲 Element  
            属性 dom
            行为 append
        3 儿子2  ElementSingle  img 
            属性 dom
            行为 append
  
        4 当执行以下代码时 出现对应效果
          1 const divModel = new ElementDouble("div","div内的文字")
          2 divModel.append("body") ;  body标签可以出现 一个 div 
  
          1 const imgModel = new ElementSingle("img","图片地址")
          2 imgModel.append("body");  body标签可以出现 一个图片 
         */

        //  父亲
        function Element(tagName) {
            const dom = document.createElement(tagName);
            this.dom = dom;
        }
        //  父亲
        Element.prototype.append = function (parentSelector) {
            document.querySelector(parentSelector).appendChild(this.dom);
        };

        // 儿子1
        function ElementDouble(tagName, content) {
            Element.call(this, tagName); // 继承 - 父亲的属性
            this.dom.innerText = content;
        }
        // 去继承父亲的行为
        ElementDouble.prototype.append = Element.prototype.append;

        // 儿子2
        function ElementSingle(tagName, src) {
            Element.call(this, tagName);
            this.dom.src = src;
        }
        ElementSingle.prototype.append = Element.prototype.append;

        const divModel = new ElementDouble('div', '这个是div');
        divModel.append('body');

        const imgModel = new ElementSingle('img', './images/b_01.jpg');
        imgModel.append('div');

      // 如果代码重复实现了 很有可能就是我们要封装的时候
      // 以前的封装 仅仅是封装一个小小的函数而已
      // 现在的封装, 面相对象的思维来封装
      // 封装 属性  父亲
      // 封装 方法  父亲

      // 两个儿子的代码 有重复部分
      // 创建标签重复 this.dom=dom  append方法也重复

      // 儿子1 有要什么功能
      // 先复用父亲的属性和方法

    </script>

方法借用模式:call

call方法可以调用一个函数,并且可以指定这个函数的 this 指向

    <script>
        const car = {
            name: '装甲车',
            add: function (username, age) {
                // 本质 可以给car添加新的属性
                this.username = username;
                this.age = age;
            },
        };

        // car.add('发动机', 100);
        // console.log(car);

        const obj = {};
        // car.add.call(obj); // obj 想要借用 添加属性的方法
        car.add.call(obj, '发动机', 200); // call 传入参数  add.call(谁要借用,被借用的方法的形参1,被借用的方法形参2)
        console.log(obj); // obj 有没有 username属性(不用管属性值)、有没有age属性(不用属性值)


      // 可以实现 了 一个空对象 obj 通过call的使用 来实现了 借别人的方法add 来给obj添加新的属性 
    </script>

二.es6(重点):

    <script>
        // 目前浏览器 支持的js的代码版本
        // 主要都支持 es5 (for if while 函数 forEach ) 版本
        // 新的语法 es6 (提供了更加简单强大的代码更能力) 提高我们的开发效率
        // 常用 重要的部分
        // 如果大家有空 了解全部 阮一峰

        // 体验一下
        // 交换
        let a = 1;
        let b = 2;
        // 交换两个值
        [a, b] = [b, a];
        console.log(a, b);

      // let c = a;
      // a = b;
      // b = c;
      // console.log(a, b);
    </script>

函数参数默认值:

定义函数的同时,可以给形参一个默认值

    <script>
        // 定义函数的同时,可以给形参一个默认值
        function show(msg = '大家一起快活呀') {
            console.log(msg);
        }
        show() // 打印 大家一起快活呀
        show('搞笑不') // 打印 搞笑不
    </script>

对象简写:

在定义对象的时候,如果属性名和变量名一直,那么可以实现简写

    <script>
        // 简写 如果变量的名字和属性的名字 一致的话,对象可以简写

        // const obj = {
        //   // 属性名 和 属性值
        //   username: 123,
        // };

        const username = 123;
        const color = 'red';

        const say = function () { };

        function show() { }

        // 很常用
        const obj = {
            username, // username:username
            color, // color : color
            say,
            show,
            height: 100,
        };
        obj.height = 200;
        // console.log(obj);

        // 对象中方法的简写
        const person = {
            show: function () {
                console.log("show");
            },// 常规写法
            // es6 关于 方法简写
            say() {
                console.log("say");
            } // es6 关于 方法简写
        }
        person.show();
        person.say();
        /*
        小结:
        1 变量名如果和你的对象的属性名一致 可以简写
           let username='悟空'
           const obj = { username }
  
        2 对象的方法 简写
          const obj ={
            say(){  // 简写的方法
  
            }
          }
         */
    </script>

三.解构:

提供更加方便获取数组中元素或者对象中属性的写法

获取数组中的元素:

    <script>
        const [a, b, c, d] = [0, 1, 2, 3]
        console.log(a, b, c, d);//0,1,2,3
    </script>

元素交互顺序:

    <script>
        let a = 1111;
        let b = 2222;
        [b, a] = [a, b];
        console.log(a, b);// 2222 1111
    </script>

获取对象中的属性(重点):

    <script>
        const obj = {
            name: "悟空",
            skill: '72变',
            say() {

            }
        }
        const { name, height, say } = obj;
        console.log(name, height, say); //悟空,72变,function(){}
    </script>

四.拓展运算符 || 剩余运算符:

通过 ...符号来获取剩下的参数

函数内获取:

    <script>
        function show(a, ...all) {
            console.log(a);
            console.log(all);
        }
        show(1) //a=1 all=[]
        show(1, 2, 3) //a=1 all=[2,3]
    </script>

数组内获取:

    <script>
        const [a, ...rest] = [1, 2, 3, 4, 5, 6]
        console.log(a); //a=1
        console.log(rest); //rest=[2,3,4,5,6]
    </script>

对象内获取:

    <script>
        const obj = {
            name: '悟空',
            skill: '72变',
            say() {

            }
        }
        const { name, ...others } = obj
        console.log(name) //悟空
        console.log(others) //{skill:72变,say:f}
    </script>

计算最大值:

    <script>
        // 计算最大值的写法 
        function getMax(...args) {
            // args= 数组  接收 所有传递给 getMax方法的 参数
            // console.log(args);
            // 计算最大值 的
            let max = args[0];
            args.forEach((value) => {
                if (value > max) {
                    max = value;
                }
            });
            console.log(max);
        }
        getMax(1); //1
        getMax(1, 2);  //2
        getMax(1, 2, 3);  //3
        getMax(11, 33, 2, 3);  //33
    </script>

拓展:

    <script>
        // 展开 ... 用法
        const obj = {
          username: '悟空',
          height: 200,
        };

        // // 新创建一个对象 这个对象 具有 所有 obj的属性
        // // 同时 还有多一个属性,color

        // // const newObj = obj;// 对象是引用类型   写 =  将 obj的地址 给了一份 newObj  两个变量指向的地址同样的 同一个对象
        // // newObj.color = 'yellow';
        // // console.log("新的对象",newObj);
        // // console.log("旧的对象",obj);

        // // 建议这做  互补影响
        // const newObj = { ...obj, color: 'yellow' }; // 给newObj 开辟新的内存空间
        const newObj={ username:"悟空",height:20}; // 给newObj 开辟新的内存空间
        newObj.username = '八戒';
        newObj.weight = 100;
        // console.log(obj);
        console.log(newObj);

        // 展开运算符 对数组操作
        const arr = ['a', 'b', 'c'];
      // 在数组的后面 新增一个 元素 'd'
      // const newArr=[...arr,'d'];

      // 在数组宅前面 新增一个属性 w
      // console.log(newArr);
      // const newArr = ['w', ...arr];
      // console.log(newArr);
      // arr.push
      // arr.unshift
      // 中间 无法使用 ...
      // splice 来实现 
    </script>

五.数组去重:

提示:方案中this.value等于input.value

方案一 some方法:

    <input type="text">
    <ul>

    </ul>
    <script>
        let arr = ['1', '2']
        const input = document.querySelector('input')
        const ul = document.querySelector('ul')
        gethtml()

        input.addEventListener("keydown", function (event) {
            if (event.key === 'Enter') {
                // some 如果数组中有一项 是返回了true 整个some方法就返回了true
                // 调用some方法的时候,在它的回调函数中 拿数组中的元素 和 当前要添加的元素 做比较 如果相等 就返回true 表示找到了重复
                const isHas = arr.some((value) => value === this.value) // 在我的数组中找到了和你待添加的元素 一样的值 返回true
                if (isHas) {
                    // 有重复了 不要再添加
                    alert('输入重复了')
                }
                else {
                    // 没有重复 你可以添加
                    // 把它添加到数组中
                    arr.push(this.value)
                    // 数组发生了改变 重新调用render方法 来实现页面的渲染
                    gethtml()
                }
            }
        })
        function gethtml() {
            const html = arr.map((value) => `<li>${value}</li>`).join('')
            ul.innerHTML = html
        }
    </script>

方案二 for循环 定一个变量,表示数组有没有重复的数据:

    <input type="text">
    <ul>

    </ul>
    <script>
        let arr = ['1', '2']
        const input = document.querySelector('input')
        const ul = document.querySelector('ul')
        gethtml()

        input.addEventListener("keydown", function (event) {
            // 定一个变量,表示数组有没有重复的数据
            // 假设它 没有重复
            let isHas = false
            for (let index = 0; index < arr.length; index++) {
                // 判断数组中的每一个元素 和 当前要输入的值做比较
                // 如果找到了,设置 isHas=true 同时 打断循环
                if (arr[index] === this.value) {
                    // 找到重复了
                    isHas = true
                    break
                }
            }
            // 判断数据有没有重复
            if (isHas) {
                //有重复
                console.log('重复');
            } else {
                // 没有重复 添加
                arr.push(this.value)
                gethtml()
            }
        })
        function gethtml() {
            const html = arr.map(value => `<li>${value}</li>`).join('')
            ul.innerHTML = html
        }
    </script>

方案三 filter方法 :

    <input type="text">
    <ul>

    </ul>
    <script>
        let arr = ['1', '2']
        const input = document.querySelector('input')
        const ul = document.querySelector('ul')
        gethtml()

        input.addEventListener("keydown", function (event) {
            // filter 来解决
            // filter 过滤
            // 先过滤出  和当前的输入框的值 不相等的 数据
            // 然后再添加
            // 当前输入框的值 "d"
            // 我数组 ['a','c','d']
            // 数组过滤 不包含 "d"  => ['a','c']
            // ['a','c'] 再次添加 'd' 进去 就可以了

            // 过滤出不包含 当前输入框的值的数组
            let newArr = arr.filter(value => value !== this.value)
            // 让我们的旧的数组 等于你过滤后的数组
            arr = newArr
            arr.push(this.value)
            gethtml()
        })
        function gethtml() {
            const html = arr.map(value => `<li>${value}</li>`).join('')
            ul.innerHTML = html
        }
    </script>

方案四 声明一个变量 量等于数组没有的下标:let i = -1

    <input type="text">
    <ul>

    </ul>
    <script>
        let arr = ['1', '2']
        const input = document.querySelector('input')
        const ul = document.querySelector('ul')
        gethtml()

        input.addEventListener("keydown", function (event) {
            // this.value =  "b"
            // arr = ["a","b","c"]
            // 先找到 “b” 在我数组的索引 位置
            // 执行 数组 删除元素  arr = [a,c]
            // 然后 再去执行 添加元素的操作
            let i = -1 // -1 表示没有找到
            for (let index = 0; index < arr.length; index++) {
                if (arr[index] === this.value) {
                    i = index
                    break
                }
            }
            // 判断 i 等于-1 表示没有相同,直接添加
            //  i 不等于-1 表示有相同,先执行删除 再添加
            if (i === -1) {

            } else {
                // 找到相同 删除它
                arr.splice(i, 1)
            }
            arr.push(this.value)
            gethtml()
        })
        function gethtml() {
            const html = arr.map(value => `<li>${value}</li>`).join('')
            ul.innerHTML = html
        }
    </script>

其他方法 了解:

   <input type="text" />
    <ul></ul>
    <script>
        const input = document.querySelector('input');
        const ul = document.querySelector('ul');
        let arr = ['a', 'b'];
        render();

        input.addEventListener('keydown', function (event) {
            if (event.key === 'Enter') {
                // 数组去重 一堆方法
                // for forEach some  
                // 没有细讲 indexOf find findIndex  includes set every 

                // 没有足够的技术积累和代码量  优雅不起来!! 


                // indexOf find findIndex includes set

                // const index=arr.indexOf(this.value);
                const index=arr.findIndex(value=>value===this.value)
                const item=arr.find(value=>value===this.value);
                const isHas=arr.includes(this.value)
                if(!isHas){
                  // 没有找到
                  arr.push(this.value);
                  render();
                }

                const set = new Set(arr);
                set.add(this.value);
                arr = [...set];
                render();
            }
        });

        function render() {
            const html = arr.map((value) => `<li>${value}</li>`).join('');
            ul.innerHTML = html;
        }