函数进阶
一、变量作用域
变量的作用范围
在ES5中,根据变量的作用范围不同,将变量分为:
全局变量:在整个文档中都有效(任何地方都能访问,任何地方都能修改),在函数外声明的变量都是全局变量
for (var i = 0; i < 3; i++) {//i全局变量
console.log(i);//0 //1 //2
}
console.log(i);//3
var a = 10;//全局变量
console.log(a);//10
<script>
console.log(a);//10
</script>
var a = 10;//全局变量
function show(){
console.log(a);//10
}
show();
var a = 10;//全局变量
if(true){
console.log(a);//10
}
{//代码块
var b=100;//全局变量
console.log(b);//100
}
console.log(b);//100
局部变量:在指定返回有效(函数内能访问,出了函数就访问不到)在函数内声明的变量(包括参数部分)
var a=10;//全局变量
function fn(){
var b=20;//局部变量
console.log(b);
console.log(a);//全局变量
}
console.log(b);//报错 局部变量只在函数内有效
fn();//20 10
function show(a, b) {
console.log(a, b);
}
show(10, 20);//10 20
console.log(a,b);//报错
//局部变量(包括参数部分)只在函数内有效
var a=10;//全局变量
function fn(){
console.log(a);//10
a=20;//修改了全局变量的值
console.log(a);//20
}
fn();
console.log(a);//20
var = 10;
function show(){
var a=30;//局部变量
console.log(a);//30
a=50;//修改离自己最近的变量a 局部变量
console.log(a);//50
}
console.log(a);//10 全局变量
show();
var num=5;
function fn(num){
num=10;//局部
console.log(num);//10 就近原则
}
fn(30);
console.log(num);//5 全局变量
推荐使用局部变量:全局变量生命周期较长,局部变量满足快速释放的原则
全局变量:只要页面不关闭,全局变量就一直占用内存;
局部变量:函数被调用后变量销毁,释放内存。
作用域链:指变量的查找机制,层层向外寻找机制,当找到离自己最近的一个停止查找。
二、预解析
浏览器在执行js代码的时候,有一个预解析的过程。浏览器将js代码的执行分为两步(实际是一个很复杂的过程,这里简化为两步):
1.在全局中找一些东西(var function)
2.执行代码
会将var定义的变量和function定义的函数预解析,变量提升和函数会被提升(变量会被存储,函数定义也会被存储,注意:并没有执行)
var a;
console.log(a);//undefined
a=10;
//上下代码等价 变量提升
console.log(a);//undefined
var a = 10;
var a = 100;
function show(){
console.log(a);//undefined
var a=5;
console.log(a);//5
}
show();
//上下代码等价 变量提升
var a = 100;
function show(){
var a;
console.log(a);//undefined
a=5;
console.log(a);//5
}
show();
fn();
function fn() {
console.log(111);//111
}
fn();//报错
var fn=function(){
console.log(111);
};
//上下代码等价 变量提升
var fn;
fn();//报错
fn=function(){
console.log(111);
};
var a = 'malatang';//全局变量
function fn() {
if (typeof a == 'string') {
a = '张亮';
console.log(a);
} else {
var a = '杨国福';
console.log(a);
}
}
fn();
//等价于以下代码
var a = 'malatang';//全局变量
function fn() {
var a;//局部
if (typeof a == 'string') {
a = '张亮';
console.log(a);
} else {
a = '杨国福';
console.log(a);
}
}
fn();
三、函数的返回值及封装
函数的返回值
return 表达式;
return语句有两个功能:
1.返回结果 注意:只能返回一个结果
2.结束函数
使用 return 关键字。
注意:
1.函数通过关键字return 返回函数中的内容
// 用函数实现求圆的面积和长方形的面积的和
//计算圆的面积
function fn1(r) {
var area = Math.PI * r * r;
return area;//返回运算结果
}
//计算长方形的面积
function fn2(w, h) {
return w * h;//返回运算结果
}
var a1 = fn1(10);//将函数的执行结果保存在变量中
var a2 = fn2(20, 5);//将函数的执行结果保存在变量中
console.log(a1 + a2);
2.return 一次只能返回一个值
function addZ(num) {
if (num < 10) {
return '0' + num;//返回结果,结束函数
}
return num;
}
var a = addZ(9);
3.函数中只要遇到return,函数就会结束
function add(a, b, c) {
if (a == undefined) {
return 0;
} else if (b == undefined) {
return a * a;
} else if (c == undefined) {
return a * b;
}
return a * b * c;
}
console.log(add());//0
console.log(add(5));//25
console.log(add(5, 10));//50
console.log(add(2, 3, 4));//24
4.函数没有返回值,默认结果为undefined
function fn(){
var a=10*10;
console.log(a);
}
var num=fn();
console.log(num);
//undefined 函数没有返回值
5.函数返回值可以返回任意类型: 基本类型、数组、对象、函数…
返回undefined
function fn(){
return 'hello';//返回结果 结束函数
console.log('world');//不会执行
}
fn();
返回null
function fn(){
return null;
}
var a=fn();
console.log(a);//null
返回字符串
function fn(){
return 'hello';
}
var a=fn();
console.log(a);//hello
返回NaN
function fn(){
return 1/'a';
}
var a=fn();
console.log(a);//NaN
返回数值型
function fn(){
return 0;
}
var a=fn();
console.log(a);//0
返回布尔型
function fn(){
return true;
}
var a=fn();
console.log(a);//true
返回数组
function fn(a, b) {
return [a * a, b * b];
}
var arr=fn(10,20);
console.log(arr);//[10,20]
返回对象
function fn(){
return {
name:'Tom',
age:20,
address:"北京路"
};
}
var obj=fn();
console.log(obj);
//{name:'Tom',age:20,address:"北京路"}
返回函数
function fn(){
return function(){
console.log('hello');
};
};
var a=fn();
console.log(a);
//f (){
// console.log('hello');
// }
a();//hello
f()();//hello
;
函数的封装
属性
修改属性:
对象.属性名=值;
获取属性值:
对象.属性名
样式:
样式设置:
对象.style.样式名=值;
获取样式的值:
对象.style.样式名 只能获取行内样式(不能获取样式表样式)
window.getComputedStyle(对象,null) 行内和样式表都能获取
获取样式兼容性写法封装
var lis = document.getElementsByTagName('li');
var box = document.getElementsByTagName('div')[0];
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function () {
// var col = window.getComputedStyle(this,null).backgroundColor;
// console.log(col,typeof col);
var col = sty(this, 'backgroundColor');
box.style.backgroundColor = col;
}
}
function sty(obj, pro) {//元素,样式
var sty = obj.style[pro];
//只能获取行内样式,否则为空字符串
if (sty == "") {//为空字符串
sty = window.getComputedStyle(obj, null)[pro];
// 行内和样式表都能获取
}
return sty;
}