zoukankan      html  css  js  c++  java
  • js学习笔记 day6

     
    ## 1.js的线程

    <script>

    //线程:一个线程一次只能处理一件事情,多个线程就可以多个事情同时进行
    //JS是单线程的!
    //JS中,分了三个任务
    //1.渲染任务
    //2.js的代码执行任务
    //3.事件处理任务(事件队列)
     
    //JS代码的执行顺序
    //1.先把主任务(代码任务)执行完毕
    //2.再去执行次要的任务(包括setTimeOut和setInterval中的回调函数中的代码)
    //setTimeOut
    //至少在指定的时间后执行指定回调函数
    //因为要等主任务中的代码执行完毕之后,才回去检查,setTimeOut的回调函数,有没到执行时间
    //问题代码
             for(var i = 0 ; i < 10; i++){
             setTimeout(function()
             console.log(j);
             },0);
            }
             //解决问题的代码
    for(var i = 0; i< 3; i++){
     
    function foo(j){
    //var j;
     
           //j = 实参
                      //j = i
    return function(){
    console.log(j);
    };
    }
    //0
    var f = foo(i);
    setTimeout(f, 0);
    }
    </script>

    ## 2.缓存

    <script>
    //缓存:cache
     
    //缓存的作用,就是将一些常用的数据,存储起来,提供使用,提升性
     
    //CDN Content Delivery Network
     
    //数据库 高并发
    //非关系型数据库(内存型数据库) MongoDB Redis
     
    //网站静态页面缓存机制
    //将网页静态化,存储在服务器端
    </script>
    ## 3.关于使用递归解决斐波那契数列问题的性能分析和优化

    <script>
    1.使用数组存储数列,虽然可以提升性能,但是有局限性
    //可以求5的 也可以求10的,但是要求100呢 100000呢
    var arr = [1, 1, 2, 3, 5, 8, 13, 21, 34];


    2. //定义一个缓存数组,存储已经计算出来的斐波那契数
    //1.计算的步骤
    //1.先从cache数组中去取想要获取的数字
    //2.如果获取到了,直接使用
    //3.如果没有获取到,就去计算,计算完之后,把计算结果存入cache,然后将结果返回
     
    // var cache = [];
    //
    // function fib(n){
    // //1.从cache中获取数据
    // if(cache[n] !== undefined){
    // //如果缓存中有 直接返回
    // return cache[n];
    // }
    // //如果缓存中没有 就计算
    // if(n <= 2){
    // //把计算结果存入数组
    // cache[n] = 1;
    // return 1;
    // }
    // var temp = fib(n - 1) + fib(n - 2);
    // //把计算结果存入数组
    // cache[n] = temp;
    // return temp;
    // }
    //
    // console.log(fib(6));


    var count =0 ;
    function createFib(){
    var cache = [];
    function fib(n){
    count ++;
    //1.从cache中获取数据
    if(cache[n] !== undefined){
    //如果缓存中有 直接返回
    return cache[n];
    }
    //如果缓存中没有 就计算
    if(n <= 2){
    //把计算结果存入数组
    cache[n] = 1;
    return 1;
    }
    var temp = fib(n - 1) + fib(n - 2);
    //把计算结果存入数组
    cache[n] = temp;
    return temp;
    }
    return fib;
    }


    3.把下一个知识点应用进来,创建缓存容器

    function createCache(){
    var cache = {};
    return function (key, value) {
    //如果传了值,就说名是设置值
    if(value !== undefined){
    cache[key] = value;
    return cache[key];
    }
    //如果没有传值,只穿了键,那就是获取值
    else{
    return cache[key];
    }
    }
    }
     
    var count =0 ;
    function createFib(){
    var fibCache = createCache();
    function fib(n){
    count ++;
    //1.从cache中获取数据
    if(fibCache(n) !== undefined){
    //如果缓存中有 直接返回
    return fibCache(n) ;
    }
    //如果缓存中没有 就计算
    if(n <= 2){
    //把计算结果存入数组
    fibCache(n , 1) ;
    return 1;
    }
    var temp = fib(n - 1) + fib(n - 2);
    //把计算结果存入数组
    fibCache(n, temp) ;
    return temp;
    }
     
    return fib;
    }


    var fib = createFib();
    // console.log(fib(6));
    fib(5);
    console.log(count);
    count = 0;
    fib(6);
    console.log(count);
    count = 0;
    fib(20);
    console.log(count);
    count = 0;
    fib(21);
    console.log(count);
    count = 0;
     
    </script>
    ## 4.jquery缓存实现的分析

    <script>
    //eleCache
    //typeCache
    //classCache
    //eventCache
     
    function createCache(){
    //cache对象中以键值对的形式存储我们的缓存数据
    var cache = {};
    //index数组中该存储键,这个键是有顺序,可以方便我们做超出容量的处理
    var index = [];
    return function (key, value) {
    //如果传了值,就说名是设置值
    if(value !== undefined){
    //将数据存入cache对象,做缓存
    cache[key] = value;
    //将键存入index数组中,以和cache中的数据进行对应
    index.push(key);
     
    //判断缓存中的数据数量是不是超出了限制
    if(index.length >= 50){
    //如果超出了限制
    //删除掉最早存储缓存的数据
    //最早存入缓存的数据的键是在index数组的第一位
    //使用数组的shift方法可以获取并删除掉数组的第一个元素
    var tempKey = index.shift();
    //获取到最早加入缓存的这个数据的键,可以使用它将数据从缓存各种删除
    delete cache[tempKey];
    }
    }
    //如果没有传值,只传了键,那就是获取值
    // else{
    // return cache[key];
    // }
    return cache[key];
    }
    }
     
    var eleCache = createCache();
    eleCache("name","高金彪");
    console.log(eleCache("name"));
    var typeCche = createCache();
    </script>

    ## 5.沙箱


    <script>
    //沙箱
    //与外界隔绝的一个环境,外界无法修改该环境内任何信息,沙箱内的东西单独属于一个世界
     
    //360沙箱模式
    //将软件和操作系统进行隔离,以达到安全的目的
     
    //苹果手的app使用的就是沙箱模式去运行
    //隔离app的空间,每个app独立运行
     
    //JS中的沙箱模式
    //沙箱模式的基本模型
     
    // (function(){
    // var a = 123;
    // })();
     
    var sum = 0;
    for(var i = 1; i<=100;i++){
    sum+=i;
    }
    console.log(sum);
     
    var a =123;
     
    (function(){
     
    //在沙箱中将所有变量的定义放在最上方
     
    //中间就放一些逻辑代码
     
    //最后,如果需要,就给外界暴露一些成员(通过window)
     
    var sum = 0;
    for(var i = 1; i<=100;i++){
    sum+=i;
    }
    console.log(sum);
    })();
     
    //为什么要使用立即执行函数表达式(IIFE)
    //因为IIFE不会在外界暴露任何的全局变量,但是又可以形成一个封闭的空间
    //刚好可以实现沙箱模式


    //jQuery当中的沙箱模式
    (function(win){
     
    var itcast = {
    getEle:function () {
     
    }
    }
     
    //如果需要在外界暴露一些属性或者方法,就可以将这些属性和方法
    //加到window全局对象上去
    //但是这window全局对象不可以直接引用,因为直接引用会破坏沙箱原则
    //所以我们选择使用传参的形式将 window对象 传入沙箱内
    //此时沙箱内使用window对象的时候,不会再去全局搜索window对象
    //而使用的就是沙箱内部定义的形参
     
    win.itCast = win.$ = itcast;
     
    })(window)


    //沙箱模式一般应用在书写第三方框架
    //或者为第三方框架书写插件
    //或者书写功能独立的一些组件
     
    //沙箱模式的优势
    //1.沙箱模式使用的是IIFE,不会再外界暴露任何的全局变量,也就不会造成全局变量污染
    //2.沙箱中的所有数据,都是和外界完全隔离的,外界无法对其进行修改,也就保证了代码的安全性


    //js中沙箱模式的实现原理就是
    //函数可以构建作用域!上级作用域不能直接访问下级作用域中的数据
    </script>
    ## 6.函数的四种调用模式

    <script>
    //1.函数模式
    //this指向window全局对象
     
    //2.方法模式
    //this指向调用这个方法的对象
     
    //3.构造函数模式
    //this 使用new创建出来的对象
     
    //4.上下文模式
     
    function test(){
    console.log(this);
    }
    test();
     
    var obj1 = {
    test:function(){
    console.log(this);
    }
    }
    obj1.test();
     
    function Person(){
    console.log(this);
    }
    var obj =new Person();
     
    </script>

    ## 7.构造函数的调用模式特征

    <script>
    //构造函数调用模式的特征
     
    //1.构造函数的首字母要大写
    //2.一般情况下和new关键字一起使用
    //3.构造函数中的this指定而是new关键字创建出来的对象
    //4.默认的返回new创建出来的这个对象
     
    function Person(){
     
    }
     
    var p = new Person();
    //构造函数的返回值:
    //默认返回new创建创建出来的对,若是值类型的数据,没有影响
    //若是对象类型,则返回这个对象,不会返回原来创建出来的对象
     
    //1.工厂模式的构造函数
    function Person(name,age){
    var o = {
    name:name,
    age:age,
    sayHello:function(){
     
    }
    }
    return o;
    }
     
    var p = Person("张三", 18);
    console.log(p);
    //简单工厂模式的构造函数 创建出来的对象 跟该构造函数无关
    //简单工厂模式的构造函数,实际的调用模式是 函数模式
     
    //2.寄生式构造函数
    function Person(name,age){
    var o = {
    name:name,
    age:age,
    sayHello:function(){
     
    }
    }
    return o;
    }
     
    var p = new Person();
     
    </script>
    ## 8.上下文函数调用模式

    <script>
    //上下文
    //字面意思:上面的文字,下面的文字
     
    //JS中的上下文
    //context 执行环境的意思
    //this
     
    //在上下文调用模式中,可以修改this的值,也就是可以修改函数的调用方式
     
    //使用如下两个方法,可以修改函数调用上下文,也就是this的值
    //apply
    //api文档中的语法语句中 [] 代表括起来的东西可有可无
    //函数.apply(对象, 函数需要参数列表,是一个数组)
    //call
    //函数.call(对象,arg1,arg2,arg3...argn)
     
    var name = "莱昂纳多·自强·郭";
    function sayHello(a, b) {
    console.log(this.name + "吃了"+ (a * b) + "个馒头");
    }
    // sayHello(); //
    var obj = {
    name:"尼古拉斯·电饭·锅"
    }
     
    var arr= []
    arr.push();
    arr.push();
    sayHello.apply(obj,arr); //
     
    function test(a , b ,c){
     
    }
    sayHello.call(obj, 1, 2);
    // sayHello.call(obj); //
    //左值 右值
    // function test(){
     
    // this = 1;
     
    // }
    //call和apply的区别
    //1.第一个参数都是要把this的指向修改成为指定的对象
    //2.当函数需要参数的时候,那么apply是用数组进行参数的传递
    //3.而call是使用单个的参数进行传递
     
    //call用于确定了函数的形参有多少个的时候使用
    //apply用于函数的形参个数不确定的情况
    </script>



    <script>
         //案例:求一个数组中的最大值
         var arr = [9, 1, 4, 10, 7, 22, 8];
         //Math.max
         Math.max(1,2,34,5);
     
         //apply方法的第二个参数 是一个数组
         // 在调用的时候,会将数组中的每一个元素拿出来,作为形参,挨个传递给函数
     
         //apply方法和call方法第一个参数传递null的时候,都表示为函数调用模式
         //也就是将this指向window
         var max = Math.max.apply(null, arr);
         console.log(max);


         //案例:将传入的参数打印,参数之间用-相互连接

         function foo() {
         return arguments.join("-");
     
         //伪数组不具有join方法,所以这个时候就要考虑去借用一下数组的join方法
         var str = Array.prototype.join.apply(arguments,["-"]);
         var str = [].join.apply(arguments,["-"]);
         return str;
         }
         var str = foo(1, 3, "abc", "ffff", 99) // 1-3-abc-ffff-99
         console.log(str);


         // var arr = [1,2,3,4];
         console.log(arr.join("-"));
     
         window.onload = function () {
         //案例:给页面上所有的 div 和 p 标签添加背景色
         var divs = document.getElementsByTagName("div");
         var ps = document.getElementsByTagName("p");
     
         var arr = [];
         //little tip: push方法可以传多个参数
         //arr.push(1,2,3,4,4,5)
     
         arr.push.apply(arr,divs);
         arr.push.apply(arr,ps);
     
         //如果使用arr.push()直接把divs传进来
         //那么相当于在arr中的第一个元素中存储了一个divs数组
         //但是我们需要把divs中的每一个元素单独的存入arr中
         //所以需要调用push方法的如下形式 push(1,2,4,4,5)
         //要实现这个形式的调用,就用到了apply方法的第二个参数的特性
         //在调用的时候,会将第二个参数的数组,拆成每一个元素以(a,b,c,d,e,f,g) 传入函数
     
         //相当于 arr.push(divs[0],divs[1],divs[..])
         arr.push(divs)


         for (var k = 0; k < arr.length; k++) {
         var ele = arr[k];
         ele.style.backgroundColor = "yellow";
         }
     
         for (var i = 0; i < divs.length; i++) {
         var div = divs[i];
         div.style.backgroundColor = "#ccc";
         }
        
         for (var j = 0; j < ps.length; j++) {
         var p = ps[j];
         p.style.backgroundColor = "#ccc";
         }
         }
    </script>

    ## 9.call apply 和bind 的概述





    <script>
        // call bind apply 改变函数中的this
        // 函数是一个对象
        // var fn = new Function();
        // function fn() {
        // }
        
        // 证明fn是Function的实例(对象)
        // console.log(fn.__proto__ === Function.prototype);
        
        // console.dir(fn);
        
        function fn(x, y) {
         console.log(this);
         console.log(x + y);
        }
        
        // fn(5, 6); // this->window
        
        // 1 调用函数,改变函数中的this
        // 2 第一个参数 设置函数内部this的指向
        // 其它参数,对应函数的参数
        // 3 函数的返回值 call的返回值就是函数的返回值
        // 4 测试
        // var obj = {
        // name: 'zs'
        // }
        // fn.call(obj, 5, 6);
        // apply 只有两个参数
        // 1 调用函数,改变函数中的this
        // 2 第一个参数 设置函数内部this的指向
        // 第二个参数 是数组
        // 3 函数的返回值 apply的返回值就是函数的返回值
        // 4 测试
        // var obj = {
        // name: 'ls'
        // }
        // fn.apply(obj, [1, 2]);
        // bind
        // 1 改变函数中的this,不会调用函数,而是把函数复制一份
        // 2 第一个参数 设置函数内部this的指向
        // 其它参数,对应函数的参数
        // 3 函数的返回值 call的返回值就是函数的返回值
        // 4 测试
        var obj = {
         name: 'ww'
        }
        
        var f = fn.bind(obj, 5, 5);
        f();
    </script>

















    </script>
  • 相关阅读:
    DbHelper数据操作类
    获取cpu序列号,硬盘ID,网卡MAC地址
    用户必备资料 103个Windows XP运行命令
    在Web.config配置文件中自定义配置节点
    Microsoft.NET PetShop4架构与技术分析
    数字转英文(货币)大写(vb)
    如何计算dba_tables中的avg_row_len.
    行选移与行链接的介绍
    如何使用动态SQL
    如何导致全表扫描原因
  • 原文地址:https://www.cnblogs.com/cwp115/p/9191827.html
Copyright © 2011-2022 走看看