美文网首页程序员
JavaScript入门笔记3

JavaScript入门笔记3

作者: David_Rao | 来源:发表于2019-11-16 22:43 被阅读0次

    写在前面

    本文是我通过在网易云课堂上学习 叶建华 老师的 撩课-零基础玩转JavaScript 视频教程,整理、精炼其配套笔记总结而来的。附上视频教程地址:

    https://study.163.com/course/courseMain.htm?courseId=1005973001

    以下是我的所有js入门笔记
    JavaScript入门笔记1:https://www.jianshu.com/p/ab044eb35c56
    JavaScript入门笔记2:https://www.jianshu.com/p/348805d50b77
    JavaScript入门笔记3:https://www.jianshu.com/p/2146931d6706
    JavaScript入门笔记4:https://www.jianshu.com/p/e95f00b53343
    JavaScript入门笔记5:https://www.jianshu.com/p/97a241434881
    JavaScript入门笔记6:https://www.jianshu.com/p/fc091ce8924e
    JavaScript入门笔记7:https://www.jianshu.com/p/ea33bfb83da1

    本章节内容
    1、函数
    ---1.1、 定义
    ---1.2、常见声明方式
    ---1.3、arguments对象
    ---1.4、return
    ---1.5、对比“函数式声明方式”和“函数表达式声明方式”
    ---1.6、匿名函数
    ---1.7、函数是一种数据类型
    ---1.8、回调函数
    ---1.9、变量的作用域

    1、函数

    1.1、 定义

    1. 函数就是可以重复执行的完成特定功能的一段代码块
    2. 函数也是一个对象
    3. 使用typeof检查一个函数对象时,会返回function

    1.2、常见声明方式

    (1)函数声明方式

    // num1,num2是形式参数
    function add(num1,num2){
          return num1+num2;
      }
    

    (2) 函数表达式声明方式

    // num1,num2是形式参数
    var add= function(num1,num2){
        return num1+num2;
    };
    

    (3)使用Function构造函数

    不推荐使用, 主要用于面向对象时理解"函数就是对象, 函数名就是指针"这一概念

    // num1,num2是形式参数
    var add = new Function('num1','num2','return num1+num2');
    

    函数调用

    var add= function(num1,num2){
        return num1+num2;
    };
    var a = 1, b = 2;
    // 调用函数,a和b是实际参数
    var result = add(a, b);
    console.log(result);  // 3
    

    函数使用注意

    1. 注意形参和实参的区别
    2. 函数的实参可以是任意的数据类型
    3. 调用函数时,解析器不会检查实参的数量, 多余实参不会被赋值, 如果实参的数量少于形参的数量,则没有对应实参的形参将是undefined

    1.3、arguments对象

    1. arguments对象仅仅属于函数。
    2. arguments是一个伪数组对象。
    3. 里面包含一个叫callee的指针,这个指针指向arguments所在的函数对象。
    4. 里面还包含传入该函数的所有实际参数。
    function sum(num1, num2){
        console.log(arguments);
    }
    sum(100, 200);
    

    arguments对象的一些应用实例

    (1)比较形参个数和实参个数是否相等

    arguments.length 返回实参个数
    函数名.length 返回形参个数

    function sum(num1, num2){
        console.log(arguments.length === sum.length);
    }
    sum(100, 200);  // true
    sum(100, 200, 300);  //false
    

    (2)arguments方便函数取出实参用于遍历运算

    function sum(){
        var value = 0;
        for(var i = 0; i < arguments.length; i++){
            value += arguments[i];
        }
        consolelog(value);
    }
    sum(10, 20, 30);
    

    1.4、return

    function getMin() {
        var minValue = arguments[0];
        for(var i = 0; i < arguments.length; i++) {
            if(arguments[i] < minValue){
                minValue = arguments[i];
            }
        }
        return minValue;
    }
    var minValue = getMin(10, 20, -30);
    console.log(minValue);  // -30
    

    1.5、对比“函数式声明方式”和“函数表达式声明方式”

    函数式声明方式

    1. JavaScript解析器首先会把当前作用域的函数声明提前到整个作用域的最前面。可以函数调用在前,函数声明在后
    2. 函数声明方式,必须紧跟在function后设置函数名。
    result = func(6, 7); 
    console.log(result);  // 13
    function func(a, b) {
        return a + b;
    }
    

    函数表达式声明方式

    1. 函数表达式声明方式,相当于先声明变量var sum = undefined,直到执行到了var sum = function()语句,sum这个函数方法才能被调用。不能函数调用在前,函数声明在后
    2. 函数表达式声明方式,不必紧跟在function后设置函数名,函数名由变量名决定。
    func(6, 7);  // 报错
    console.log(result);
    var func = function(a, b) {
        return a + b;
    }
    

    因此,
    如果函数经常使用,选择“函数声明”方式定义函数,这种方式无论在哪里定义都能先初始化该函数。
    如果函数不经常使用,或函数代码量非常庞大,选择“函数表达式声明”方式定义函数“,这种方式避免了函数初始化都需要在程序开头花费时间。

    1.6、匿名函数

    没有命名的函数

    (1)用在绑定事件的时候

    document.onclick = function () {
            alert(1);
     }
    

    (2)回调函数

    setInterval(function () {
            console.log(444);
    },1000);
    

    (3)立即执行函数

    函数定义完,立即被调用,这种函数叫做立即执行函数。立即执行函数往往只会执行一次。

    (function(num1,  num2){
        console.log("num1 = "+ num1);
        console.log("num2 = "+ num2);
    })(100, 101);
    

    这里引入了闭包的概念

    ( function(形参) )( 实参 )
    

    1.7、函数是一种数据类型

    1. 函数是一种引用数据类型,属于Object类型。
    2. "函数名"是指向对应函数体的指针(地址),"函数名()"是函数返回的结果。
    function fn() {
        return undefined;
    }
    console.log(typeof fn);  //function
    console.log(typeof fn());  //undefined
    

    1.8、回调函数

    1. 回调函数就是被函数调用的函数。
    2. 如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
    3. "函数名"就是指向对应函数体的指针(地址)
    4. 多用于递归
    function add(num1, num2){return num1 + num2;}
    function sub(num1, num2){return num1 - num2;}
    function mul(num1, num2){return num1 * num2;}
    function divide(num1, num2){return num1 / num2;}
        
    function cal(num1, num2, func) {
        return func(num1, num2);
    }
    
    var result1 = cal(10, 20, add);
    var result2 = cal(10, 20, sub);
    var result3 = cal(10, 20, mul);
    var result4 = cal(10, 20, divide);
    
    console.log(result1);  // 30
    console.log(result2);  // -10
    console.log(result3);  // 200
    console.log(result4);  // 0.5
    

    1.9、变量的作用域

    1.9.1、 作用域

    变量可以起作用的范围

    1.9.2、 全局变量,局部变量

    1. a是全局变量,从头至尾都能被认出来
    2. b是局部变量,只有在它所在的函数代码块内,它才能被认出来。
    var a = 1;
    function fn(){
        var b = 2;
        console.log("In function, a = " + a);  // a = 1
        console.log("In function, b = " + b);  // b = 2
    }
    fn();
    console.log("Out of function, a = " + a);  // a = 1
    console.log("Out of function, b = " + b);  // 报错
    

    1.9.3、 注意

    (1)不使用var声明的变量是全局变量(不推荐使用)

    // 这里的b没有用var声明,调用函数之后就创建为全局变量
    var a = 1;
    function fn(){
        b = 2;
    }
    fn();
    console.log("Out of function, a = " + a);  // a = 1
    console.log("Out of function, b = " + b);  // b = 2
    

    (2)变量退出作用域之后才会销毁,全局变量关闭网页或浏览器才会销毁

    1.9.4、块级作用域

    (1)非函数所属的大括号内并不算一个作用域,只有函数的大括号内才算一个作用域

    (2)作用域内用var声明的变量是该作用域的局部变量

    // 说明非函数的大括号内并不算一个作用域
    {var name = "David";}
    console.log(name);  // David
    
    // 说明非函数的大括号内并不算一个作用域
    var num = 5;
    if (num > 3) {
        var sum = 7;       
    }
    console.log(sum);  // 7
    

    (3)ES6之后,用let声明变量

    ES6之后,若要将非函数所属的大括号内视为一个作用域,可以用let声明变量,该变量的作用域为这个大括号内

    ES6的块级作用域
    用let命令新增了块级作用域,外层作用域无法获取到内层作用域,非常安全明了。即使外层和内层都使用相同变量名,也都互不干扰。
    https://www.cnblogs.com/guanqiweb/p/10282574.html

    (4)其它语言中变量i只能在for循环内部访问(局部变量),JS比较特殊

    for (var i = 0; i < 10; i++) {
    
     }
    console.log(i);  //10
    

    1.9.5、作用域链

    var color = "yellow";
    function getColor() {
        var anotherColor = "red";
            function swapColor() {
                var tmpColor = color;
                color = anotherColor;
                anotherColor = tmpColor;
            }
        swapColor();
    }
    getColor();
    console.log(color);  // "red"
    

    1.9.6、 预解析

    (1)概念

    1. js代码的执行是由浏览器中的js解析器来执行的
    2. js解析器执行js代码的时候,分为两个过程:预解析过程和代码执行过程。

    (2)预解析过程

    1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值
    2. 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用
    3. 先提升var,再提升function
    console.log(a);  // undefined
    var a = 10;
    console.log(a);  // 10
    

    👆相当于👇

    var a;
    console.log(a);  // undefined
    a = 10;
    console.log(a);  // 10
    
    console.log(fn); 
    //ƒ fn() {
    //    console.log('我是函数');
    //}
    function fn() {
        console.log('我是函数');
    }
    var fn = "我是变量";
    console.log(fn);  //“我是变量”
    

    👆相当于👇

    var fn;
    function fn() {
        console.log('我是函数');
    }
    fn = "我是变量";
    console.log(fn);  // function的声明后于var的声明,故funtion的声明把var的声明覆盖了
    

    👇b、c前面没有var声明,所以是全局变量,a前有var声明,是局部变量,故运行第四行的console.log(a);时会报错👇

    f1();
    console.log(c);
    console.log(b);
    console.log(a);
    function f1(){
        var a = b = c = 9;
        console.log(a);
        console.log(b);
        console.log(c);
    }
    

    写在最后

    如果您觉得文章对您有帮助,不要吝惜您的“点赞”呀!

    相关文章

      网友评论

        本文标题:JavaScript入门笔记3

        本文链接:https://www.haomeiwen.com/subject/chluictx.html