js-day04 函数 作用域 变量提升 函数返回值

函数

概念

函数: 将具有独立功能的代码块整合命名的代码

作用: 减少页面代码 提高页面执行速度 页面结构更加清晰

使用:

\1. 事件处理函数: 元素.事件 = function(){}

function(){}--->函数

\2. 对象的方法:

var obj = {

abs: function(){} ---> 函数

}

\3. 封装复用

声明

函数: 由事件驱动的或者在有需要的时候被调用的代码块

注意: 函数只声明 没有任何效果

声明函数:

  1. 函数声明:

    1.1 函数:

    语法: function 函数名(){

    函数体;

    }

    1.2 调用函数:

    函数名();

    fn();
    function fn() {
        console.log(1);
    };
    // fn();
    // fn();
    // fn();
    // fn();
    // fn();
  2. 字面量声明:

    2.1 函数:

    语法: var 变量名 = function(){

    函数体;

    }

    2.2 调用函数:

    函数名();

    // fn1 is not a function: fn1不是一个函数
    // fn1();
    var fn1 = function () {
      console.log(2);
    };
    // fn1();

注意

函数名和变量名在这里是一样, 命名规范一致的

区别: 函数声明的方式调用可以在声明之前或者之后, 字面量声明的方式调用只能在声明之后;

参数

当遇到不确定的值, 就需要抽取成形参, 在调用的时候, 不同数据传进去

形参: 形式参数, 写在函数function后面的()里, 用来接收实际传递过来的数据

类似变量, 命名规范和变量一致

实参: 实际传递过来的数据, 写在函数调用的()里

arguments:存在于每一个函数中, 是实参的集合

一般形参和实参一一对应

单个参数

// 单个参数
function sum(a) {
    // 求和
    var s = 0;
    // 1 + 2 + 3 + 4 + ... + 100
    for(var i = 1; i <= a; i++){
        // s = s + i;
        s += i;
    }
    console.log(s);
};
// 调用
sum(100);
sum(1000);
sum(2000);

多个参数

多个参数: 用,隔开

// 50-80  90-100 1000-10000
// 多个参数: 用,隔开
function sum1(start, end) {
    // 求和
    var s = 0;
    // 1 + 2 + 3 + 4 + ... + 100
    for(var i = start; i <= end; i++){
        // s = s + i;
        s += i;
    }
    console.log(s);
};
sum1(1, 100);
sum1(50, 80);

arguments

如果参数个数不确定, 形参和实参干脆一个都不写, 直接使用arguments

arguments: 存在于每一个函数中, 是实参的集合

function sum2() {
    console.log(arguments);
    // 将arguments中的每个数据加起来
    var s = 0;
    for(var i = 0; i < arguments.length; i++){
        console.log(arguments[i]);
        s += arguments[i];
    }
    console.log(s);
}
sum2(3,4,5,6,7,8);
sum2(40,50,60);

形参和arguments的关系:

两者互相影响

function fn(a) {
    console.log(a, arguments);
    a = 50;
    console.log(a, arguments);
    arguments[0] = 100;
    console.log(a, arguments);
​
};
fn(30);

函数问题

  1. 形参实参不一一对应:

    形参 > 实参: 多余的形参就是undefined

    实参 > 形参: 多余的实参不能通过形参获取

    function fn(a, b) {
        console.log(a, b);
    };
    fn(10); // a = 10 b = undefined
    fn(10, 20, 30); // a = 10 b = 20
  2. 函数重名:

    函数名重名: 后面的覆盖前面的

    函数和变量名重名: 变量覆盖函数

    function a() {
        console.log('a');
    }
    function a() {
        console.log('a1');
    }
    ​
    a(); // a1
    ​
    ​
    var b = 30;
    function b() {
        console.log('b');
    }
    // b(); // b is not a function
  3. 函数封装

    \1. 声明空函数

    \2. 实现单个效果

    \3. 调用

    \4. 抽参

    \5. 传参: 把谁抽出来 把谁传进去

    function getOdd(a) {
        // 0--10
        for(var i = 0; i <= a; i++){
            // 偶数: 被2整除 取余等于0
            if(i % 2 == 0){
                console.log(i);
            }
        }
    }
    
    getOdd(10);
    getOdd(66);
    getOdd(100);
    

参数的数据类型

所有数据类型都可以做为参数

一般不用null和undefined作为参数

由于null好undefined不具有实际意义 所以一般不使用

function getType(a) {
    console.log(a, typeof a);
}
getType(10);
getType('中公');
getType(true);
getType(null);
getType(undefined);
var m = {a: 1};
getType(m);
getType([1,2,3,4]);

function fn() {
    console.log(1);
}
getType(fn);

作用域

作用: 读(获取)、写(设置)

域: 区域

作用域: 变量和函数被读写的区域

es5中 作用域通过函数来划分, 又叫做函数作用域

全局作用域: script标签下

全局变量、全局函数, 可以在整个js中被读写

局部作用域: function的{}里

在局部作用域中, 用var\function声明的变量和函数, 叫做局部变量、局部函数, 只在当前作用域起作用, 如果出了{} 会被销毁

// 全局作用域
var n = 10; // 全局变量
function fn() { // 全局函数
    // 局部作用域
    console.log(n); // 10
    var z = 1;
    console.log(z); // 1
}
fn();
console.log(z); // 报错

作用域链

作用域链: js的一种查找机制, 决定了变量和函数向上一级作用域查找的过程

查找过程: 先找自身作用域, 如果自身作用域有,直接返回, 如果自身没有,往上一级作用域查找, 直到到全局作用域,如果全局作用域也没有,报错: is not defined;

var n = 10; // 全局变量
function fn() {
    // 局部作用域
    var z = 20; // 局部变量
    console.log(n, z);  
}
fn();

变量提升

js在解析代码的时候, 不是按照单纯的从上到下的顺序来执行

至少会执行两步:

\1. 预解析: 找var、function, 将var声明的变量的声明提到最前, function声明的函数整个存储在内存中

\2. 逐行解析: 从上到下的顺序一行行执行代码

函数的形参在函数被调用的第一行代码优先执行, 形参接收实参, 执行函数体

函数每调用形成一个新的局部作用域, 代码的解析过程遵循预解析过程

var

console.log(a); // undefined
var a = 10;
/* 
    解析过程:
        var a;
        console.log(a);
        a = 10;
*/

function

// function
function sum() {
    console.log('函数1');
}
console.log(sum);

function sum() {
    console.log('函数2');
};
console.log(sum);
/* 
    解析过程: 
    function sum() {
        console.log('函数1');
    }
    function sum() {
        console.log('函数2');
    };
    console.log(sum); 函数2
    console.log(sum); 函数2
*/

var和function

// var function 函数声明 字面量声明的区别
var fn = 'abc';
function fn() {
    console.log(1);
}
console.log(fn);
/* 
    解析过程:
        var fn;
        function fn() {
            console.log(1);
        }
        fn = 'abc';
        console.log(fn); abc
*/

形参

// 传参
// 函数的形参在函数被调用的第一行代码优先执行, 形参接收实参, 执行函数体
// 函数每调用形成一个新的局部作用域, 代码的解析过程遵循预解析过程
function fun(a) {
    console.log(a);
    var a = 30;
    console.log(a);
};
fun(10);

/* 
    解析过程:
        function fun(a) {
            console.log(a);
            var a = 30;
            console.log(a);
            解析过程:
                var a;-->声明形参 
                var a;
                a = 10; ---> 接收实参
                console.log(a); // 10
                a = 30;
                console.log(a); // 30
        };
        fun(10);
*/

函数返回值

函数在执行的时候 就像一个小黑屋 里面的数据不能直接出来 如果想要出来需要越狱

函数的返回值: 每个函数执行后都会有返回值, 默认返回值 undefined

就是函数调用的结果

接收函数的返回值: var 变量 = 函数();

想要将函数内的数据 在函数外能使用 需要将函数内的数据设置成返回值返回回来

设置函数的返回值:

函数最后: return value;

接收返回值

function a() {
    console.log(1);
}
var b = a();
console.log(b);

设置返回值

// 设置返回值
function fn() {
    var mn = 20;
    return mn;
}
var q = fn();
console.log(q);

return作用

设置函数的返回值: 函数最后: return value;

return: 结束函数 return后面的代码不执行

function fn1() {
    console.log(1);
    return 'abc';
    // 不执行
    console.log(2);
}
var m = fn1();
console.log(m); // 'abc'

返回多个

return设置返回值的时候 一次只能返回一个数据 如果用,返回多个, 只会返回最后一个;

如果想要返回多个数据, 建议 数组 或者 对象, 更推荐用对象

function fn2() {
    // return 10, 20, 30;
    // return [10, 20, 30];
    return {
        a: 10,
        b: 20,
        c: 30
    };
}
var mn = fn2();
console.log(mn);

使用情况:

\1. 封装函数 函数的最后去到的是一个数据

\2. 操作的对象 返回回来

\3. 函数内的数据 要在 函数外面用到的时候

返回值数据类型

返回值的数据类型可以是一切数据类型

function rType() {
    return function () {
        console.log(90);
    };
    return {a: 1, b:2};
    return [1,2,3,4];
    return null;
    return true;
    return 30;
    return 'abc';
}
var a = rType();
console.log(a);

封装步骤

\1. 实现单个效果

\2. 声明空函数

\3. 单个效果放在空函数里

\4. 调用

\5. 分析不确定的项, 抽取参数

\6. 传参

\7. 设置返回值

\8. 接收返回值

function getMax(data) {
    // 1. 假设最大值
    var max = data[0];
    // 2. 用这个值和数组的每一个值进行比较
    for (var i = 1; i < data.length; i++) {
        // 如果比假设值大
        if (max < data[i]) {
            max = data[i];
        }
    }
    // console.log(max);
    return max;
}
var m = getMax(arr);
console.log(m);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值