在哪修改网站关键词,黑糖WordPress主题,成都建设网站公司,自助建站系统平台函数
函数是一个可重用的代码块#xff0c;用来完成某个特定功能。每当需要反复执行一段代码时#xff0c;可以利用函数来避免重复书写相同代码。函数包含着的代码只能在函数被调用时才会执行#xff0c;就可以避免页面载入时执行该脚本在JavaScript中#xff0c;可以使用…函数
函数是一个可重用的代码块用来完成某个特定功能。每当需要反复执行一段代码时可以利用函数来避免重复书写相同代码。函数包含着的代码只能在函数被调用时才会执行就可以避免页面载入时执行该脚本在JavaScript中可以使用以下三种方法来定义一个函数 使用function语句定义函数使用Function()构造函数来定义函数在表达式中定义函数
Function构造函数定义函数
var 函数名 new Function(“参数1””参数2””参数3”……”函数体”);注意
1. 在使用Function()构造函数的时候第一个字母要大写
2. Function()构造函数只能在JavaScript 1.1或更高版本中使用
3. 每次调用构造函数时都会解析函数体并且创建一个新的函数对象效率非常底function语句定义函数
function 函数名 (参数1参数2……[形参]){语句块return 返回值
}function关键字用于定义一个函数 函数名函数名通常是一个合法的标识符,是唯一的区分大小写的 参数在函数里可以有0个或者多个参数。如果有多个参数参数与参数之间要用逗号隔开。无论函数是否有参数小括号必需要有 函数体用大括号括起来的代码块即函数的主体 返回值函数返回的值由关键字return完成可选项
在表达式中直接定义函数
var 函数名 function (参数1参数2…){函数体};注意 在表达式中定义函数的方法只能在JS1.2版本或以上版本中使用 函数名 函数名/变量名
var rightKeyfunction(){if(event.button2){alert(禁止使用鼠标右键);}
}
window.onmousedown rightKey;调用函数
1.直接调用
myFunction();或window.myFunction()2.事件处理中调用
div onclickmyFunction()/div3.将函数的返回值赋给变量
var t myFunction();函数的参数
形參定义函数时函数名后面()中的参数JavaScript中的函数允许给行参赋初始值 实参调用函数时传递的参数 参数的匹配 默认情况下形參和实参是一一对应的 但是当传递的参数个数与函数定义好的参数个数可以不匹配当不匹配时
如果传递的参数个数小于函数定义的参数个数JavaScript会自动将多余的参数值设为undefined如果传递的参数个数大于函数定义的参数个数那么多余传递的参数将会被忽略掉。
获取所有实参【arguments】
function Test(a,b){alert(typeof(arguments)); // 获得类型alert(arguments[1]); // 获取下标为1的参数值alert(arguments.length); // 获取参数的长度alert(arguments.callee); // 获取函数的所有内容
}
Test(zhang,li);默认参数
JavaScript中的函数允许给参数赋初始值 比如我们在创建封装一个创建table表格的函数如果任何参数不传我们也想创建一个四行五列并且背景颜色各行换色的表格这时候我们就可以使用表格来创建 案例创建一个带默认参数的函数
function tab(row,colorpink,color2gray){document.write(table border1 width500);for(var index 0; index row; index){if(index%2 1){document.write(tr bgcolorcolortdindex /tdtd1/tdtd1/tdtd1/tdtd1/td/tr);}else{document.write(tr bgcolorcolor2tdindex /tdtd1/tdtd1/tdtd1/tdtd1/td/tr);}}document.write(/table);
}
tab(10,gray,orange);函数的返回值
●return语句并不是必须的 ●默认情况下函数的返回值为undefined ●在使用 return 语句时函数会停止执行并返回指定的值return后面的代码不再执行
什么情况下添加return 如果函数中的变量要在函数外进行调用 函数体的结果需要在函数外进行使用
变量的作用域
全局变量 在函数外声明的的变量为全局在整个JS文档中生效 局部变量 在函数内用var声明的变量为局部变量只能在函数内部使用。
全局变局部
全局变量可以在局部的任意位置使用
局部变全局
局部变量不能在全局使用如果想要在全局使用可以去除前边的var或者将该值使用return返回到全局
块级作用域【ES6中新增的内容】
什么是作用域链【了解】
●只要在js中创建变量就会存在作用域【全局作用域】 ●写在函数内部的被称为局部作用域 ●如果函数中还有函数那么在这个作用域中就又可以诞生一个新的作用域 ●在函数中如果在当前作用域中没有查到值就会向上级作用域去查直到查到全局作用域这样一个查找过程形成的链条就叫做作用域链。 默认情况下内部环境可以通过作用域链访问所有外部环境但外部环境不能访问内部环境的任何变量和函数
var n 10;
function outer(){function inner(){function center(){console.log(n);}center();}inner();var n 15;
}
outer(); // undefined案例案例分析
var a 1
function fn1(){function fn2(){console.log(a)}function fn3(){var a 4fn2()}var a 2return fn3
}
var fn fn1()
fn() //输出多少如函数的执行形成一个私有作用域形参和当前私有作用域中声明的变量都是私有变量保存在内部的一个变量对象中其下一个外部环境可能是函数也就包含了函数的内部变量对象直到全局作用域。
预解析
预解析又称之为变量提升在js代码真正执行之前进行提前加载把所有带有var和function的关键字进行预解析 ●JavaScipt代码是由浏览器中的JavaScript解析器来执行的 ●JavaScript解析器在运行JavaScript代码的时候分为两步预解析和代码执行 ●预解析分为变量预解析变量提升和函数预解析函数提升 ●代码执行是按代码的书写顺序从上到下执行的
对于带有var和function关键字在预解释的时候操作 var :只声明不定义 function:既声明又定义 注私有作用域下也要进行预解析预解析只发生在当前的作用域下 就是当文档加载的时候开始只对window进行预解析函数执行的时候才会对里面的代码进行预解析
console.log(a); // 注意预解析的问题如果同时有变量和函数的预解析那么函数的优先级高
var a hello;
function a(){console.log(123);
}// 优先执行栈内存中的内容
// function a(){
// console.log(123);
// }
// var a hello;
// console.log(a); // hello案例分析代码结果 // 案例1
var num 10;
fun();
function fun(){console.log(num);var num 20;
}
// 案例二
var num 10;
function fun() {console.log(num);var num 20;console.log(num);
}
fun();// 案例三
var a 18;
f1();
function f1() {var b 9;console.log(a);console.log(b);var a 13;
}// 案例四
console.log(a,b,c);
var a b c 5;// 案例四
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {var a b c 9;console.log(a);console.log(b);console.log(c);
}
// 案例五
fn();//报错 只预解析“”左边的右边的是指针不参与预解析
var fnfunction(){console.log(11);
}
// 案例六
function fn(){console.log(a);a100;
}
fn();
console.log(a);
//注意js中如果在不进行任何特殊处理的情况下上面的代码报错下面的代码不再执行// 案例七
console.log(show);
function show(){console.log(123);
}
var show 10;// 案例八
function show(){console.log(123);
}
var show 10;
console.log(show);案例分析代码结果 // 案例1
var num 10;
fun();
function fun(){console.log(num);var num 20;
}
// 案例二
var num 10;
function fun() {console.log(num);var num 20;console.log(num);
}
fun();// 案例三
var a 18;
f1();
function f1() {var b 9;console.log(a);console.log(b);var a 13;
}// 案例四
console.log(a,b,c);
var a b c 5;// 案例四
f1();
console.log(c);
console.log(b);
console.log(a);
function f1() {var a b c 9;console.log(a);console.log(b);console.log(c);
}
// 案例五
fn();//报错 只预解析“”左边的右边的是指针不参与预解析
var fnfunction(){console.log(11);
}
// 案例六
function fn(){console.log(a);a100;
}
fn();
console.log(a);
//注意js中如果在不进行任何特殊处理的情况下上面的代码报错下面的代码不再执行// 案例七
console.log(show);
function show(){console.log(123);
}
var show 10;// 案例八
function show(){console.log(123);
}
var show 10;
console.log(show);变量的生命周期【了解】
JavaScript 变量的生命期从它们被声明的时间开始。 局部变量会在函数运行以后被删除。 全局变量会在页面关闭后被删除。
ulli1/lili2/lili3/lili4/lili5/lili6/li
/ulvar lis document.getElementsByTagName(li);for(var i0; ilis.length;i){lis[i].onclick function(){alert(i);}
}案例
// 案例一
function test(){uname 香水有毒;
}
console.log(uname);// 案例二
function test(){uname 香水有毒;
}
test();
console.log(uname); // 案例三
uname 香水有毒;
function test(){console.log(uname);
}
test(); // 案例四
var uname 香水有毒;
function test(){console.log(uname);
}
function test2(){uname 老鼠爱大米;test();
}
test2(); // 案例五
var uname 香水有毒;
function test(){console.log(uname);
}
function test2(){uname 老鼠爱大米;return test;
}
restest2();
res();自执行函数
(function a(){alert(我是自执行函数)} ()); // 用括号把整个表达式包起来
(function a(){alert(我是自执行函数)}) (); //用括号把函数包起来
!function a(){alert(我是自执行函数)}(); // 求反我们不在意值是多少只想通过语法检查。
function a(){alert(我是自执行函数)}();
-function a(){alert(我是自执行函数)}();
~function a(){alert(我是自执行函数)}();
void function a(){alert(我是自执行函数)}();
new function a(){alert(我是自执行函数)}();自执行函数通常都是定义之后立即执行以后都不再会调用所以声明时可以省略函数名因此自执行函数又叫匿名函数 。
(function(){console.log(我是匿名函数)})();// 我是匿名函数如果上一行代码没有使用 分号 ’ ; 结束可能会导致匿名函数通不过语法检查所以通常会在小括号前加个分号
;(function(){console.log(我是匿名函数)})()// 我是匿名函数自执行函数的效果
自执行函数可以用来保存变量的作用域防止污染全局变量 以一个经典的面试题为例
ulli这是第1个li/lili这是第2个li/lili这是第3个li/lili这是第4个li/lili这是第5个li/lili这是第6个li/li
/ul一个列表里有6个li要求点击li的时候打印当前被点击li的索引。 如果我们直接通过for循环绑定事件
var lis document.querySelectorAll(li);
for(var i 0;ilis.length;i){lis[i].onclick function (){console.log(i)}
}
// 无论哪个li被点击打印的永远都是相同的值因为在所有的点击事件中访问的都是全局的 i,当事件触发时i的值已经变成是lis.length了。在es6语法出现之后我们使用 let 关键字创建的块级作用域可以解决这种问题在 let 出现以前通常是使用匿名函数闭包的方式创建函数作用域来保存每一步循环里 i 的值
var lis document.querySelectorAll(li);
for(var i 0;ilis.length;i){(function(i){lis[i].onclick function (){console.log(i)}})(i)
}
// 使用这种方法每次循环都会创建一个匿名函数这个匿名函数生成了闭包的效果新建了一个作用域
// 这个作用域接收到每次循环的i值保存了下来即使循环结束闭包形成的作用域也不会被销毁
// 事件处理函数中访问的 i 不再是全局变量而且匿名函数中的局部变量。闭包
什么是闭包闭包就是能够读取其他函数内部变量的函数。例如在javascript中只有函数内部的子函数才能读取局部变量所以闭包可以理解成“定义在一个函数内部的函数“。在本质上闭包是将函数内部和函数外部连接起来的桥梁。 特点
闭包就是一个特殊的函数函数内部可以引用函数外部的参数和变量【能访问到其他作用域中的变量】参数和变量不会被垃圾回收机制回收【延长变量的生命周期】 创建闭包
// 简单的闭包
var num 10;
function show(){console.log(num);
}// 局部变量在全局使用
function show(){var num 10;return function(){ // 闭包函数return num};
}
var b show();
console.log(b());// 局部变量
function f1(){var n999;
}// 局部变量在全局使用
function f1(){var n999;function f2(){ alert(n); // 999}return f2; // 闭包函数
}
f1()()// 总结闭包就是能够读取其他函数内部变量的函数。案例将普通函数改为闭包函数
// 普通函数
function show(){var m 1;function inner(){var n 0;console.log(n);console.log(m);};inner();
}// 闭包函数
function show(){var m 1;return function(){var n 0;console.log(n);console.log(m);};
}闭包的用途
是前面提到的可以读取函数内部的变量就是让这些变量的值始终保持在内存中。
闭包的缺点
比普通函数更占用内存会导致网页性能变差在IE下容易造成内存泄露。
什么是内存泄漏
首先需要了解浏览器自身的内存回收机制。 每个浏览器会有自己的一套回收机制当分配出去的内存不使用的时候便会回收内存泄露的根本原因就是你的代码中分配了一些‘顽固的’内存浏览器无法进行回收如果这些’顽固的’内存还在一直不停地分配就会导致后面所用内存不足造成泄露。
闭包造成内存泄漏
因为闭包就是能够访问外部函数变量的一个函数而函数是必须保存在内存中的对象所以位于函数执行上下文中的所有变量也需要保存在内存中这样就不会被回收如果一旦循环引用或创建闭包就会占据大量内存可能会引起内存泄漏
函数案例
封装一个反转数组方法
// 方法一
function reverse(arr){var newArr [];for(var i0;iarr.length;i){newArr[arr.length-i-1] arr[i];}return newArr;
}
var arr1 reverse([1,4,7,9,12,16]);
console.log(arr1);// 方法二
function reverse(arr){var newArr [];for(var iarr.length-1;i0;i--){newArr[newArr.length] arr[i]} return newArr;
}
var arr1 reverse([1,4,7,9,12,16]);
console.log(arr1);// 注意数组中不管是任意内容都可以实现反转函数封装实现 - 冒泡排序
function sort(arr){for(var i0;iarr.length-1;i){for(var j0;jarr.length-i-1;j){if(arr[j] arr[j1]){var temp arr[j];arr[j] arr[j1];arr[j1] temp;} }}return arr;
}
var arr1 sort([40,8,15,18,12]);
console.log(arr1);使用函数判断今年是平年还是闰年
function isRunYear(year){// 闰年 true平年 falsevar flag false;if((year%40 year %100!0 )||year%4000){flag true;}return flag;
}
console.log(isRunYear(2000));
// 思考输入年份判断当前年份的2月份有多少天获取数组中的最大值
function max(arr){var max arr[1];for(var i0;iarr.length;i){if(arr[i] max){max arr[i]}}return max;
}
console.log(max([1,34,96,23,78]));