zoukankan      html  css  js  c++  java
  • JS基础-第5天

    复习函数

    函数

    作用:封装一段代码,封装的功能可以被反复调用执行。

    定义函数

    // 第一种 - 函数声明
    function 函数名(){
        
    }
    // 第二种 - 函数表达式
    var 函数名 = function(){
        
    }
    // 第三种 - 构造函数函数 - 了解
    var 函数名 = new Function();

    调用函数

    函数名();

    函数三要素

    函数名称    -  变量名
    函数参数    -  形参  实参 (定义参数,使用参数,给参数赋值)
    函数返回值   - 难点,return,把函数的<数据>返回给函数外部。

     

    补充一些需要了解的其他知识点

    1.匿名函数

    所谓的匿名函数就是一个没有名字的函数,但是js语法是不允许匿名函数单独存在,一般我们也不会直接写一个单独的匿名函数,我们现在用到匿名函数的地方:

    函数表达式、后面再学习WebAPI的时候用来注册事件也会用到,自调用函数也用到了...

    function (参数列表){
      函数体
    }

    2.自调用函数

    定义之后会自动调用的函授

    (function(参数列表){
      函数体
    })(实参);

    一般在我们的技术能力达到一定的高度之后,对某个自己的功能实现封装的时候使用(js面向对象)

    3.函数也是数据类型

    function fn(){}
    typeof fn === 'function'

    函数这种数据类型是复杂类型,函数本质也是对象。

     

    4.形参和实参

    形参相当于变量名,实参相当与要赋值给变量的数据。

     

    5. 函数也是变量,所以可以作为函数的参数

    我们发现只要是数据类型就可以作为参数,而函数也是一种数据类型,就把函数也作为参数,也是可以的,我们称作为参数的函数是回调函数

     

    作用域

    目标

    能区别全局作用域局部作用域

     

    概念

    什么是作用域: 一个变量或者一个函数的有效范围。

    通过什么划分作用域:JS 主要通过函数划分作用域,一个函数体就是一个独立的作用域。

    在 JS 里面作用域分为全局作用域局部作用域

    全局指的是在页面的任何地方都可以访问.
    局部指的是只能在函数内部使用.

    可以认为函数里面就是局部作用域。

     

    控制台查看作用域

    变量名和函数名

    在全局作用域下创建的变量,能在整个 JS 页面任意位置,全局生效。

    函数名本质也是变量名,所以在全局作用域下创建的函数,也能是全局生效。

     

    局部变量和参数

    函数内的变量只能在函数内部访问,函数外部无法访问。

    函数内的形参本质也是局部变量,函数形参也只能在函数内访问,函数外部无法访问。

     

    编程源于生活

    局部作用域结合生活例子记忆:
    代码:函数内创建的局部变量             生活:人的私有财产
    代码:函数内使用局部变量               生活:人可以使用自己的私有财产
    代码:局部变量在函数之外被使用          生活:人的财产被别人用了
       代码:控制台报错     生活:打电话报警

     

    小结

    局部作用域和全局作用域?

    局部作用域:在函数内创建,只对函数内部生效,函数外部无法访问。
    全局作用域:在顶级作用域下创建,整个JS页面都生效。

    JS主要通过什么划分作用域?

    JS 主要通过函数划分作用域,一个函数体就是一个独立的作用域。

     

    预解析

    目标

    了解预解析变量提升和函数声明提升。

     

    概念

    js代码在执行之前,会预先解析一次,解析的工作就是把变量和函数的声明提升到当前作用域的最顶端,变量的赋值和函数的调用仍然在原来的位置。

    比如你写的代码:
    var a = 10;
    var b = 20;
    
    程序运行前预解析:
    var a;
    var b;
    a = 10;
    b = 20;

    预解析提升的情况

    只有两种情况的代码,JS 会发生预解析,分别是 var 变量创建 和 function 函数声明

    1. var 创建变量会提升

    2. function 函数声明会提升

     

    变量预解析

    源代码分析

    console.log("自己写的源代码");
    function fn(){
        console.log(num);       // undefined,为什么输出 undefined
        var num = 10;
        console.log(num);       // 10
    }
    fn();

    模拟 JavaScript 在执行代码前的预解析过程

    // 模拟 JS 在执行代码前预解析的过程
    function fn(){
        var num;                // JS把创建变量的过程提升到当前作用域的最前面(JS自动的)
        console.log(num);       // undefined,因为赋值语句在输出后才赋值
        num = 10;                // 重新赋值
        console.log(num);       // 10,输出赋值后 的 num
    }
    fn();

    函数预解析

    函数的声明JS也会预解析,所以我们在控制台打断点执行代码的时候,发现没有办法在函数上打断点。 因为函数在执行代码前已经预解析创建完毕了。

    // 2. 所以在前面也能调用函数
    fn();
    // 1. 因为JS会自动把函数声明的过程在代码执行前预先解析
    function fn(){
        console.log("函数被调用了");
    }

    小结

    哪两种情况在 JS 会发生预解析?

     

    短路运算

    目标

    知道短路运算运算规则。

    短路运算符号

    短路运算符号其实就是逻辑运算符的 && 和 ||

    &&      与,且
    ||

    短路运算优先级

    && 运算符优先级高于 || 运算符。

    回顾之前的逻辑运算符

    编程源于生活,生活例子:某人找对象,两个条件,身材好 并且 漂亮。

    生活总结:如果有其中一个条件不满足,最终都不要,主要看不满足条件。

    程序总结:&& 运算,如果一个条件为 false,最终结果为 false。

    &&      /且       -     找假
    || 或          -     找真

    隐式布尔类型转换

    相当于 JS 偷偷的帮我们执行了 Boolean() 函数把数据转隐式换成布尔类型,用于短路运算。

    Boolean(数据);        // 隐式转换,JS自动的,我们看不见
    转换情况:
    转换成 true 的情况有无数种。
    转换为 false 6 种情况:""  0   NaN  undefined  null  false

    短路运算执行过程

    只需要管 && || 运算符 左边的数据,左边数据隐式转换后为 真 还是为 假,最终决定计算结果。

    如果 && 运算符左边隐式转换为假,左边就是结果(找假),否则右边的是结果。

    如果 || 运算符左边隐式转换为真,左边就是结果(找真),否则右边的是结果。

    练习

    运算符 || 找真

    // 左边数字 1 隐式转换后为 true,左边数据为 真,左边就是计算的结果
    console.log( 1 || 0 );               // 1
    // 左边字符串 "456" 隐式转换后为 true,左边数据为 真,左边就是计算的结果
    console.log( "456" || "789" );       // "456" 
    // 左边 null 隐式转换后为 false,左边数据为 假,相反右边才是计算结果
    console.log( null || 123 );         // 123
    // 左边 NaN 隐式转换后为 false,左边数据为 假,相反右边才是计算结果
    console.log( NaN || 0 );            // 0

    运算符 && 找假

    // 左边数字 1 隐式转换后为 true,左边数据为 真,相反右边才是计算结果
    console.log( 1 && 0 );               // 0
    // 左边字符串 "456" 隐式转换后为 true,左边数据为 真,相反右边才是计算结果
    console.log( "456" && "789" );       // "789" 
    // 左边 null 隐式转换后为 false,左边数据为 假,左边就是计算结果
    console.log( null && 123 );         // null
    // 左边 NaN 隐式转换后为 false,左边数据为 假,左边就是计算结果
    console.log( NaN && 0 );            // NaN

    小结

    短路运算 && || 的执行过程?

    短路运算 && || 哪个优先级更高?

     

    对象基本概念

    目标

    了解对象基本概念。

     

    什么是对象

    对象是属性和方法的<无序>集合。(无序键值对的集合)

    数组是一堆数据的<有序>集合。

     

    内置对象

    我们以前学习的 new Date(), Math 这些都是JS里面字带的对象,称为内置对象,内置对象提供了不少功能,但是迟早有一天,这些功能是不够用的,需要我们自己创建自己的对象,然后指挥这些对象去做事情。

     

    面向对象

    把万事万物抽象成对象,将来只要想要让某个对象去做事情,就只需要找到对象,指挥对象做事情就行了。

     

    小结

    对象是什么?

    对象和数组区别?

     

    创建对象的语法

    目标

    用两种方式创建对象。

    对象字面量

    字面量的方式创建

    var 对象名称 = {};
    var 对象名称 = {
      属性名:属性值,
      方法名: function(){}
    }
    // 注意点: 多个键值对之间使用 逗号 隔开即可

    对象构造函数

    使用 构造函数的方式创建对象

    var 对象名称 = new Object();// 此时就已经创建了一个对象
    
    例如:
    var obj = new Object();

    对象和数组区别

    对象是无序的数据集合

    小结

    创建对象?

    1. 字面量
    var 对象名称 = { };
    2. 构造函数
    var 对象名 = new Object();

    对象存储数据?

    var 对象名称 = {
        键名称1: 值1,
        键名称2: 值2
    };

    对象取数据?

    对象名称.键名称
    
    对象名称["键名称"]            // 特殊的情况下要使用到 - 遍历对象

    对象的方法?

    对象的方法 本质就是 函数,如果函数没有设置返回值,默认返回 undefined

    如何调用对象方法?

    对象.方法名();

    给对象添加属性和添加方法

    对象.属性名 = 属性值;
    对象.方法名 = function(){}
    
    例如:
    obj.name = '李狗蛋';
    obj.eat = function(){}

    工厂模式

    把创建对象的过程进行封装。

    之前所学习的这些语法,只能创建单个对象如果想要方便的创建多个同类型对象,就可以使用工厂模式。

    常见写法

    写法1

    function createPerson(name,sex,age){
        var obj = {
            name: name,
            sex: sex,
            age: age,
            sayHi: function(){
                console.log("我的名字是"+obj.name+",今年"+obj.age+",性别是"+obj.sex);
            }
        }
        return obj;
    }

    写法2

    function createStudent(name,gender,age) {
      var student = new Object();
      student.name = name;
      student.gender = gender;
      student.age = age;
      student.readBook = function () {
        console.log('从前有座山....');
      }
      return student;
    }

    小结

    小结:工厂函数内部
    1. 在工厂函数内部创建对象
    2. 把传入参数进行属性的设置
    3. 在工厂函数内,把创建的对象返回 return

    自定义构造函数

    目前来说,自定义构造函数是我们在js里面最推荐的创建对象方式。

    目标

    学会使用构造函数创建对象,知道 new 和 this 。

    构造函数写法

    // 创建构造函数
    function Student(name,gender,age) {    
        this.name = name;
        this.gender = gender;
        this.age = age;
        this.readBook = function () {
          console.log('从前有座山....');
        }
      } 
    // 调用构造函数
    var stu1 = new Student("名字","性别",18);
    console.log(stu1);

    new 关键字

    这是一个专门用户创建新对象的操作符 ,都会配合 构造函数进行使用

    一般格式就是:

    new 构造函数()

    这个new关键字执行过程:

    1. 调用构造函数,并且在函数内部创建了一个对象,然把对象存进 this 这个东西里面

    2. 调用构造函数里面的所有的代码,为 this,添加属性和方法

    3. 自动把对象返回,也就是把 this 返回

    this关键字

    在构造函数里面我们发现有一个新的关键字 this,this在js里面就是一个专门指向一个对象的类似一个变量的东西,可以这么理解,这个this就是一个变量,这个变量只会存储一个对象,这个对象是什么呢?

    现在不用太关注,目前大家只要知道,构造函数里面的this,就是我们在new的时候创建的对象。

    小结

    构造函数是否需要创建新对象?

    不需要。

    那个关键词代表构造函数内部的对象?

    this 就代表构造函数内的对象。

    构造函数是否需要return对象?

    不需要。 构造函数自动返回内部对象。

    构造函数命名规范建议?

    构造函数名称首字母大写

    如何调用构造函数?

    new 关键词调用构造函数。

    构造函数参考代码

    // 自定义的构造函数,和工厂函数一样,也是用于批量创建对象
    function Person(name,age){
        // 函数内创建的对象用 this 表示
        this.name = name;
        this.age = age;
        this.sayHi = function(){
            console.log("我的名字叫" + this.name);
        }
    }
    // 构造函数需要通过 new 关键词区调用
    var p1 = new Person("张三",18);
    console.log(p1);
    p1.sayHi();

    for-in遍历对象

    有时候需要把对象里面的每个键值对全都访问一次,这种方式成为 - 遍历对象

    有一个特殊的语法可以遍历对象

    for (var 变量名 in 你要遍历的对象){
          通过key得到每个键
          通过 对象[key] 这个方式得到每个值
    }
    例如:
     var obj = {
       name :'二狗',
       age : 12,
       gender : '男',
       height: 188
     }
     for(var key in obj){
      console.log(obj[key]);
     }
    // 最终就把每一个属性的值输出了

    小结

    数组有序,遍历用 for 循环,索引值从0开始。

    对象无序,遍历用 for in 循环,对象遍历的是键名称。

    语法:

    for(var key in 对象名称){
        console.log( key );               // 循环输出每一个键名称
        console.log( 对象名称[key] );     // 循环输出每一个键对应的值        
    }
  • 相关阅读:
    数组同时求极值
    约瑟夫环
    使用流迭代器,&nbsp;sort,&nbsp;co…
    Emacs 使用TAGS阅读源码
    Making Emacs Work For Me
    gnu libc 源码分享
    JavaSE 键盘事件类(KeyEvent)实现
    老子《道德经》第二十三章
    linux 系统没有默认的目录
    老子《首德经》第二十二章
  • 原文地址:https://www.cnblogs.com/replaceroot/p/10714503.html
Copyright © 2011-2022 走看看