- 11/30/2016 8:14:11 AM
- 复习
- 补充条件是函数声明
- 如何使用闭包操作多个数据
- 使用闭包获取随机数
- 循环注册点击事件问题
- 循环setTimeout的问题
- 递归处理斐波数列存在的性能问题
- 第五天
- 闭包
11/30/2016 8:14:11 AM
- 函数是参数会有一个复制的过程 第7
- 在函数里面,如果有和形参相同的函数,这个函数会覆盖掉形参的值—- 函数里面有这个特殊点
- f1(10)
- 形参不进行预解析—不一定准确(用结论)
- 只会出现在面试中
- 作业题2
- 循环里面没有块级作用域,这边的i是全局的
- console.log(i),在函数里面,是在函数被调用的时候进行执行的打印
- 复习
- 获取后代元素
- 递归概念
- 划归思想
- 递归获取所有元素
- dom中没有直接获取后代元素的犯法
- 但是dom提供了获取带元素的属性(迟来的热点,childNodes)
- 先获取子代的所有元素,再去获取自带元素的所有子代
- 一次往下找,知道找到没有为知
- 注意:
- 第一层for—>第二层for(执行完成再进行走上一级的for)
复习
- 词法
- 词法作用域
- 在代码作用域就是在代码写好的时候,就可以确定变量的作用域
- 不去管代码的执行
- 词法作用域
- 在js中只有函数可以限定作用域
- 变量提升
- 再js预解析阶段,会将所有的变量的声明,提升到其所在的作用的范围
- 复杂的面试题
- 先变量提示
- 第二个
- 构造函数当做普通函数调用的this指向widow
- 1
- 全局作用域中声明中的变量,都是window的属性
- 第三个
- 静态的方法的Foo
- 执行顺序相关
- 第四个
- 创建一个对象
- 去找原型里面的
- 总结一个
- 函数
- 当成普通函数调用,this指向的是window
- 当成构造函数,this指向的是新创建出出来的对象 11/30/2016 10:15:22 AM
- 函数
补充条件是函数声明
- 总结
- 条件是函数声明只会提升函数名称,不会提升函数体
-
代码
<script> /* * 条件式函数声明,只会提升函数名!!!不会提升函数体!!!! * */ //foo();//foo is not a function(…) //注释掉上面 foo(){} /* if("foo" in window){ console.log(foo); function foo(){} }*/ /*代码的执行 * 条件式函数声明可以进行在外部拿到foo的声明.... * */ console.log(foo);//undefined if("foo" in window){ console.log(foo);//foo(){} //解析成函数表达式的形式,所以 //var foo = function(){}; function foo(){} } </script> ------------------------------------------- ## 闭包 ##
- 概念
- 字面意思
- 一个闭合的封闭的包裹结构 就是闭包
- js中的闭包
- 先这么记忆: 函数就是闭包
- 改造:
- 闭包指的就是可以访问独立的数据的函数
- 字面意思
- 闭包要解决的问题是什么?
- 如何从函数外去访问函数内容声明的变量
- ** 闭包就是可以访问对的数据的函数**
- 原理
- 就是函数的
- 内部-->外部
-
闭包的基本结构
//闭包的基本结构 function outer(){ var data = 3; function inner(){ return data; } return inner; } var fn = outer(); console.log(fn());//3
如何使用闭包操作多个数据
- 闭包
-
可以给函数一个独立的变量
1. 保护变量,其他人都不能访问,只能通过特定的渠道去访问 2. 可以在设置变量值的时候,添加一些校验逻辑
-
- 闭包的实际应用
- 闭包设置和获取值方法
- 初始步骤:
- 写设置和获取函数
- 调用外部函数,进行返回两个函数,方便外面使用
- 初始步骤:
-
代码
function outer(){ var data = 10; function getDate(){ return data; } function setData(value){ data = value; } /*return 两个函数,供外面使用*/ return { getDate : getDate, setData : setData }; } var obj = outer(); console.log(obj.getDate());//10 obj.setData(111); console.log(obj.getDate());//111
- 闭包返回值进行封装成对象的形式(直接在return中写)
-
代码结构
/*闭包 * * 函数可以设置和获取数据 * */ function outer(){ var data = 11; return { setData:function(val){ data = val; }, getData : function(){ return data; } } }; var obj = outer(); //通过返回的对象进行设置data和获取改变后的data obj.setData(222); console.log(obj.getData());//222 obj.setData(1111); console.log(obj.getData());//1111 //进行再次调用的外部函数,是新开辟的一块空间,data是原始的数据 var obj2 = outer(); console.log(obj2.getData());//11
-
使用闭包获取随机数
- 多次访问外部函数,会操作的不是一个
- 变量是存在函数的执行环境中
- 第二次调用的时候,不是同一个
- 每一次函数执行都会新开辟空间,注意: 新开辟空间 ======
-
代码结构
<script> /* * 使用闭包获取随机数 * * 调用rm()外部函数,进行返回生成的随机数 * */ function rm(){ var rmVal = Math.random(); return { getRmVal : function(){ return rmVal; } } } var obj = rm(); //打印的是同一个,因为调用外部函数,是同一个 console.log(obj.getRmVal());//0.06471660300867077 console.log(obj.getRmVal());//0.06471660300867077 //进行新开辟一块内存空间 var obj2 = rm(); console.log(obj2.getRmVal());//0.24329169554195662 </script> ---------------------------------------------------
循环注册点击事件问题
- 给每个div加上一个index,但是别人可以把其改掉
使用闭包处理
- 思路
- 问题的根源上
- 在于注册的所有点击事件,都会访问一个i变量
- 在点击的执行,i是最后一个值
- 不要在点击的时候,去访问全局的i
- 而是给点击事件,这个处理函数一个独立的数据
- 当我们点击div的时候,使用自己的事件处理程序…
- 注意
- 每次循环的时候,都给对应的的
- j是自己的
- 闭包所在的外部空间会一直存在
- 优化闭包解决循环点击处理点击事件的代码
循环setTimeout的问题
- setTimeout(回调函时间数,ms)
- 功能: 在指定的时间后执行回调函数中的内容
- 至少在指定的时间后执行
- 至少:
- 是因为setTingout的回调函数,需要在所有的侏罗纪代码指定完之后才回去检测有没有到时间…
- 0 : 是立即执行
-
- js
- js是单线程的:
- 同时只能执行一个任务
- js当中有两种任务
- 主任务(主要的逻辑代码)
- 次要任务(setTingout一级setInterval中的回调函数等….)
- 注意
- conso.log 不准确
- alert 会阻塞线程
- 这里顺序不规则
11/30/2016 4:17:26 PM
11/30/2016 4:37:33 PM
递归处理斐波数列存在的性能问题
- 功能: 在指定的时间后执行回调函数中的内容
- 每次都会重新计算
- 将数组直接定义在全局中,容易其他因素的干扰,不安全,
- 将数组作为函数的一个独有的数据来保护,所以使用闭包来创建函数(斐波那契)
11/30/2016 5:31:57 PM
第五天
闭包
- 闭包概念
- 主要解决问题
- 原因: 作用域的关系
- 案例
- 循环注册点击事件存在的问题
- 循环中setTimeout的问题
- 斐波那契
- 解决问题
- 使用闭包优化
12/2/2016 8:25:40 AM