js语言基础练习(二)---------------函数的基础知识

函数概述、参数、返回值、函数名函数体和函数加载问题、函数声明、变量和作用域、隐式全局变量、变量声明提升。



1。函数的定义和使用

函数 ,具有一定功能的代码块 可以重复执行的代码块

函数不调用不执行  执行方法 fn()

函数定义 function fn(){}

预解析  function 和变量

函数调用可以在函数定义之前

<!DOCTYPE html>
<html>
<head>
    <title>函数的定义和使用</title>
</head>
<body>
<script type="text/javascript">

    fn_name();

    function fn_name(){
        alert(1);
    }
    // 定义函数

    function getSum(){
        var sum = 0;
        for (var i=1;i<=100;i++){
            sum+=i;
        }
        alert(sum);
    }

    fn1();
    // 会输出1

    function fn1(){
        alert(1+1);
    }

    function fn1(){
        alert(1);
    }

    // a,b占位置用的,形参,形式上参与运算的值
    function fn2(a,b){
        alert(a+b);
    }

    fn2(4,4);
    // 4,4实参,实际上参与运算的值
    fn2(1,2);

    fn3();
    function fn3(a,b){
        alert(a+b);
        // NaN 

        alert(a);
        alert(b);
        // undefined,未定义,未赋值

        document.getElementById(a).title=‘1‘;
        // 未赋值,又进行强制操作,报错
    }

</script>

</body>
</html>

2.参数

参数 返回值 函数两大组成部分

函数的组成部分1:参数2返回值3功能

参数

需求1   1+1=?   Alert(1+1)

需求2    2+2=?   Alert(2+2)

需求3    4+4=?   Alert(4+4)

需求随时会改变,

可能修改运算的值而不是功能,可以设置参数,解决问题。

形参 形式上参与运算的值,占位置

实参 实际上参与运算的值

实参想参与运算必须要有形参占位置。

参数:增加函数功能性 如1+1  -》  a+b 功能强大

程序员交互性

参数可拓展性

// a,b占位置用的,形参,形式上参与运算的值

function fn2(a,b){

alert(a+b);

}

fn2(4,4);

// 4,4实参,实际上参与运算的值

函数名相同,后面的函数会覆盖前面的函数。函数名不能相同

3参数个数问题

如果形参个数与实参个数不匹配

一般情况下,不会让形参和实参不匹配

  1. 形参=实参  正常执行
  2. 实参》形参  正常执行,多余的实参无意义,函数不使用
  3. 实参《形参  看程序具体内容是否报错 NaN,undefined,报错

未给定实参,undefined

本身没有赋值,又对其进行强制操作,报错

fn3();

function fn3(a,b){

alert(a+b);

// NaN

alert(a);

alert(b);

// undefined,未定义,未赋值

document.getElementById(a).title=‘1‘;

// 未赋值,又进行强制操作,报错

}

Js中没有方法重载,函数名相同(无关形参个数),后面的会覆盖前面的函数。

比如fn(a,b)

fn(a,b,c)

4.

  1. 返回值

什么是返回值:执行完毕函数以后,我们能给其他变量赋值。

把函数的值赋值给外面,使用return,否则返回值是undefined

返回值的作用:一般来说,函数通过运算出来的数都是一个半成品,需要二次加工,所有不能直接结束,需要在函数外部二次加工。

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>
    //函数的组成分为:      1.参数。    2.返回值。    3.功能。

    //什么是返回值:执行完毕函数以后,我们能给其他变量赋值。
    //返回值干什么用的呢?一般来讲,函数通过运算出来的数都是一个半成品,需要二次加工。

    // 系统自带的函数,confirm等的返回值
   var bool1 = confirm("我们结婚吧?");
   console.log(bool1);
      // false,返回值是布尔值

   var bool2 = alert("我们结婚吧?");
   console.log(bool2);
        // undefined,返回值是undefined

   var bool3 = prompt("请输入:");
   console.log(bool3);
   // 返回值输入什么就是什么

    var aaa = fn();
    console.log(aaa);
    function fn(){
        var bbb = 111;
        //如果我们想把函数内部的值赋值为外部,必须使用return;
        //如果没有return或者只有return没有值,那么返回值都是undefined。
        return bbb;
    }

</script>
</body>
</html>

练习1:返回值必须执行函数才能得到,return可以退出函数

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <script>
        //函数的返回值必须要执行函数才能得到。

       //求和:
       var num = getSum()+1+1+1;
       alert(num);

       function getSum(){
           var sum = 0;
           for(var i=1;i<=100;i++){
               sum+=i;
           }
           return sum;
       }

        //需求:1+1=2;拓展这个算式
       var aaa = fn(1,1);
       alert(aaa);
       // 或者
       alert(fn(2,2));

       function fn(a,b){
           //规则中有几个变化的值,我们就定义几个变量。
           var sum = a+b;
           //外部要用哪个值,我们就返回哪个值。
           return sum;
       }

       demo();
       function demo(){
           console.log(1);
           console.log(2);
            // return可以切断函数。 后面的所有代码不再执行
            // break跳出这个循环。  continue跳出本次循环进入下一循环。
           return;
           console.log(3);
           console.log(4);
       }

    </script>
</body>
</html>

练习二:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>

    //(参数和返回值)
    //求圆的周长(long=2*pi*r)
   var long1 = getLong(0.5);
   console.log(long1);
   console.log(getLong(1));
   function getLong(r){
        // 通俗版
       var pi = 3.141592653;
       var l = 2*pi*r;
       return l;
   }

    //求圆的和面积(area = pi*r*r)
   var area1 = getArea(1);
   console.log(area1);
   function getArea(r){
       //通俗版
//        var pi = 3.14;
//        var a = pi*r*r;
//        return a;
       //精简版
//        var pi = Math.PI;
//        var a = pi*Math.pow(r,2);
//        return a;
       //最终版
       return Math.PI*Math.pow(r,2);
   }

    //求2个数中的最大值

   console.log(getMax(1,2));
   function getMax(num1,num2){
//        if(num1>num2){
//            return num1;
//        }else{
//            return num2;
//        }
       //return是可以切断函数的。
//        if(num1>num2){
//            return num1;
//        }
//        return num2;
       //三元运算
       return num1>num2?num1:num2;
   }

    //求3个数中的最大值
   console.log(getMaxThree(-1,0,3));
   function getMaxThree(a,b,c){
//        var d = a>b?a:b;
//        return d>c?d:c;
       //精简版
       return (a>b?a:b)>c?(a>b?a:b):c;
       //判断a和b
//        if(a>b){
//            //如果a大判断a和c
//            if(a>c){
//                return a;
//            }else{
//                return c;
//            }
//        }else{
//            //如果b打,判断b和c
//            if(b>c){
//                return b;
//            }else{
//                return c;
//            }
//        }
   }

    //求一组数中的最大值
   var arr = [-3,-2,-1,0,1,2,3];
   var maxValue = getArrMax(arr);
   console.log(maxValue);
   console.log(getArrMax(arr));

   function getArrMax(array){
       //用的必须是形参的数组中的第一项。
       var max = array[0];
       for(var i=1;i<array.length;i++){
           if(array[i]>max){
               max = array[i];
           }
       }
       return max;
   }

    //求一组数中的最小值
       var arr = [-3,-2,-1,0,1,2,3];
       var minValue = getArrMin(arr);
       console.log(minValue);
       console.log(getArrMin(arr));

   function getArrMin(aaa){
       //把数组中的第一位默认为,最小值。
       var min = aaa[0];
       for(var i=1;i<aaa.length;i++){
           //判断数组中的每一项,如果下雨min,那么把他赋值给min
           if(aaa[i]<min){
               min=aaa[i];
           }
       }
       //书写位置要注意,一定是这个for循环执行完毕之后再返回
       return min;
   }

    //翻转数组,返回一个新数组
    //用两种方法做,第一种创建心数组。第二种直接修改原数组。
   var arr1 = [1,2,3];
   var arr2 = reverse1(arr1);
   console.log(arr2);
   console.log(reverse1(arr1));
   //定义一个新数组,把老数组中的元素反向添加到新数组中
   function reverse1(array){
       var newArr = [];
       for(var i=array.length-1;i>=0;i--){
           newArr[newArr.length] = array[i];
       }
       return newArr;
   }

   var arr = [1,2,3];
   console.log(arr);
//    console.log(reverse2(arr));
   reverse2(arr);
   console.log(arr);
   //修改或者说翻转原数组,此方法没有返回值,所以只能打印原数组。
   function reverse2(array){
       for(var i=0;i<array.length/2;i++){
           var temp = array[i];
           array[i] = array[array.length-1-i];
           array[array.length-1-i] = temp;
       }
       return array;   //Array对象中的方法返回了一个数组。
   }

    //对数组排序,从小到大

//    var arr = [2,1,3,4];
    var arr = [4,3,2,1];
    console.log(bubble(arr));

    function bubble(array){
        //外循环控制轮数(元素-1)
        for(var i=0;i<array.length-1;i++){
            //开闭原则(标志,标识,旗帜)
            var flag = true;
            //内循环控制次数(元素-1)
            for(var j=0;j<array.length-1-i;j++){
                //判断符合标准就交换位置
                if(array[j]>array[j+1]){
                    var temp = array[j];
                    array[j] = array[j+1];
                    array[j+1] = temp;
                    flag = false;
                }
            }
            if(flag){
                //此情况在数组是极限从大到小排列下,会出现问题。每一轮flag都是false,最终无返回值。
//                return array;
                break;
            }
        }
        //有了return执行完毕方法后,就可以用变量接收返回值!
        return array;
    }

</script>
</body>
</html>

练习3:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>
//    求阶乘
   console.log(getJC(10));

   function getJC(num){
       var sumJC = 1;
       for(var i=1;i<=num;i++){
           sumJC *= i;
       }
       return sumJC;
   }

//    求1!+2!+3!+....+n!(函数嵌套)
    //求阶乘的和

   console.log(getSumJC(4));

   function getSumJC(number){
       var sum = 0;
       for(var i=1;i<=number;i++){
           sum += getJC(i);//求阶乘
       }
       return sum;
   }

//    判断一个数是否是素数(质数)
    //思路:除了自身和1以外,不能被其他数整除。
    //注意点:
    //1.必须用for循环实现
    //2.判断是否是素数,所以她的返回值应该是true或者false。
    //3.如果num%i===0了,那么一定不是素数。只有出了1和自身以外所有的数都不能整除,那么才能说她是素数。

    console.log(isPrime(3));

//    function isPrime(num){
//        //除了自身和1以外,不能被其他数整除。
//        for(var i=2;i<num;i++){
//            if(num%i===0){
//                return false;
//            }
//        }
//        return true;
//    }

    //拓展1(了解)
//    function isPrime(num){
//        //开闭原则
//        var bool = true;
//        //除了自身和1以外,不能被其他数整除。
//        for(var i=2;i<num;i++){
//            if(num%i===0){
//                bool = false;
//            }
//        }
//        return bool;
//    }

    //拓展2
    function isPrime(num){
        //除了自身和1以外,不能被其他数整除。
        for(var i=2;i<=num/2;i++){
            if(num%i===0){
                return false;
            }
        }
        return true;
    }

    //拓展3
//    function isPrime(num){
//        //除了自身和1以外,不能被其他数整除。
//        //判断一个数是不是指数,只需要判断到他的平方根,超过平方根在判断,无意义。
//        //因为一个数是由两个数相称得到的,一个变大,另外一个必然变小,那么判断到这个数的平方根就已经是极限了,不必超过平方根
//        for(var i=2;i<=Math.sqrt(num);i++){
//            if(num%i===0){
//                return false;
//            }
//        }
//        return true;
//    }

</script>
</body>
</html>

5.函数名、函数体、函数加载

函数名,就等于整个函数。执行函数,就等于函数的功能+返回值。 js加载的时候只加载函数名,不加载函数体

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>
    //函数名,就等于整个函数。
    //执行函数,就等于函数的功能+返回值;
    // js加载的时候只加载函数名,不加载函数体

    //打印函数名,就等于打印整个函数。
    console.log(fn);
    //打印执行函数,就等于打印函数的返回值。
    console.log(fn());  //函数中包函数,先执行里面,后执行外面。

    function fn(){
        var arr = [1,3,3];
    }

</script>
</body>
</html>

6.函数的定义

三种定义方法

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>

//    //第一种定义方法最强大,定义完毕后,在哪里使用都可以,无位置限制。
//    fn1();
//    //后两种定义方法是有局限性的。(使用函数必须在定义函数之后)
//    fn2();
//    fn3();

    //第一种
    function fn1(){
        console.log("我是第一种定义方法!");
    }

    //第二种(匿名函数),函数不会被提前,使用必须在定义之后
    var fn2 = function (){
        console.log("我是第二种定义方法!");
    }

    //第三种
    var fn3 = new Function("console.log(‘我是第三种定义方法!‘)");

//    fn1();
//    fn2();
//    fn3();

</script>
</body>
</html>

7.变量和作用域

局部变量:只有局部能够访问到的变量

全局变量:在哪里都能访问的变量

隐式全局变量

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

<script>

    //变量问题:根据作用范围,变量可以分为局部变量和全局变量。

    //局部变量:只有局部能够访问的变量。存在的时间比较短,执行完函数之后会被回收。
        //函数内部用var定义的变量。
    //全局变量:在哪里都能访问到的变量。
        //函数外部或者进入javascript之后立即定义的变量和函数内部不带有var的变量。

   var num3 = 333;
//全局变量

//    //函数加载的时候,只加载函数名,不加载函数体。
   function fn(){
       //局部变量,
       var num1 = 111;
       //全局变量(成员变量)
       num2 = 222;

       console.log(num3);
   }
//
   fn();
//    console.log(num1);  访问不到,因为num1是局部变量
   console.log(num2);
   // 执行fn()之后num2才能访问到,因为函数加载时候只加载函数名,不加载函数体
   console.log(num3);

//    //块级作用域,js中没有。
//    {
//        var aaa = 1;
//    }

// 作用域指的是作用范围

    //隐式全局变量
    function fn(){
        //b和c都是隐式全局变量
        var a = b = c = 1;
        //e和f都是隐式全局变量(分号相当于换行)
        var d = 1;e =2;f=3;
        //g和i都不是隐式全局变量 ,g,h,i全是局部变量
        // ,相当于共用一个var
        var g = 1,h= 2,i=3;
    }

    fn();
    console.log(b);
    console.log(c);
    console.log(e);
    console.log(f);
//    console.log(a);
//    console.log(h);
//    console.log(i);

</script>
</body>
</html>

8.变量声明提升和预解析

预解析:js的解析器在页面加载的时候,首先检查页面上的语法错误。把变量声明提升起来。
变量值提升变量名,不提升变量值。而用function直接定义的方法是整体提升。
1.查看语法错误。
2.变量声明提升和函数整体提升(变量声明提升的时候,只提升变量名,不提升变量值)
3.函数范围内,照样适用。

函数就近原则

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>

<script>

    // console.log(aaa);报错

    // console.log(aaa);
    // var aaa;  undefined 预解析

    // console.log(aaa);
    // var aaa=111;  undefined 预解析,但是变量值提升变量名,不提升变量值

    var aaa;
    console.log(aaa);
    aaa = 111;
    fn();

// 形参bbb相当于局部变量
    function fn(bbb){
        //
        //函数的就近原则。局部变量能解决的不会使用全局变量。

        // console.log(a);  报错
        // var a;
        // console.log(a);  undefined

        var aaa;
        //函数的就近原则。局部变量能解决的不会使用全局变量。这里的aaa是函数内部定义的局部变量

        console.log(aaa);
        // undefined  变量声明提升在函数内部照样实用。
        aaa = 222;
    }

    function fn2(bbb){
        //两个函数中的局部变量不会相互影响。
        console.log(bbb);
    }

</script>

</body>
</html>

例子

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>

//    1、-----------------------------------

   var num = 10;
   fun();
   function fun(){
       //变量声明提升   只提升变量名,不提升变量值。var num;
       console.log(num);
       // undefined
       var num = 20;
   }
////    2、-----------------------------------
   var a = 18;
   f1();
   function f1(){
       var b=9;
       console.log(a);
       // undefined,就近原则,函数内部有a的定义,此时a是局部变量;根据变量声明提升,只提升变量名,不提升变量值。
       console.log(b);
       // 9
       var a = ‘123‘;
   }
////    3、-----------------------------------
            f2();
    console.log(cc);
    // 9    输出顺序4 cc是全局变量,故有值
    console.log(bb);
    console.log(aa);
    // 报错,aa是局部变量,函数执行结束变量已经销毁,没有定义过
    function f2(){
        var aa = bb = cc = 9;
        // bb、cc隐式全局变量
        console.log(aa);
        // 9   输出顺序1
        console.log(bb);
        // 9    输出顺序2
        console.log(cc);
        // 9    输出顺序3
    }

</script>
</body>
</html>
时间: 2024-10-28 11:13:55

js语言基础练习(二)---------------函数的基础知识的相关文章

android基础(二)Broadcast Receiver知识

1.广播的注册 (1)动态广播注册: 优点:可以灵活控制广播的注册与撤销 缺点:必须在程序启动时才能接收广播 IntentFilter :当Intent在组建之间传递时,组件想告诉android系统自己可以响应及处理那些Intent,就要用到IntentFilter类,IntentFilter对象负责过滤掉组件无法响应和处理的Intent,只将自己关心的Intent接收进来进行处理. IntentFilter.addAction():根据action设置可以通过的intent,IntentFil

java 基础(二)

java 基础(二)java 基础(二) 2016-2-1 by Damon 61. 编写多线程程序有几种实现方式 Java 5以前实现多线程有两种实现方法:一种是继承Thread类:另一种是实现Runnable接口.两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者,因为Java中的继承是单继承,一个类有一个父类,如果继承了Thread类就无法再继承其他类了,显然使用Runnable接口更为灵活. 补充:Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的

Python 基础语法(二)

Python 基础语法(二) --------------------------------------------接 Python 基础语法(一) -------------------------------------------- 2. 元组 tuple和list十分相似,但是tuple是不可变的,即不能修改tuple,元组通过圆括号中用逗号分割的项定义:支持索引和切片操作:可以使用 in 查看一个元素是否在tuple中.空元组():只含有一个元素的元组("a",) #需要加

进击Node.js基础(二)

一.一个牛逼闪闪的知识点Promise npm install bluebird 二.牛逼闪闪的Promise只需三点1.Promise是JS针对异步操作场景的解决方案 针对异步的场景,业界有很多解决方案,如回调.事件机制 Promise是一个对象,同时它也一种规范,针对异步操作约定了统一的接口,表示一个异步操作的最终结果以同步的方式来写代码,执行的操作是异步的,但是又保证程序的执行顺序是同步的. 原本是社区的一个规范的构想,被加入到ES6的语言标准里面,比如Chrom,Firefox浏览器已对

Go语言开发(二)、Go语言基础

Go语言开发(二).Go语言基础 一.Go语言程序结构 Go语言程序基本结构如下:A.包声明B.引入包C.函数D.变量E.语句 & 表达式F.注释 package main //包声明 import "fmt" //引入包 func main(){ //main函数 //打印Hello World fmt.Print("Hello World!") } 二.Go语言基础语法 1.Go语言标记 Go语言程序由多个标记组成,可以是关键字.标识符.常量.字符串.符

C++语言学习(二)——C++对C语言基础语法的扩展

C++语言学习(二)--C++对C语言基础语法的扩展 C++是基于C语言扩展发展而来的面向对象的程序设计语言,本文将主要讨论C++语言基于C语言扩展的方面. 一.实用性增强 C语言中变量的定义必须在作用域开始的位置进行定义. #include <stdio.h> int main(int argc, char *argv[]) { int i;//定义变量 int j; //使用变量 for(i = 0; i < 10; i++) { for(j = 0; j < 10; j++)

go语言基础(main函数、数据类型)

go语言基础(main函数.数据类型) 1.Go语言介绍 Go语言是云计算时代的c语言 c和c++这类语言提供了很快的执行速度,而Rudy和python这类语言则擅长快速开发.Go语言则介于两者之间,不仅提供了高性能的语言,同时也让开发更快速 优势 部署简单,可直接编译成机器码.不依赖其他库,部署就是扔一个文件上去就完成了 静态类型语言(c是静态语言.python解释性语言),但是有动态语言的感觉,静态类型的语言就是可以在编译的时候检查出来隐藏的大多数问题,动态语言的感觉就是有很多的包可以使用,

Linux多任务编程之二:fork()函数及其基础实验(转)

来源:CSDN  作者:王文松 转自Linux公社 fork()函数 在 Linux 中创建一个新进程的唯一方法是使用fork()函数.fork()函数是 Linux 系统中一个非常重要的函数,和咱们以前遇到过的函数由一些区别,因为它看起来执行一次却返回两个值,这又作何解释?不着急,慢慢看. 函数说明 fork()函数用于从已存在的一个进程中创建一个新的进程,新进程称为子进程,而原进程称为父进程.使用fork()函数得到的子进程是父进程的 一个复制品,它从父进程处继承了整个进程的地址空间,包括进

javascript语法基础-变量与函数

三 javascript语法基础-变量与函数 (一)变量的声明与运用 JavaScript中的变量与Java.C等强类型语言有很大区别,虽然在JavaScript中具有字符串.数字等数据类型. 变量申明语句的结构是var保留字加标识符,var和标识符之间用空格隔开. 赋值语句的结构是在变量和需要赋的值之间加上一个等号,例如a=1的含义是将变量a的值指定为1. 变量在定义的时候也可以同时赋值,如var a=1. PS:在变量使用前事先进行声明是个良好的编程习惯,这对将来学习Java等其他语言有帮助

C#编程总结(二)多线程基础

C#编程总结(二)多线程基础 无论您是为具有单个处理器的计算机还是为具有多个处理器的计算机进行开发,您都希望应用程序为用户提供最好的响应性能,即使应用程序当前正在完成其他工作.要使应用程序能够快速响应用户操作,同时在用户事件之间或者甚至在用户事件期间利用处理器,最强大的方式之一是使用多线程技术. 多线程:线程是程序中一个单一的顺序控制流程.在单个程序中同时运行多个线程完成不同的工作,称为多线程.如果某个线程进行一次长延迟操作, 处理器就切换到另一个线程执行.这样,多个线程的并行(并发)执行隐藏了