JS高级. 06 缓存、分析解决递归斐波那契数列、jQuery缓存、沙箱、函数的四种调用方式、call和apply修改函数调用方法
缓存
- cache
- 作用就是将一些常用的数据存储起来
- 提升性能
- 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>
沙箱
- 与外界隔绝的一个环境,外界无法修改内部的数据
- 沙箱基本模型
a) 沙箱中将所有变量的定义放最上面
b) 中间放一些逻辑代码
c)
(function(){
//变量定义
//逻辑代码
//如果需要,向window对象添加成员,以暴露接口
})()
- 如果需要在外加暴力一些属性或者方法,就可以将这些属性或者方法加到window全局对象上
- 但是这个window全局对象不可以直接引用,因为引用会破坏沙箱原则
- 所以我们选择使用传参的形式将window对象传入沙箱内
- 一般应用在书写第三方框架或者为第三方框架书写插件或者书写功能独立的一些组件
沙箱的优势
- 杀星模式使用的是IIFE,不会在外界报篓任何全局变量,也不会找茬代码污染
- 沙箱中的所有数据,都和外界隔离的,外界无法对其进行修改
- 函数可以创建作用域, 上级作用域无法直接访问下级作用域
沙箱实现原理
函数可以创建作用域, 上级作用域无法直接访问下级作用域
第三方框架
插件
独立的组件
函数的四种调用模式
函数模式
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修改函数调用方法的更多相关文章
- Python(迭代器 生成器 装饰器 递归 斐波那契数列)
1.迭代器 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外,迭代器的一大优 ...
- java递归 斐波那契数列递归与非递归实现
递归简单来说就是自己调用自己, 递归构造包括两个部分: 1.定义递归头:什么时候需要调用自身方法,如果没有头,将陷入死循环 2.递归体:调用自身方法干什么 递归是自己调用自己的方法,用条件来判断调用什 ...
- js函数的四种调用方式以及对应的this指向
一.函数调用,此时this是全局的也就是window 1 var c=function(){ 2 alert(this==window) 3 } 4 c()//true 二.方法调用 var myOb ...
- JavaScript高级之函数的四种调用形式
主要内容 分析函数的四种调用形式 弄清楚函数中this的意义 明确构造函对象的过程 学会使用上下文调用函数 了解函数的调用过程有助于深入学习与分析JavaScript代码. 本文是JavaScript ...
- Android NDK入门实例 计算斐波那契数列一生成jni头文件
最近要用到Android NDK,调用本地代码.就学了下Android NDK,顺便与大家分享.下面以一个具体的实例计算斐波那契数列,说明如何利用Android NDK,调用本地代码.以及比较本地代码 ...
- 7、斐波那契数列、跳台阶、变态跳台阶、矩形覆盖------------>剑指offer系列
题目:斐波那契数列 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0). f(n) = f(n-1) + f(n-2) 基本思路 这道题在剑指offe ...
- python基础练习题(题目 斐波那契数列II)
day16 --------------------------------------------------------------- 实例024:斐波那契数列II 题目 有一分数序列:2/1,3 ...
- JS 从斐波那契数列浅谈递归
一.前言 昨晚下班后,经理出于兴趣给我们技术组讲了讲算法相关的东西,全程一脸懵逼的听,中途还给我们出了一道比较有趣的爬楼问题,问题如下: 假设一个人从地面开始爬楼梯,规定一步只能爬一坎或者两坎,人只能 ...
- 【Java】斐波那契数列(Fibonacci Sequence、兔子数列)的3种计算方法(递归实现、递归值缓存实现、循环实现、尾递归实现)
斐波那契数列:0.1.1.2.3.5.8.13………… 他的规律是,第一项是0,第二项是1,第三项开始(含第三项)等于前两项之和. > 递归实现 看到这个规则,第一个想起当然是递归算法去实现了, ...
随机推荐
- Android NestedScrollView与RecyclerView嵌套,以及NestedScrollView不会滚动到屏幕顶部解决
①NestedScrollView与RecyclerView嵌套,导致滚动惯性消失 解决:mRecyclerView.setNestedScrollingEnabled(false); ②Nested ...
- idea 新建文件夹目录问题解决
选中工程,设置,去掉选项“Compact Empty Middle Packages” .
- redis的使用方式
常用的语法以及使用方式: key中不能包含回车空格等,key不要太长,占用内存. 概念介绍: 差集: a:{1,2,3} b:{2,3,4},以a为锚点,差集 ...
- 修改mysql编码方式
第一种: 通过mysql命令行修改: 1)首先查看数据库字符编码,命令为: show variables like’collation_%’; show variables like’char ...
- supersocket 通过配置文件启动服务 总是 初始化失败的 解决办法
<serverTypes> <add name="APPServerType" type="TMPServer.APP.APPServer, TMPSe ...
- ZT C++关键字new学习
http://blog.csdn.net/waken_ma/article/details/4007914 C++关键字new学习 很多新手对C++关键字new可能不是很了解吧,今天我一起来学习一下. ...
- C语言socket编程----struct sockaddr 和struct sockaddr_in介绍和初始化
sockaddr结构体 struct sockaddr{ sa_family_t sa_family; //地址族,最常用的是"AF_INET"(IPV4)和"AF_ ...
- 【LaTeX】E喵的LaTeX新手入门教程(3)
[LaTeX]E喵的LaTeX新手入门教程(3) 数学公式作者: 郭英东.sty 昨天熄灯了真是坑爹.前情回顾 [LaTeX]E喵的LaTeX新手入门教程(1)准备篇 [LaTeX]E喵的LaTeX新 ...
- SQA计划和测试规程
一.SQA计划 (一)目的 本计划的目的是定义我们该小组所做的“云医院”项目的SQA任务和职责,在项目过程中应遵循的流程.规范和约定等,以确保软件质量得到维持. (二)范围 本计划应用于“云医院”项目 ...
- ABAP git客户端
Jerry习惯把自己写的小程序放到自己的github上:https://github.com/i042416 对于写的ABAP程序,需要先把SAPGUI里的代码手动拷贝到本地,然后用git客户端pus ...