函数
1.函数
函数的概念:函数是由事件驱动的或当他被调用时可重复使用的代码块
使用场景:
- 作为事件处理函数 标签.事件 = function(){}
- 函数封装
- 代码复用
1.1函数的声明和使用
-
普通声明方式
- 声明:function 函数名(){代码块}
- 调用:函数名()
-
表达式声明
- 声明:var 变量 = function (){ 代码块}
- 调用:变量名()
//1.普通函数声明方式 function study(){ console.log("沉迷学习,日渐消瘦"); } //函数没有调用不会执行 console.log(study); //d打印函数 study(); study(); study(); //可重复使用代码块 //2.表达式声明 var s = function (){ console.log("沉迷游戏,无法自拔"); } s();
1.2 函数参数
1.2.1 参数
如果函数中出现不确定的值,就可以作为参数
形参(形式参数): function 函数名(参数1,参数2)
实参(实际参数): 函数名(10)
//单个参数
function sum(n){//var n;
var s = 0;
for(var i = 1;i<=n;i++){
s += i;
}
console.log(s);
}
//调用
sum(100);
sum(200);
//多个参数,多个参数之间用,隔开
//声明一个函数,计算两个数和
function add(a,b){
console.log(a+b);
}
add(10,20); //30
//声明一个函数,计算所有用户输入的和
//arguments:实参集合,如果参数个数确定不了,就不写形参,直接使用arguments
function s(){
console.log(arguments,arguments.length); //实参集合
console.log(arguments[0]); //10
var sum = 0;
for(var i = 0;i<arguments.length;i++){
sum += arguments[iR
console.log(sum);
}
s(10,20);
s(10,20,30);
s(10,20,30,40);
1.2.2 参数类型
所有的js数据类型都能作为函数参数
//1.函数做为参数
function sayhello(){
console.log("你好呀,你吃饭了吗?");
}
function see(f){//var f = function sayhello(){console.log("你好呀,你吃饭了吗?");}
f();
}
see(sayhello);
1.3 函数注意点
//形参个数与实参个数不一致的时候,一一对应,没有被赋值的就是undefined,多了的不管
function sum(a,b){//var a,b;
console.log(a+b);
}
sum(10); //NaN 实参给形参赋值的时候是一一对应 a=10,b=undefined : NaN
sum(10,20);//30 a = 10,b=20
sum(10,20,30);//30 a = 10,b=20
//同名会覆盖(函数和函数,函数和变量),后面会覆盖前面
function add(x,y){
console.log(x+y);
}
function add(x,y){
console.log(x*y);
}
// var add = 10;
// console.log(add);
add(10,20); //200 add is not a function
//arguments和形参是一个东西,一改全改
function fun(a){
arguments[0] = 100;
console.log(a); //100
a = 200;
console.log(arguments[0]);
}
fun(10);
//普通函数中this的指向----window
function fu(){
console.log(this);
}
fu();
1.4 作用域和预解析
1.4.1 作用域
作用域:变量或函数的有效使用范围(全局作用和局部作用域)
-
全局变量/函数
全局变量/函数: 在函数外声明的变量/函数,叫全局变量/函数,可以在当前页面内任意地方使用和修改,会一直存储在内存,知道页面关闭
//全局变量 var x = 10; console.log(x); //10; x = 30; console.log(x); //30 function fun(){ console.log(x);//30 x = 100; } fun(); console.log(x); //100
-
局部变量/函数
在函数内声明的变量/函数,叫局部变量/函数,只能在函数内部使用,出了函数的{}就销毁了
//局部变量
function fun2(m){//var m;
var y = 1;
console.log(y);
}
fun2(10);
//console.log(y);// y is not defined 没有声明变量y
//console.log(m);
-
作用域链:
js中的一种查找机制,先查找自己作用域范围内是否存在,有就使用自己的,没有就往上一级作用域查找,依次往上查找,一直找到全局,全局没有报错,is not defined
var n = 10; function fun3(){ var n = 40; function inner(){ // var n = 100; console.log(n); } inner(); } fun3();
2.4.2预解析
浏览器在解析js的过程中,至少有两步,预解析,逐行执行
-
预解析:找一些东西,找var function,把var 和function的声明提到最前面, 所有作用域代码在执行之前都会进行预解析
- 找var:提前声明一下变量,存储在内存中,如果变量同名声明一次
- function:提前声明函数,存储在内存中,如果同名会多次声明
-
逐行执行:声明已经提到了最前面,逐行执行的时候将不会再声明
//找var console.log(a);//undefined var a = 10; console.log(a);//10 var a = 20; console.log(a);//20
//找function console.log(sum); //函数2 function sum(){ console.log("函数1"); } console.log(sum); //函数2 function sum(){ console.log("函数2"); } console.log(sum);//函数2
-
普通函数声明方式和表达式声明方式的区别?
add(); //和 function add(){ console.log("和"); } // addd(); 预解析的时候,变量只声明,不赋值,undefined addd is not a function var addd = function(){ console.log("addd"); }
-
笔试题
console.log(c);//函数2 var c = 10; function c(){ console.log("函数1"); } console.log(c); //10 var c = 20; function c(){ console.log("函数2"); } console.log(c); //20 //c(); //c is not a function //局部作用域预解析 function sum(){ console.log(a);//undefined var a = 10; } sum(); var x = 10; function fun1(){ console.log(x); //undefined var x = 20; } fun1(); function fun2(a){//var a,函数执行的第一步,就是给参数赋值 a =100 console.log(a);//100 var a = 20; console.log(a);//20 } fun2(100);
1.5 函数返回值
1.5.1 return
需要用到函数内部的变量或者是函数的时候需要使用return 进行数据返回
函数返回值:return 可以将函数内部的变量或函数返回到函数外面去使用
语法:return 需要返回的内容
特点:return 一次只能返回一个,写多个最后只会返回最后一个
函数中只要遇到return函数就结束了
//return 一次只能返回一个,写多个最后只会返回最后一个
function sum(a,b){
var c1 = a+b;
var c2 = a*b;
var c3 = a/b;
return [c1,c2,c3];
}
//函数调用表达式的结果就是函数的返回值
var s = sum(10,20);
console.log(s);
//函数中只要遇到return函数就结束了
function ss(){
return 1; //函数中只要遇到return函数就结束,后面的代码不会执行
console.log("js难吗?");
}
ss();
function add(){
s = 0;
for(var i = 1;i<=100;i++){
s += i; //s+=1
return s;//函数中只要遇到return函数就结束
}
}
var a = add();
console.log(a);//1
1.5.2 获取元素样式
//1.只能获取行间样式
var w = oDiv.style.width;
//console.log(w);
//2.获取非行间样式
//标准浏览器:getComputedStyle(标签).属性名 ie8-不兼容
var w1 = getComputedStyle(oDiv).width;
console.log(w1); //200px
//IE浏览器:标签.currentStyle.属性名
var w1 = oDiv.currentStyle.width;
console.log(w1);
//3.兼容,拿其中一个方法作为判断条件 xx.xx, 如果是直接调用的就使用window.xx
//alert(window.getComputedStyle);
//alert(oDiv.currentStyle)
if(oDiv.currentStyle){
var w1 = oDiv.currentStyle.width;
}else{
var w1 = getComputedStyle(oDiv).width;
}
console.log(w1);
封装
function getStyle(elem,attr) {//标签:elem 属性:attribute
if (window.getComputedStyle) {
//标准
var w = getComputedStyle(elem)[attr];
} else {
//ie
var w = elem.currentStyle[attr];
}
return w;
}
代码复用
/*
如果功能一个,结构一致,代码复用
1.先实现一个,里面的元素都需要通过父元素获取
2.把主要代码放入函数中,把父元素作为参数
*/
var oP = document.getElementsByTagName("p");
car(oP[0])
car(oP[1])
car(oP[2])
function car(parent) {
//1.获取元素
var oPrice = parent.getElementsByTagName("span")[0]
var oCount = parent.getElementsByTagName("input")[0]
var oSum = parent.getElementsByTagName("span")[1]
//2.点击input,计算小计 = 价格*数量
oCount.onclick = function () {
oSum.innerText = (parseFloat(oPrice.innerText) * Number(oCount.value)).toFixed(2) + "元";
}
}