js-函数的认识及应用

Posted 傻fufu的小陶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了js-函数的认识及应用相关的知识,希望对你有一定的参考价值。

函数

函数定义:(方法) => 完成某个特定功能的工具

函数封装流程:
(1) 按照功能的需要,现将完成该功能的代码写出来 (写正常功能的代码)
(2) 把完成特定功能的代码放到函数中,起一个名字
(3)把可变参数改为形式参数
(4) 确定函数的返回值 (使用了该函数/方法 你想得到什么样的结果)
(5) 通过函数调用该函数 函数名() (调用 => 启动)

关于函数的返回值
(1) 返回值一般用于执行函数执行的结果,如果不设置 默认返回undefined ()
(2) return 之后的语句不执行

关于函数的调用及其执行:
(1)每次调用函数,会执行函数中的上下文(从函数中的第一行执行到最后一行)),如果遇到return就停止了
(2) 形式参数(函数在封装过程中的假设性参数(变量) => 实际值由用户在调用方法时对应传入)
实际参数(函数在执行时真正传入的值)
形式参数和实际参数 一一对应
(3)函数内部变量的预解析
(4)函数内部代码的执行
1.function
function 函数名(参数1,参数2){
执行语句;
return返回值
}

函数分类以及创建方式

1.系统(内置)函数
alert(“hello”)提示框
isNaN 判断不是数字,获得返回值
eval() 直接尝试计算字符串表达式的值,bug多不建议使用
confirm(“确定删除我吗?”) 确认框
prompt(“请输入一个分数”) 输入框 点确认时能拿到输入框的值,点取消时得到null

var res=confirm("确定删除我吗?");
if(res){
    alert("你不爱我了")
}else{
    alert("你太明智了")
}

2.自定义函数
2.1.具名函数(声明式)
函数如果不执行,就是以字符串的形式存储在内存中(函数名也是一个变量,用来存储函数)
2.2匿名函数

//函数创建时默认是以命名函数的格式解读的,所以不能直接声明
function (a,b){//报错
    return a + b;
}

a.用变量,数组,对象,事件等保存函数(赋值式声明函数)

var fn = function(a,b){
    return a + b;
}
var btn = document.getElementById("btn");
btn.onclick = function(){
    alert("111");
}

b.回调函数

function sum(a,b,callback){//callback是一个形参,只是一个名字
    console.log(a+b);
    //求和成功以后,还想做一件事,但不确定想做什么
    //调用匿名函数function(),在function()匿名函数里规定要做的事情
    callback();//function(){alert("666");}
}//函数封装

//function(){alert("666");是sum函数调用过程中的一个实参
sum(3,4,function(){
    alert("666");
})

匿名函数的自执行

//匿名函数的自执行
//通过使用小括号()或 运算符 提升优先级,解读为匿名函数
(function (a,b){
    return a + b;
});//声明即调用
!function (a,b){
    return a + b;
}()//声明即调用

~function (a,b){
    return a + b;
}()//声明即调用

+function (a,b){
    return a + b;
}()//声明即调用

c.通过官方的方法function创建函数(一般不使用)

var fn = new Function("a","b","return a+b");
console.log(fn);

函数的嵌套

函数嵌套调用时,必须等内层函数执行完,外层函数才可以继续向后执行
如果想把函数嵌套的内层结果传递出来,外层函数必须用return 返回内层函数的结果

function fn(){
    console.log("fn开始执行");
    function a(){
        console.log("a");
        return 1;
    }
    return a();//1
}

函数的递归

如果想把函数嵌套的内层结果传递出来,外层函数必须用return 返回内层函数的结果。同函数的嵌套。
1.伪递归=>在函数结尾算出结果,再依次往回传

所谓递归,就是通过调用自己,重复执行函数中的代码段(和循环类似)

特点:先传递再回归

注意:递归要有临界值(即跳出条件),否则会陷入死循环。

  function gcd(a, b) {
            if (a % b === 0) {//临界值
                return b;
            }
            return gcd(b, a % b);
        }
        var res = gcd(18, 99);
        console.log(res);

2.依赖递归
按照规律递归(当前的值依赖于前一个或多个的结果)


作用域

即代码生效的范围,决定了变量的可访问性

全局作用域和局部作用域

变量:
全局变量(函数之外的地方都是全局作用域)
特点:可以在任何地方使用,也可以在函数中使用(前提是不存在同名的局部变量👇)
window(Global全局对象=>全局变量都存在window中)

局部变量:
(1)在函数内通过(var let const)声明的变量
(2)形式参数也是局部变量
特点:只能在函数内生效。不会影响全局变量=>局部作用域(函数作用域)
Local(函数中的对象=>局部变量都存在于Local中)
简单来说,当定义一个函数,就相当于开辟一个局部作用域的空间,当局部作用域中var定义的变量属于局部变量,这个局部变量旨在局部作用域中使用

作用域链:查找变量的路径

短路赋值

var a= b || c
如果 b 不是false,就把b的值赋予a,否则把c的值赋予a。
PS:js中以下值会被转换为false:
false、undefined、null、0、负数、NaN、""、’’。

预解析:

javascript是解释型语言,在代码执行之前会把代码先解释一遍,再执行代码

能预解析什么:【1】使用var关键声明的变量【2】声明式定义的函数

简单来说,就是在代码执行之前,告诉浏览器有一个变量可以使用,只不过变量是未赋值状态(告诉浏览器有一个函数名可以使用,函数式以地址的形式寻处在堆里面,会把地址赋值给一个变量。
console.log(num);//10
var num = 10;

预解析的无节操,哪怕if条件不执行,if里面的变量依然会被预解析,只是未赋值而已

预编译的经典面试题👇

<script>

        // 面试题1
        // console.log(v1);
        // var v1 = 100;
        // function foo() {
        //     console.log(v1);
        //     var v1 = 200;
        //     console.log(v1);
        // }
        // foo();
        // console.log(v1);

        // // 实际js接受到的代码
        // var v1;
        // function foo() {
        //     // 预编译呢
        //     var v1;
        //     console.log(v1);
        //     v1 = 200;
        //     console.log(v1);
        // }


        // console.log(v1);   // undefined
        // v1 = 100;
        // foo();        // undefined   // 200
        // console.log(v1);  // 100


        // 面试题2
        // console.log(add(1, 2));

        // function add(x, y) {
        //     return x + y;
        // }

        // console.log(add)

        // var add = 10;

        // console.log(add);

        // console.log(add(1, 2))

        // js接受到的代码
        var add;
        function add(x, y) {
            return x + y;
        }
        console.log(add(1, 2));     // 3 
        console.log(add)    // 函数  打印的是函数
        add = 10;
        console.log(add);   // 变回了数字   10
        console.log(add(1, 2))  // 报错 add is not a function

    </script>

arguements伪数组

是函数的内置参数(所有函数都有),用来存放函数在调用过程中传递的实际参数(集合)
一般用于参数不定项目(一个或多个)

arguements特性:
1.有length属性,表长度(实际参数的个数)
2.对应下标取值和赋值,下标最大值为length-1(从0开始算)

function add(){
    console.log(arguments);
    console.log(arguments.length);
    //下标取值
    console.log(arguments[3]);
    //下标赋值
    arguments[3] = 66;
    console.log(arguments);
}
add(1,2,3,4,4,5)

(3)循环遍历(通过循环取出集合中的每一个值(元素))

for (var i=0;i<arguments.length;i++){
    console.log(arguments[i]);
}
//案例(求arguements集合里的实际参数的和)👇
 function add() {
            console.log(arguments);
            var sum = 0;
            for (var i = 0; i < arguments.length; i++) {
                sum += arguments[i];
            }
            return sum;
        }
        var result = add(1, 2, 3, 4, 4, 5);
        console.log(result);//19

以上是关于js-函数的认识及应用的主要内容,如果未能解决你的问题,请参考以下文章

关于JS递归函数细化认识及实用实例

模块化的书写及应用的认识

JS 作用域及作用域链

JS 作用域及作用域链

js之认识闭包

js_字符串数组常用方法及应用