1.多属性运动完整版
function buffMove(elem, attrObj, time, callback) { // callback /* elem 缓冲的元素 attrObj同时运动属性的对象{样式名:目标值}*/ clearInterval(elem.timer); elem.timer = setInterval(function () { var tag = true;// 初始值定义为true 假设所有的属性都达到了目标点 // name变量中存储的是width height 也就是要缓冲的样式 // 目标值attrObj[name] 原先的目标值target需要替换成attrObj[name] for (var name in attrObj) { //在当前left值的基础上+10 if (name == "opacity") { // name是opacity var current = parseInt(getStyle(elem, name) * 100); // target的值是0-1 更改的是透明度,透明度需要*100 target>1 其他属性的值 不需要*100 attrObj[name] = attrObj[name] > 1 ? attrObj[name] : attrObj[name] * 100 // } else { // name是其他属性 var current = parseInt(getStyle(elem, name)); } var speed = (attrObj[name] - current) / time; // speed 速度/步长 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed) //2.去验证假设的情况 if (current != attrObj[name]) { tag = false } if (name == "opacity") { // 透明度opacity elem.style[name] = (current + speed) / 100; } else { // 其他属性 elem.style[name] = current + speed + "px"; } } // 3.判断结论是否成立 if (tag) { clearInterval(elem.timer) if (callback) callback(); } }, 50) }
2.高级函数
2.1函数的分类
-
事件处理函数 标签.事件类型 = function(){}
-
普通函数 function 函数名(){}
-
表达式函数 var 变量名 = function(){}
-
回调函数/callback
-
闭包函数
-
匿名函数和立即执行函数
-
构造函数
2.2回调函数
-
将函数作为另一个函数的参数进行传递
<script> function fun2(){ console.log("其他逻辑") } function fun1(callback){ //callback 就是fun2函数 console.log("fun1函数") // 下面还有很多逻辑 这个逻辑我封装到另一个函数中了 callback(); } fun1(fun2);//回调函数就是 函数作为参数传递给另一个函数 </script>
2.2匿名函数
-
没有名字的函数
-
语法:function(){}
2.3立即执行函数IIFE
-
立即执行函数(IIFE) 匿名函数的自执行就叫立即执行函数
-
语法:(匿名函数)()
(function(){ console.log("匿名函数") })()
-
立即执行函数的参数
(function(a,b){//a,b就是形参 console.log(a,b) })(10,20)//实参
-
立即执行函数的返回值
var res = (function (a, b) { return a + b })(10, 20) console.log(res);
-
好处:避免全局污染,立即执行函数中的变量不会随意被更改
var a = "全局变量a值" var res = (function(){ var a = 10; var b = 20; return { "a":a, "b":b } })() a = 50; console.log(res); console.log(res.a); console.log(res.b);
-
练习 封装a.js getStyle和getRandom就不会被随意更改
var ujiuye = (function(){ function getStyle(){ console.log("获取非行间样式") } function getRandom(){ console.log("验证码") } return { "getStyle":getStyle, "getRandom":getRandom } })() 在页面中使用a.js中的方法 <script src="./a.js"></script> console.log(ujiuye); ujiuye.getStyle(); var getStyle = 50; ujiuye.getStyle();//getStyle方法就不会被覆盖 ujiuye.getRandom();
2.3闭包函数
2.3.1闭包函数的基础使用
-
局部变量/局部函数:函数内部声明的变量或者函数 称为局部变量/函数 函数外面无法使用 出了函数作用域就会被销毁
-
闭包函数:闭包就是能够读取其他函数内部变量的函数 函数套函数
//1.局部函数/局部变量 function outer() { var a = 10;//局部变量 function inner() { //局部函数 console.log(a);// 10 } } outer(); // console.log(a);//报错 // inner();// 报错 // 2.闭包函数:闭包就是能够读取其他函数内部变量的函数 函数套函数 function outer() { var a = 10;//局部变量 function inner() { //局部函数 console.log(a);// 10 } return inner } var res = outer();// res就是 function inner(){console.log(a)} // //我就想在外边拿到a console.log(res);// function inner(){console.log(a)} res();//10
-
闭包函数的优点和缺点
-
优点:缓存数据 扩大变量的作用域范围
-
缺点:如果大量使用闭包,可能造成内存泄漏(后期没用的变量不能及时得到释放,会浪费内存)。
-
//3.闭包函数的优点:缓存数据 扩大变量的作用域范围 function outer() { var a = 10 function inner() { a++; console.log(a); } return inner } var res = outer();//res就是inner函数 function inner(){a++,console.log(a)} res();//11 res();//12 res();//13 res();//14 /* js的垃圾回收机制:是js中定义回收资源的一种机制,每隔一段时间 js的执行环境就会去清理没用的数据 标记清除回收 引用计数回收 引用计数回收:每次使用变量 计数+1 当计数是0 就会被回收掉 */ // 4.闭包函数的缺点:如果大量使用闭包,可能造成内存泄漏(后期没用的变量不能及时得到释放,会浪费内存)。 // 5.手动释放:null //每次重新赋值 都是一个独立的闭包 var res1 = outer(); // res1 function inner(){a++,console.log(a)} res1();//11 res1();//12 res1();//13 res1 = null
2.3.2 闭包的使用场景
<script> // 1.需要使用函数内部的局部变量 function outer() { var a = 10; function inner() { return a } return inner } var res = outer();// res 就是 funtion inner(){return a} var a1 = res(); console.log(a1);// 10 // 2.输出结果是多少? var arr = []; for (var i = 0; i < 10; i++) { arr.push(function () { console.log(i) }) } /* arr = [ function(){console.log(i)} function(){console.log(i)} function(){console.log(i)} function(){console.log(i)} function(){console.log(i)} function(){console.log(i)} function(){console.log(i)} function(){console.log(i)} function(){console.log(i)} function(){console.log(i)} ] */ console.log(arr[6]);// function(){conosle.log(i)} arr[6]();// 10 arr[3]();// 10 // 如何修改? 调用arr[6]输出6 调用arr[5]输出5 var arr = []; for (var i = 0; i < 10; i++) { (function (a) {//形参a console.log(a) arr.push(function () { console.log(a) }) })(i)//实参i 是for循环中i的值 } /* arr[ function(){console.log(0)}, function(){console.log(1)}, function(){console.log(2)}, function(){console.log(3)}, function(){console.log(4)}, function(){console.log(5)}, function(){console.log(6)}, function(){console.log(7)}, function(){console.log(8)}, function(){console.log(9)}, ] */ arr[6](); //3.循环添加点击事件 在循环点击事件中获取对应的下标 var list = document.getElementsByTagName("li"); for (var i = 0; i < list.length; i++) { (function (i) { list[i].onclick = function () { console.log(i);//输出对应的下标 } })(i) } </script>