JavaScript高级[通俗易懂]

JavaScript高级[通俗易懂]一、高级函数1、函数回调函数回调的本质:在一个函数中,当满足一定的条件,回调函数会当作调用函数的参数传入下面这个例子,faa作为回调函数,fbb作为调用函数。在JavaScript中内置的调用函

大家好,又见面了,我是你们的朋友全栈君。

 

一、高级函数

  1、函数回调

  函数回调的本质:在一个函数中,当满足一定的条件,回调函数会当作调用函数的参数传入

  下面这个例子,faa作为回调函数,fbb作为调用函数。在JavaScript中内置的调用函数已经给我们写好了,我们只需写好fbb(回调函数)就好,就算你不写也不出错。

<script>
    function faa(data) {
        console.log('执行faa函数');//判断函数是否执行
        var start_time = new Date().getTime();
        var stop_time = new Date().getTime();
        //设置执行数据处理数据的时间为3s
        while (stop_time-start_time <3000) {
            stop_time = new Date().getTime();
        }
        var time = stop_time - start_time;
        console.log(data);
        console.log('一共耗时',time)

    }

    function fbb(func) {
        var data = 'fbb的数据';
        if (func) {
            func(data)
        } else {
            console.log('没有设置回调函数');
        }
    }

    fbb(faa)

</script>

  既然已经写到了函数的回调,那么再写一个面向对象的回调

<script>

    var web = {
        recved: null,
        send: function () {
            console.log('开始请求数据');

            // 这里模拟请求数据花费的时间
            start_time = new Date().getTime();
            stop_time = new Date().getTime();
            while (stop_time - start_time < 3000) {
                stop_time = new Date().getTime();
            }

            var data = '请求得到后的数据';

            if (web.recved && data) {
                web.recved(data);
            } else {
                console.log('回调函数没有定义');
            }
        }
    };
    web.recved = function (data) {
        console.log(data);
    };
    web.send();

</script>

  上面这个例子,首先写一个对象,写好它的属性,方法。假如send方法就是内置的,早已经写好的方法,我们执行web.send(),虽然产生数据,但是最为程序员的我们并没有写处理这个数据的方法,所以我们为recved编写了一个处理数据方法,再去执行web.send(),这样产生的数据就能处理了。

  再说,比如事件的绑定,我们为className为div的div标签绑定鼠标点击事件

  在我们没有给div的点击事件写相应的函数时,程序并没报错,一旦为其添上方法,我们在触发该事件的话,那么我们写的方法会作为回调函数去执行。

  2、函数的闭包

  闭包目的:不允许提升变量作用域时,该函数的局部变量需要被其他函数使用

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

  闭包的解决案例:①影响局部变量的生命周期,持久化局部变量 ②解决变量污染

//这就是闭包,一个函数想使用另一个函数局部变量
function faa() {
    var date = [1,2,3,4];
    function fbb() {
        console.log(date)
    }
    fbb();
}
faa();
//通过闭包,可以提升函数内部的局部变量
function faa() {
    var data = '获取到的数据';
    function fbb() {
        return data
    }
    fbb();
}

var a = faa();
console

 

二、循环绑定

<body>
    <ul>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
        <li></li>
    </ul>
</body>
<script>
    var lis = document.querySelectorAll('li');
    for (var i = 0 ; i < lis.length;i++) {
        lis[i].onClick = function () {
            alert(i);
        }
    }
</script>
/*你在页面点击li标签,会弹出5,上面全部都是弹出5 为什么会这样,就是循环绑定出现的变量污染,var是ES5中定义变量的方法,是没有块级作用域的,当for循环结束时,i就等于5*/

//我们可以通过闭包函数去解决这个问题
<script> var lis = document.querySelectorAll('li'); for (var i = 0 ; i < lis.length;i++) {
    (function(i){ lis[i].onclick = function () { alert(i); };
    })(i) } </script>
/*我们将为为li标签绑定点击事件的方法,写出一个闭包函数,外函数就是一个匿名函数的自调用。循环一次,先是匿名函数自调用一次,产生一个局部空间存放函数体代码,这样循坏5次,就产生了五个不同局部空间的
函数,当触发点击事件,就去执行相对应的回调函数,所引弹出的是它对应的索引值*/

//我们可以通过对象的属性去解决变量污染问题
<script> var lis = document.querySelectorAll('li'); for (var i = 0 ; i < lis.length;i++) {
    lis[i].index = i;
    lis[i].onclick = function() {
      alert(this.index)
    };
  }
</script>
//前面说了var定义的变量是无块级作用域的,我们可以通过ES6的语法,let去解决变量污染问题
<script>
 let lis = document.querySelectorAll('li'); 
  for (let i = 0 ; i < lis.length;i++) {
    lis[i].onclick = function () {
      alert(i);
    }
  }  </script>

 

三、面向对象Js

<script>
    //定义两个空对象
    var obj1 = {};
    var obj2 = new Object();
var zhuyu = {
    name:'zhuyu',  
    age : '21',
  } //创建一个zhuyu对象
  //查看属性的方法:zhuyu.name zhuyu['age']
  //添加/修改属性的方法:zhuyu.age = '22' 添加:zhuyu.sex = 'male'
  //删除属性的方法:delete zhuyu.sex
  //方法的添加修改删除和属性一样。方法的调用直接对象名.方法名()

  //构造函数,相当于python中面向对象的类
  //ES5中
  function People(name,age,sex) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.eat = function () {
            console.log('eat.......');
          }
    }
  //JavaScript的面向对象也有继承,多态,封装三大特性。
  简单写写继承:子级里继承父级属性,父级.call(this,name,age);
         子级里继承父级方法,子级.prototype = new 父级;

  //ES6中
  clsaa People() {
    constructor(name,age) {
      this.name = name;
      this.age = age;
    }
    //实例方法
    eat() {console.log('eat........')}
    //类方法
    static do() {'do.....'}
  }
  
</script>

 

四、定时器

//setInterval(持续性定时器)
//setInterval(函数, 毫秒数, 函数所需参数(可以省略));
var timer = setInterval(function() {console.log("呵呵");}, 1000)


//setTimeout(一次性定时器)
//setTimeout(函数, 毫秒数, 函数所需参数(可以省略));
setTimeout(function (data) {console.log(data);}, 1000, "数据");

//清除定时器
clearTimerout()|clearInterval()

 

  

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/155349.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • vue中通过路由跳转的三种方式

    vue中通过路由跳转的三种方式router-view实现路由内容的地方,引入组件时写到需要引入的地方需要注意的是,使用vue-router控制路由则必须router-view作为容器。通过路由跳转的三种方式1、router-link【实现跳转最简单的方法】&amp;amp;lt;router-linkto=’需要跳转到的页面的路径&amp;amp;gt;浏览器在解析时,将它解析成一个类似于&amp;amp;lt;a&amp;amp;gt;的

    2022年7月27日
    3
  • 用户态和内核态切换开销_进程切换在用户态还是内核态

    用户态和内核态切换开销_进程切换在用户态还是内核态1.切换方式从用户态到内核态切换可以通过三种方式,或者说会导致从用户态切换到内核态的操作:系统调用,这个上面已经讲解过了,在我公众号之前的文章也有讲解过。其实系统调用本身就是中断,但是软件中断,跟硬中断不同。系统调用机制是使用了操作系统为用户特别开放的一个中断来实现,如Linux的int80h中断。 异常:如果当前进程运行在用户态,如果这个时候发生了异常事件,会触发由当前运行进程切换到处理此异常的内核相关进程中 外围设备中断:外围设备完成用户请求的操作之后,会向CPU发出中断信号,这

    2022年9月18日
    4
  • PHP中跨站脚本的过滤RemoveXss函数

    PHP中跨站脚本的过滤RemoveXss函数

    2021年8月29日
    155
  • Baidu与Google地图API初探

    Baidu与Google地图API初探

    2021年12月1日
    44
  • Java object转string「建议收藏」

    Java object转string「建议收藏」publicstaticcreateString(Objectobject){rerutnobject!=null?object.toString():””;}

    2022年4月30日
    62
  • CMS收集器和G1收集器的区别「建议收藏」

    CMS收集器和G1收集器的区别「建议收藏」目录CMS收集器和G1收集器的区别区别一:使用范围不一样区别二:STW的时间区别三:垃圾碎片区别四:垃圾回收的过程不一样对于CMS收集器和G1收集器的不同,目前简单写了一下4点,有不足的地方后面再不断的更新修改。CMS收集器和G1收集器的区别 区别一:使用范围不一样  CMS收集器是老年代的收集器,可以配合新生代的Serial和ParNew收集…

    2022年6月3日
    56

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号