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>
posted @ 2018-06-17 00:20  稀土骑士  阅读(88)  评论(0编辑  收藏  举报