缓存

  1. cache
  2. 作用就是将一些常用的数据存储起来
  3. 提升性能
  4. cdn
 //-----------------分析解决递归斐波那契数列
<script> //定义一个缓存数组,存储已经计算出来的斐波那契数
//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;
// } // 把下一个知识点应用进来,创建缓存容器 // function createCache(){
// var cache = {};
// return function (key, value) {
// //如果传了值,就说名是设置值
// if(value !== undefined){
// cache[key] = value;
// return cache[key];
// }
// //如果没有传值,只穿了键,那就是获取值
// else{
// return cache[key];
// }
// }
// } // 缓存容器
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>
 

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 >= 40){
//如果超出了限制
//删除掉最早存储缓存的数据
//最早存入缓存的数据的键是在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>
 

jQuery缓存的分析

 
<script>
function createCache() {
var keys = [];
function cache( key, value ) {
// 使用(key + " ") 是为了避免和原生(本地)的原型中的属性冲突
if ( keys.push( key + " " ) > 3 ) {
// 只保留最新存入的数据
delete cache[ keys.shift() ];
}
// 1 给 cache 赋值
// 2 把值返回
return (cache[ key + " " ] = value);
}
return cache;
} var typeCache = createCache();
typeCache("monitor");
console.log(typeCache["monitor" + " "]); typeCache("monitor","张学友");
console.log(typeCache["monitor" + " "]); typeCache("monitor2","刘德华");
console.log(typeCache["monitor2" + " "]); typeCache("monitor3","彭于晏");
console.log(typeCache["monitor3 "]); // console.log(typeCache["monitor "]); </script>

沙箱

  1. 与外界隔绝的一个环境,外界无法修改内部的数据
  2. 沙箱基本模型

    a)  沙箱中将所有变量的定义放最上面

    b)  中间放一些逻辑代码

    c)

(function(){
//变量定义
//逻辑代码
//如果需要,向window对象添加成员,以暴露接口
})()
  1. 如果需要在外加暴力一些属性或者方法,就可以将这些属性或者方法加到window全局对象上
  2. 但是这个window全局对象不可以直接引用,因为引用会破坏沙箱原则
  3. 所以我们选择使用传参的形式将window对象传入沙箱内
  4. 一般应用在书写第三方框架或者为第三方框架书写插件或者书写功能独立的一些组件

沙箱的优势

  1. 杀星模式使用的是IIFE,不会在外界报篓任何全局变量,也不会找茬代码污染
  2. 沙箱中的所有数据,都和外界隔离的,外界无法对其进行修改
  3. 函数可以创建作用域, 上级作用域无法直接访问下级作用域

沙箱实现原理

  函数可以创建作用域, 上级作用域无法直接访问下级作用域

第三方框架
插件
独立的组件

函数的四种调用模式

函数模式    

  this指向window全局对象

方法模式

  this指向调用这个方法的对象

var obj = {
name:'jack',
sayHello: function () {
console.log('hello');
}
}
obj.sayHello();

构造函数模式  

    this  使用new创建出来的对象

    new Obj()

简单工厂模式的构造函数创建出来的对象和工厂函数无关

function Person(name, age){

        var o={
name:name,
age:age
}
return o;
}
var p = Person('jack',20);
console.log(p); // P 是一个 Object对象,和构造函数Person()无关

  寄生式构造函数

a)    function fun(name, age) {
var o = {
name: name,
age: age
}
return o;
}
var obj = new fun('jack', 20); //创建出来的是Object对象,和构造函数无关

  简单工厂模式的构造函数,实际上调用模式是 函数模式 调用

上下文模式 

     var name = "莱昂纳多·自强·郭";
function sayHello(a, b) {
console.log(this.name + "吃了"+ (a * b) + "个馒头");
} sayHello(); // 莱昂纳多·自强·郭吃了NaN个馒头 var obj = {
name:"尼古拉斯·电饭·锅"
} var arr= []
arr.push();
arr.push();
sayHello.apply(obj,arr); // 尼古拉斯·电饭·锅吃了NaN个馒头
     sayHello.call(obj, 1, 2); // 尼古拉斯·电饭·锅吃了2个馒头

1.  左值(等号左边)  右值(等号右边)

a)  左值被赋值
b)  右值不能被赋值,
2.  上下文调用模式中,可以修改this的值,也就是可以修改函数调用方法
3.  使用如下方法可以修改上下文,也就是this的值
  a)  apply:函数.apply(this修改成的那个对象,[可传可不传])//传数组
  b)  call:函数.call(this修改成的那个对象,[value1], [value2], ...[valueN]);
  c)  定义在Function.prototype里
  d)  数组可以点出来任何属性不报错
//案例:将传入的参数打印,参数之间用-相互连接
function foo(){
// return arguments.join("-"); // 是错误的
//伪数组不具有join方法,所以这个时候就要考虑去借用一下数组的join方法
var str = Array.prototype.join.apply ( arguments, ["-"]);
// var str2 = [].join.apply( arguments ,["-"]);
return str ;
} var str = foo(1,2,"abc","sofa",99)
console.log(str);// 1-2-abc-sofa-99
4.  call和apply的区别
  a)  第一个参数都是要把this修改成对象
  b)  当函数需要参数的时候,那么apply用数组进行传值
  c)  call用单个参数传值
  d)  apply和call方法第一个传入参数是null的时候都表示为函数调用模式
    1.  也就是将this指向window
5.  array.prototype === [];两个书写方式表达的意思相同
6.  api文档语句中[],的内容表示可有可无
7.  undefined*undefined = NaN
//案例:求一个数组中的最大值
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 ); //22
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";
// }
}

JS高级. 06 缓存、分析解决递归斐波那契数列、jQuery缓存、沙箱、函数的四种调用方式、call和apply修改函数调用方法的更多相关文章

  1. Python(迭代器 生成器 装饰器 递归 斐波那契数列)

    1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...

  2. java递归 斐波那契数列递归与非递归实现

    递归简单来说就是自己调用自己, 递归构造包括两个部分: 1.定义递归头:什么时候需要调用自身方法,如果没有头,将陷入死循环 2.递归体:调用自身方法干什么 递归是自己调用自己的方法,用条件来判断调用什 ...

  3. js函数的四种调用方式以及对应的this指向

    一.函数调用,此时this是全局的也就是window 1 var c=function(){ 2 alert(this==window) 3 } 4 c()//true 二.方法调用 var myOb ...

  4. JavaScript高级之函数的四种调用形式

    主要内容 分析函数的四种调用形式 弄清楚函数中this的意义 明确构造函对象的过程 学会使用上下文调用函数 了解函数的调用过程有助于深入学习与分析JavaScript代码. 本文是JavaScript ...

  5. Android NDK入门实例 计算斐波那契数列一生成jni头文件

    最近要用到Android NDK,调用本地代码.就学了下Android NDK,顺便与大家分享.下面以一个具体的实例计算斐波那契数列,说明如何利用Android NDK,调用本地代码.以及比较本地代码 ...

  6. 7、斐波那契数列、跳台阶、变态跳台阶、矩形覆盖------------>剑指offer系列

    题目:斐波那契数列 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). f(n) = f(n-1) + f(n-2) 基本思路 这道题在剑指offe ...

  7. python基础练习题(题目 斐波那契数列II)

    day16 --------------------------------------------------------------- 实例024:斐波那契数列II 题目 有一分数序列:2/1,3 ...

  8. JS 从斐波那契数列浅谈递归

    一.前言 昨晚下班后,经理出于兴趣给我们技术组讲了讲算法相关的东西,全程一脸懵逼的听,中途还给我们出了一道比较有趣的爬楼问题,问题如下: 假设一个人从地面开始爬楼梯,规定一步只能爬一坎或者两坎,人只能 ...

  9. 【Java】斐波那契数列(Fibonacci Sequence、兔子数列)的3种计算方法(递归实现、递归值缓存实现、循环实现、尾递归实现)

    斐波那契数列:0.1.1.2.3.5.8.13………… 他的规律是,第一项是0,第二项是1,第三项开始(含第三项)等于前两项之和. > 递归实现 看到这个规则,第一个想起当然是递归算法去实现了, ...

随机推荐

  1. CKEditor的使用

    需要配置的功能列表 //class: cke_button( 按钮 ) , ck_combo(下拉) /* 需要配置的功能列表 document:保存(save).新建(newpage).预览(pre ...

  2. Iscrool下拉刷新

    简易下拉刷新 css样式: *{ margin: 0px; padding: 0px; } #wrapper{ width: 100%; height: 150px; border: 1px soli ...

  3. WebSettings 最全属性说明

    setAllowContentAccess (boolean allow) 是否允许在WebView中访问内容URL(Content Url),默认允许.内容Url访问允许WebView从安装在系统中 ...

  4. SQL 出现18456

    SQL Server 2008R2 18456错误解决方案   SQL Server 2008R2 18456错误解决方案 微软解释说,因密码或用户名错误而使身份验证失败并导致连接尝试被拒时,类似下面 ...

  5. Sql根据经纬度算出距离

    SELECT  ISNULL((2 * 6378.137 * ASIN(SQRT(POWER(SIN((117.223372- ISNULL(Latitude,0) )*PI()/360),2)+CO ...

  6. 架构蓝图--软件架构 "4+1" 视图模型

    引言 我们已经看到在许多文章和书籍中,作者欲使用单张视图来捕捉所有的系统架构要点.通过仔细地观察这 些图例中的方框和箭头,不难发现作者努力地在单一视图中表达超过其表达限度的蓝图.方框是代表运行的程序吗 ...

  7. 获取v$latch数据源实验

    实验环境:Oracle Rac 11.2.0.3 首先获取v$latch的定义:通过PL/SQL或者get ddl等常规途径只能获取到v_$latch相关的视图信息.需要通过特殊方法获取v$latch ...

  8. March 10 2017 Week 10 Friday

    If you love life, life will love you back. 爱生活,生活也会爱你. Love life, and it will love you back. All thi ...

  9. Python语言程序设计基础(1)—— 程序设计基本方法

    Everybody in this country should learn how to program a computer,because it teaches you how to think ...

  10. CSP

    CSP(Content-Security-Policy): 内容安全策略   作用: .限制资源获取 .报告资源获取越权   限制方式: .default-src限制全局 跟链接请求有关的东西,限制他 ...