zoukankan      html  css  js  c++  java
  • JS高级

    一、函数高级

    1.函数回调

    函数回调的本质:在一个函数中,满足特定条件下,调用另一个函数

    // 回调的函数
    function callback(data) {}
    // 逻辑函数
    function func(callback) {
        // 函数回调
        if (callback) callback(data);
    }
    function a_fn(data) {
            console.log('a_fn');
            // 如果要使用数据,那么定义形参接收参数
            console.log(data);
        }
    
        function b_fn(a_fn) {
            var data = "b_fn 的 数据";
            console.log('b_fn');
            // 条件: a_fn有值(有函数实现体)
            if (a_fn) {
                // 调用参数函数
                a_fn(data);
            }
        }
        b_fn(a_fn);
    test

    总结:

       1.一个函数(函数名)作为另外一个函数的参数
       2.满足一定的条件,调用参数函数
       3.形成了函数回调,回调的函数可以获取调用函数的局部变量(将数据携带出去)

    2.闭包

    闭包本质:函数的嵌套定义,内层函数称之为闭包

    闭包目的:不允许提升变量作用域时,该函数的局部变量需要被其他函数使用
    闭包的解决案例:①影响局部变量的生命周期,持久化局部变量;②解决变量污染

    function outer() {
        var data = {}
        //闭包
        function inner() {
            return data;
        }
        return inner;
    }

    注:外部使用局部变量的方法: 返回值 | 函数回调 | 闭包 | 提升作用域

    2.1局部变量持久化

     function outer() {
            //eg:请求得到的数据,如果不持久化,方法执行完毕后,数据就会被销毁
            var data=[1,2,3,4,5];
            console.log(data);
            //通过闭包解决该类问题,所以闭包所有代码均可以随意自定义
            function inner(){
                return data;
            }
            //数据被inner操作返回,inner属于outer,所以需要将inner返回出去(跟外界建立联系)
            return inner;
        }
        //将局部变量生命周期提升于inner函数相同,inner存在,局部变量data就一直存在
        var inner = outer();

    2.2闭包解决变量污染

    现有一个列表,点击某个时,弹出下标

    <script type="text/javascript">
        // 需求:点击li,打印li在ul中的索引 => 0, 1, 2, 3, 4
        // 1.lis 
        var lis = document.querySelectorAll('ul li');
        // 2.循环绑定
        for (var i = 0; i < lis.length; i++) {
            // 解决的原理:一共产生了5个外层函数,存储的形参i的值分别是0, 1, 2, 3, 4
            // 内层函数也产生了5个,且和外层函数一一对应,打印的i就是外层函数的形参i
    
            // 外层函数
            (function (i) {
                // 内层函数:闭包
                lis[i].onclick = function () {
                    alert(i)
                }
            })(i)    
        }
        console.log(i);  // 点击事件触发一定晚于该逻辑语句
        // 所以再去触发点击,弹出i的值,永远是5
    
        // 该类问题就称之为变量污染
    </script>

    ES6的块级作用域的语法也可以解决循环绑定变量污染的问题

    let lis = document.querySelectorAll('li');
        for (let i = 0; i < lis.length; i++) {
            lis[i].onclick = function () {
                alert(i)
            }
        }

    二、JS的面向对象

    1.面向对象初始

    var obj = {}; | var obj = new Object();
    // 属性
    obj.prop = "";|obj['name']="";
    // 方法
    obj.func = function () {}
    // 删除属性与方法
    delete obj.prop
    delete obj.func

    2.类字典结构使用

    js中没有字典(键值对存储数据的方式),但可以通过对象实现字典方式存储数据,并使用数据

    var dict = {name: "zero", age: 18}
    var dict = {"my-name": "zero", fn: function () {}, fun () {}}
    //使用
    dict.name | dict["my-name"] | dict.fn()
    总结:
    1.key全为字符串形式,但存在两种书写方式
    2.key在js语法标识符支持情况下,可以省略引号,但key为js非法标识符的情况下,必须添加引号。
    3.value可以为任意类型
    4.访问值可以通过字典名(对象名).key语法与[“key”]语法来访问value
    5.可以随意添加key与value完成增删改查
    // 增
    dict.key4 = true;
    console.log(dict);
    
    // 删
    delete dict.key4;
    console.log(dict);
    
    // 改
    dict["my-key3"] = [5, 4, 3, 2, 1];
    console.log(dict);
    
    // 查
    console.log(dict.key1);
    console.log(dict["key1"]);

    3.构造函数

    构造函数其实就是普通函数
    特定的语法与规定:
    1.一般采用首字母大写(大驼峰)
    2.内部可以构建属性与方法,通过this关键词

    // 普通函数
    function fn() {
        var num = 10;
        console.log('普通函数');
    }
    fn();
    
    //构造函数
    function People(name) {
        this.name = name;
        this.eat = function (agr) {
            console.log(this.name + "" + agr);
        }
    }

    构造函数可以创建多个对象,使用{}构建出的对象是唯一的

    var p1 = new People("zero");  // new关键词, 创建对象并实例化
    var p2 = new People("seven");
    
    var obj = {} //对象唯一

    构造函数的属性变量与{}的语法规则不一样,构造函数内部通过this,二普通对象直接通过对象名.的方式

    function People(name) {
        this.name = name;
        this.eat = function (agr) {
            console.log(this.name + "吃" + agr);
        }
    }
    
    //普通对象
    var obj = {
        index: "obj对象",
        fn: function () {
            console.log("obj方法");
        }
    };
    // 使用属性与方法
    console.log(obj.index);
    obj.fn();

    4.继承

    1.完成继承,必须拥有两个构造函数
    2.一个函数要使用另外一个函数的属性与方法,需要对其进行继承(属性与方法的复用)

    4.1 ES5的继承

    属性的继承用call方法,在继承函数中由被继承函数调用,传入继承函数的this与被继承函数创建属性对属性进行赋值的所有需要的数据
    方法的继承prototype原型

        // 类似于父级
        function Sup(name) {
            // 属性存放某个值
            this.name = name;
            // 方法完成某项功能
            this.func = function () {
                console.log("func");
            }
        }
        var sup = new Sup("supClass");
        console.log(sup.name);
        sup.func();
    
        // 类似于子级
        function Sub(name) {
            // 属性的继承
            Sup.call(this, name);//Sup有name属性,那么可以通过call将Sub的name传给Sup
        }
        // 方法的继承
        Sub.prototype = new Sup; //将new Sup赋值给Sub.prototype
    
        var sub = new Sub("subClass");
        console.log(sub.name);
        sub.func();
    
        // 原型
        console.log(sup.__proto__);

    4.2 ES6继承

    // 多对象 => 创建类
        class Person {
            // 构造器:创建对象完成初始化操作
            constructor (name, age) {
                this.name = name;
                this.age = age;
            }
            // 实例方法:只能由对象调用
            eat () {
                console.log(this.name + '吃吃吃');
            }
            // 类方法:只能由类调用
            static create () {
                console.log('诞生');
            }
        }
        let p1 = new Person('zero', 8);
        let p2 = new Person('seven', 58);
    
        console.log(p1.age);
        p2.eat();
        // Person.eat();
        Person.create();
        // p2.create();
    
    
        // 继承
        class Student extends Person {
            constructor (name, age, sex) {
                // super指向父级
                super(name, age);
                this.sex = sex;
            }
        }
    
        let s1 = new Student("张三", 18, "男");
        // 属性的继承
        console.log(s1.name, s1.age, s1.sex);
        console.log();
        // 方法的继承
        s1.eat();
        // 继承为全继承
        Student.create();

    补:ES6用箭头语法表示函数

    // 函数
    let f = () => {
    }

    5.属性解决循环绑定变量污染

    还是用之前的变量污染的例子,js代码看下面

        var lis = document.querySelectorAll('li');
    
        for (var i = 0; i < lis.length; i++) {
            // lis[i]依次代表五个li页面元素对象
            // 给每一个li设置一个(临时)属性
            lis[i].index = i;  // 第一个li的index属性存储的就是索引0,以此类推,最后一个存储的是索引4
    
            lis[i].onclick = function () {
                // var temp = lis[i].index; // lis[i]中的i一样存在变量污染
                var temp = this.index;  // 当前被点击的li
                alert(temp)  // temp => this.index(lis[i].index) => i(索引)
            }
        }

    三、定时器

    应用场景:
    1.完成js自启(不需要手动触发)动画
    2.css完成不了的动画

    • setInterval  一次性定时器

    • setTimeout  持续性定时器

    // 一次性定时器
        /* 异步执行
            setTimeout(函数, 毫秒数, 函数所需参数(可以省略));
        */
        console.log("开始");
        setTimeout(function (data) {
            console.log(data);
        }, 1000, "数据");
        console.log("结束");
    
    
        // 持续性定时器
        /*异步执行
            setInterval(函数, 毫秒数, 函数所需参数(可以省略));
        */
        console.log("又开始");
        var timer = setInterval(function() {
            console.log("呵呵");
        }, 1000)
        console.log(timer);
        console.log("又结束");

    清除定时器

    1.持续性与一次性定时器通常都应该有清除定时器操作
    2.清除定时器操作可以混用 clearTimeout() | clearInterval()
    3.定时器的返回值就是定时器编号,就是普普通通的数字类型

        document.onclick = function () {
            console.log("定时器清除了");
            clearInterval(timer);
            // clearTimeout(timer);
        }
    
        // 清除所有定时器
        // 如果上方创建过n个定时器,那么timeout值为n+1
        var timeout = setTimeout(function(){}, 1);
        for (var i = 0; i < timeout; i++) {
            // 循环将编号[0, n]所有定时器都清除一次
            clearTimeout(i)
        }
        // 1.允许重复清除
        // 2.允许清除不存在的定时器编号
  • 相关阅读:
    2017年 JavaScript 框架回顾 -- 后端框架
    2017年 JavaScript 框架回顾 -- React生态系统
    2017年 JavaScript 框架回顾 -- 前端框架
    TypeScript VS JavaScript 深度对比
    优化Webpack构建性能的几点建议
    前端开发者常用的9个JavaScript图表库
    JavaScript 性能优化技巧分享
    基于低代码平台(Low Code Platform)开发中小企业信息化项目
    SoapUI实践:自动化测试、压力测试、持续集成
    JavaScript中的内存泄漏以及如何处理
  • 原文地址:https://www.cnblogs.com/mangM/p/9807237.html
Copyright © 2011-2022 走看看