函数
1.函数的声明
(1)函数声明
function 函数名(){ 保存的代码块 }
function fun(){
console.log("声明了一个函数");
}
(2)函数调用
函数名()
fun();//只有调用函数,函数才会执行
fun();//函数可以重复调用
(3)表达式声明
声明:var 变量 = function (){}
调用:变量()
var fun1 = function (){
console.log("表达式函数");
}
fun1();
思考:表达式声明和普通函数的声明有什么区别?
sum(); //10
function sum(){ console.log(10)}
表达式声明
s(); //报错 s is not a function
var s = function(){ console.log(20)}
在预解析的过程中,函数会存储整个,因此可以在之前调用,表达式是var声明,只会存储undefined
2.函数的简单使用
//声明一个函数,计算1-100的和
function sum(){
var s = 0;
for(var i = 1;i<=100;i++){
s += i;
}
console.log(s);
}
//2.调用
sum(); //5050
3.函数的参数
a.函数参数:如果函数中遇到不能确定的值,就做成参数。
b.函数参数分为形式参数和实际参数,形参与实参一一对应
形参(形式参数):function 函数名(a){} a:形参
实参(实际参数):函数名(10) 10:实参
参数的几种情况:
(1.)一个参数
function sum(a) {//a=形参 var a;
console.log(10+a);
}
sum(10); //a=10
sum(20);//a = 20;
(2.)多个参数
function add(a,b) {
console.log(a+b);
}
add(10,20);//30
add(100,200);//300
//多个参数之间用逗号隔开
(3.)参数个数不确定
//如果参数的个数确定不了,就不写参数,使用关键字:arguments(实参集合),他类似于数组,与数组用法相同
function sum1() {
console.log(arguments); //获取实参集合 10,20,30,40
console.log(arguments.length); //获取实参长度 4
console.log(arguments[0]);//10
}
sum1(10,20,30,40);
//arguments和参数的关系:arguments和形参是互通的
function add(a) {
console.log(arguments[0]); //10
arguments[0] = 20; //arguments和参数是一个东西
console.log(a);//20
}
add(10);
4.函数的参数类型
//所有的js类型都能作为函数参数:Number,String,Boolean,null,undefined,Object
//Null和undefined不建议做参数传入,没有意义
//1.number
function sum(a) {//a=形参 var a;
console.log(10+a);
}
sum(10); //a=10
sum(20);//a = 20;
//2.String
//声明一个函数,判断输入的值是否是一个小数
function isXX(str){
if(parseInt(str) != parseFloat(str)){
console.log("小数");
}else{
console.log("整数")
}
}
isXX("12.9");
//3.Boolean
function moodFun(mode){
if(mode == true){ //开心
console.log("怕拍手");
}else{
console.log("跺跺脚")
}
}
moodFun(true);
//4.obj
var obj = {
"attr":"唐伯虎",
"name":"如花",
"age":48,
"height":180
}
//声明一个函数,将对象中存储的数据,转化成一句话输出
function fun(obj){
console.log(obj.attr+"找了一个对象,叫"+obj.name);
}
fun(obj);
//5.array
//声明一个函数,实现数组从小到大排序
//冒泡,快排,选择
//选择排序:拿第一个元素和后面所有的进行比较,如果比第一个更小,交换位置
var arr = [3,7,1,9,5,6,4,8,2];
function fun(obj){
console.log(obj.attr+"找了一个对象,叫"+obj.name);
}
fun(obj);
function sheng(arr){
for(var i=0;i<arr.length;i++){
for(var j=i+1;j<arr.length;j++){
if(arr[i]>arr[j]){
var temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
console.log(arr);
}
sheng([2,5,1,4,7,6,8]);
//6.函数作为参数
function xk(){
console.log("下课");
}
function funs(f){//var f= function xk(){ console.log("下课");这就是一个表达式函数,调用表达式函数:变量名();
f();
}
console.log(xk); //函数名代表的是整个函数
funs(xk);
5.函数中的问题
(1)函数中重复命名
函数的命名规则与变量名的命名规则相同
a.函数名之间不能重名
b.函数名与变量名也不能重名
function sum(x,y){
console.log("x+y=" + (x+y) );
}
function sum(x,y){
console.log(x+y);
}
sum(10,20);//30 而不是 x+y=30 第二个函数的结果覆盖了第一个函数的结果
(2)函数的形参和实参个数不同
function add(x,y){//var x,y;
console.log(x+y);
}
add(10,20); //x = 10,y = 20 30
add(10,20,30);//x = 10, y = 20 30 实参个数大于形参个数时,多的不管
add(10); //x = 10,y=undefined NaN 实参个数小于形参个数时,没有被赋值的形参值为undefined
(3)函数中的this
var w = 100; //所有的全局变量都属于window
function f(){
console.log(this.w);//100,普通函数中的this指的是window
}
f();
6.作用域
作用域:作用域指变量或函数的有效使用范围(生命周期),有全局作用域和局部作用域。
全局变量:直接在script标签下声明的变量也就是函数外声明的变量(函数),叫做全局变量(函数)。
特点:可以在任何地方被访问和修改,会一直存储在内存,直到页面关闭
局部变量:函数内部定义的变量(函数),叫做局部变量(函数)。
特点:只能在函数内部使用,出了函数括号就被销毁。
//1.全局变量
var a = 10;
function sum(){
console.log(a); //10
a = 100;
}
sum();
console.log(a);//100
//2.局部变量:只能在函数内使用,出了函数的{}就会被销毁
function fun() {
var x = 20;
console.log(x);//20
}
fun();
//console.log(x);//undefined
作用域链:js中的一种查找机制,先找自己作用域范围内是否存在,有就用自己的,没有就依次在父级作用域查找,一直找到全局,如果全局也没有,系统会报错。XX is not undefined;
var i = 10;
function f() {
var i = 20;
function ff() {
console.log(i);//20 自己没有,找上一个父级
}
ff();
}
f();
7.预解析(变量提升)
浏览器在解析js的时候,其中至少要经历两个步骤
1.预解析
全局作用域:找var function
先找var,找到以后会在js仓库中存储当前变量但不赋值,如果重名只声明一次,变量重名不会覆盖,var a = undefined
再找function,找到以后会在js仓库中先声明函数再存储整个函数,函数重名会覆盖 function 函数名(){代码块};
局部作用域:找参数,就是在执行函数时函数内部可以看做是一个小的区域,有自己的预解析,参数就跟var一样
2.逐步执行
//1.var
console.log(a); //undefined
var a = 10;
console.log(a);//10
//2.function
console.log(sum);//function sum(){console.log(10+20);}
sum();//30
function sum() {
//计算两个数的和
console.log(10+20);
}
//3.先找var,再找function,同名会覆盖,
//逐行执行的时候,只会走变量声明赋值,函数不会再重新声明
console.log(c); //函数2
var c = 10;
console.log(c); //10
function c() {
console.log("函数1");
}
console.log(c); //10
var c = 30;
console.log(c); //30
function c() {
console.log("函数2");
}
console.log(c); //30
//4.函数在调用前,也会有预解析
var a = 10;
function sum() {
console.log(a);//undefined
var a = 10;
}
sum();
var x = 10;
var y = 20;
function fun(){
console.log(x);//undefined
console.log(y);//20
var x = 20;
}
fun();
8.函数返回值
为什么要用函数返回值:函数是用来实现某个特定的功能,操作完之后,在函数外部可能会需要使用这个计算好的值,但是在函数内部定义的变量外面访问不了,针对这个情况,函数通过返回值将计算好的数据传出函数,在外部使用。
//函数返回值:
所有的函数,在调用以后都会有一个返回的结果,没有指定返回值,返回undefined
通过return关键字,设置返回值
return 值
//注意:
return 一次只能返回一个值,写了很多个,也只能返回最后的那个值
函数中只要遇到return ,函数就会结束
//1.声明一个函数,计算两个数的和,返回计算结果
function sum(a,b){
var c = a+b;
var d = a*b;
return c,d;
}
var s = sum(10,20);//定义一个变量存放return返回的值
console.log(s); //200
//2.函数中只要遇到return 函数结束
function fun1(){
return "hello";
console.log("hello world");
console.log("hello 你好");
console.log("hello 哈哈");
}
fun1();//hello 走完return函数结束
function su(){
var s = 0;
for(var i = 1;i<=100;i++){
s += i; //s = 1
return s;
}
}
console.log(su());//1
9.函数返回值类型
//函数的返回值类型:js所有的数据类型都能作为函数的返回值
//1.number
function sum(a,b){
return a+b;
}
/2.string
var obj = {
"name":"雄宝宝",
"age":18
}
function toString(obj) {
return "姓名是:"+obj.name+"年龄是:"+obj.age;
}
console.log(toString(obj));
//3.array
var arr = [5,7,8,1,4,2,9,3,6];
function sort(array) {//array =10 array= [5,7,8,1,4,2,9,3,6];
for(var i = 0;i<array.length;i++){
for(var j = i+1;j<array.length;j++){
if(array[i]>array[j]){
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
return array;
}
console.log(sort(arr));
//4.function
function fun() {
return function(){
console.log("我是返回的函数");
return function(){
console.log("s");
}
}
}
var f = fun(); //var f = function(){ console.log("我是返回的函数"); }
f();
fun();
10.获取元素样式
获取行间样式:标签.style.属性名
获取非行间样式:
标准浏览器: getComputedStyle(标签).属性名 ,ie不兼容(6 7 8)
i e浏览器:标签.currentStyle.属性名
// 标准浏览器: getComputedStyle(标签).属性名
var w = getComputedStyle(oDiv).width;
console.log(w);
//ie浏览器:标签.currentStyle.属性名
var w = oDiv.currentStyle.width;
console.log(w);
//兼容:判断方法有没有,拿其中一个方法作为判断条件,如果有就用这个方法,没有换一个
//alert( oDiv.currentStyle)//true,非0为真,有值 “”,0,false,null undefined
if(oDiv.currentStyle){ //有值 ie
var w = oDiv.currentStyle.width;
}else{
var w = getComputedStyle(oDiv).width;
}
console.log(w);
//封装(声明一个函数,把主要代码放入函数中,找可变的值做参数,调用)
var w = getStyle(oDiv,"width");
console.log(w);
function getStyle(elem,attr){ //元素:elem,属性:attr
if(elem.currentStyle){
var w = elem.currentStyle[attr];
}else{
var w = getComputedStyle(elem)[attr];
}
return w;
}
//调用
<script src="ujiuye.js"></script>
<script>
var oDiv = document.getElementsByTagName("div")[0];
console.log(getStyle(oDiv,"width"));
</script>
函数的应用
代码复用:结构一样,功能一致,我们就采用代码复用
步骤:1.先实现其中一组的功能,里面的标签必须通过父元素获取
2.声明一个函数,将之前实现的一组的主要代码放入函数中,将父元素作为参数
3.for循环调用函数
//点击编辑,出现编辑框,点击保存则保存修改后的值,取消则恢复原样 部分代码
<ul>
<li>
<p style="display:block">
<span>JavaScript权威指南</span>
<a href="#">编辑</a>
</p>
<p style="display:none">
<input type="text" value="JavaScript权威指南">
<a href="#">保存</a>
<a href="#">取消</a>
</p>
</li>
<li>
<p style="display:block">
<span>JavaScript权威指南</span>
<a href="#">编辑</a>
</p>
<p style="display:none">
<input type="text" value="JavaScript权威指南">
<a href="#">保存</a>
<a href="#">取消</a>
</p>
</li>
<li>
<p style="display:block">
<span>JavaScript权威指南</span>
<a href="#">编辑</a>
</p>
<p style="display:none">
<input type="text" value="JavaScript权威指南">
<a href="#">保存</a>
<a href="#">取消</a>
</p>
</li>
<li>
<p style="display:block">
<span>JavaScript权威指南</span>
<a href="#">编辑</a>
</p>
<p style="display:none">
<input type="text" value="JavaScript权威指南">
<a href="#">保存</a>
<a href="#">取消</a>
</p>
</li>
<li>
<p style="display:block">
<span>JavaScript权威指南</span>
<a href="#">编辑</a>
</p>
<p style="display:none">
<input type="text" value="JavaScript权威指南">
<a href="#">保存</a>
<a href="#">取消</a>
</p>
</li>
</ul>
<script>
var oLi=document.getElementsByTagName("li");
var father=oLi;
for(var i=0;i<oLi.length;i++){
newEdit(oLi[i]);
}
function newEdit(father){
var oP=father.getElementsByTagName("p");
var father1=oP[0];
var father2=oP[1];
var oA= father1.getElementsByTagName("a")[0];
var oSpan= father1.getElementsByTagName("span")[0];
var oIn=father2.getElementsByTagName("input")[0];
var oA1=father2.getElementsByTagName("a");
//点击编辑
oA.onclick = function(){
oP[0].style.display="none";
oP[1].style.display="block";
}
//点击保存
oA1[0].onclick = function(){
oP[0].style.display="block";
oP[1].style.display="none";
oSpan.innerHTML="";
oSpan.innerHTML=oIn.value;
}
//点击取消
oA1[1].onclick = function(){
oP[0].style.display="block";
oP[1].style.display="none";
}
}
</script>
//实现侧边导航图的部分代码
<div id="container">
<ul class="left">
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
</ul>
<ul id="right">
<div class="rightBox">
<a href="#">a1</a>
<ul id="bottom">
<li style="background-color: white ;color:black;">a1</li>
<li>a2</li>
<li>a3</li>
<li style="border-right:none;">a4</li>
</ul>
</div>
<div class="rightBox" style="display:none;">
<a href="#">b1</a>
<ul id="bottom">
<li style="background-color: white ;color:black;">b1</li>
<li>b2</li>
<li>b3</li>
<li style="border-right:none;">b4</li>
</ul>
</div>
<div class="rightBox" style="display:none;">
<a href="#">c1</a>
<ul id="bottom">
<li style="background-color: white ;color:black;">c1</li>
<li>c2</li>
<li>c3</li>
<li style="border-right:none;">c4</li>
</ul>
</div>
<div class="rightBox" style="display:none;">
<a href="#">d1</a>
<ul id="bottom">
<li style="background-color: white ;color:black;">d1</li>
<li>d2</li>
<li>d3</li>
<li style="border-right:none;">d4</li>
</ul>
</div>
</ul>
</div>
<script>
var oUl=document.getElementById("container").getElementsByTagName("ul")[0];
var oLi=oUl.getElementsByTagName("li");
var oBox=document.getElementById("right").getElementsByTagName("div");
for(var i=0;i<oLi.length;i++){
oLi[i].index=i;
oLi[i].onmouseover = function(){
for(var j=0;j<oLi.length;j++){
oLi[j].style.backgroundColor="red";
oLi[j].style.color="white";
oBox[j].style.display="none";
}
this.style.backgroundColor="yellow";
this.style.color="black";
oBox[this.index].style.display="block";
}
}
for(var i=0;i<oBox.length;i++){
change(oBox[i]);
}
var father=oBox;
function change(father){
var oLi1=father.getElementsByTagName("li");
var oA=father.getElementsByTagName("a")[0];
for(var i=0;i<oLi1.length;i++){
oLi1[i].onmouseover = function(){
for(var j=0;j<oLi1.length;j++){
oLi1[j].style.backgroundColor="purple";
oLi1[j].style.color="white";
}
this.style.backgroundColor="white";
this.style.color="black";
oA.innerHTML=this.innerHTML;
}
}
}
</script>