JS基础(三)-函数、JS中的对象

函数

  1. 函数基本概念
    1. JavaScript中函数的概念和C语言几乎一样,都是用于封装一段代码,方便将来重复使用的
    2. 不同的是JavaScript中的函数也是一种类型, 是引用类型
  2. 函数的定义

     // 格式一:
     function 函数名(形参1, 形参2, 形参3...) {
       //函数体
       return 返回值;
     }
        
     // 格式二:
     var 变量 = function(实参1, 实参2, 实参3...){
       //函数体
       return 返回值;
     };
    
    1. 注意点:
      1. 和C语言一样, 函数可以没有形参, 也可以有一个或多个形参
      2. 不同的是由于JavaScript是弱语言, 所以形参只用写一个占位符即可
      3. 和C语言一样, 函数可以没有返回值, 也可以有返回值
      4. 不同的是JavaScript是弱语言, 所以不用写返回值类型
      5. 如果函数没有使用 return语句 ,那么函数有默认的返回值:undefined
      6. 如果函数使用 return语句,那么return后面的值,就成了函数的返回值
      7. 如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined
              
       function sayHi(name) {
           console.log(name);
       }
       sayHi("sss");
          
       var sayHello = function (name, age) {
           console.log("name = "+ name, "age = "+age);
       }
       sayHello("sss", 12);s
              
       function sum1(a, b) {
           var res = a + b;
           return res;
       }
       var res = sum1(10, 20);
       console.log(res); // 30
              
       function sum2(a, b) {
          var res = a + b;
          return;
       }
       var res = sum2(10, 20);
       console.log(res); // undefined
              
       function sum3(a, b) {
          var res = a + b;
       }
       var res = sum3(10, 20);
       console.log(res); // undefined
      
  3. arguments的使用
    1. 由于JavaScript中的函数是引用类型(可以添加属性和方法)。所以所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有的实参。arguments是一个伪数组,因此可以进行遍历

       function getSum() {
         var sum = 0;
         for (var i = 0; i < arguments.length; i++) {
           sum += arguments[i];
         }
         return sum;
       }
       var sum = getSum(5, 1, 3, 4);
       console.log(sum);
      
  4. 函数作为参数和返回值
    1. 由于JavaScript中的函数也是一种数据类型, 所以函数也可以作为参数和返回值使用
    2. 函数作为其他函数参数

       var sayHi = function () {
           console.log("hello world");
       }
       function test(fn) {
           fn();
       }
       test(sayHi);
      
    3. 函数作为其他函数返回值

       function test() {
           var sayHi = function () {
               console.log("hello world");
           }
           return sayHi
       }
       var res = test();
       res();
      
  5. 匿名函数
    1. 没有名称的函数, 我们称之为匿名函数
    2. 匿名函数不能单独出现, 一般作为其他函数参数或者返回值使用
     // 报错
     function () {
         console.log("hello world");
     }
        
     // 立即执行函数
     (function () {
         console.log("hello world");
     })();
        
     // 作为函数参数
     function test(fn) {
         fn();
     }
     test(function () {
         console.log("hello world");
     });
        
     // 作为函数返回值
     function test() {
         return function () {
             console.log("hello world");
         }
     }
     var res = test();
     res();
    

ES6新增语法

  1. 扩展运算符在函数的形参列表中的作用
    1. 将传递给函数的所有实参打包到一个数组中

       //values打包所有的实参
       function getsum(...values){
          console.log(values)
          var sum = 0;
           for (var i = 0; i < values.length; i++) {
               sum += values[i];
           }
           return sum;
       }
       getsum(10,20);
      
    2. 注意: 扩展运算符只能写在最后

       //只能写在最后
       function getsum(a,...values){}
      
  2. 函数形参默认值

     function sum(a = 10,b= 6){
         return a + b;
     }
     console.log(sum());
    
  3. 箭头函数
    1. ES6新增的一种定义函数的方法,简化定义函数

       let 函数名称 = (形参列表)=>{
           函数体
       }
      
    2. 如果只有一个形参,形参的括号可以省略

       let 函数名称 = 形参1=>{
           函数体
       }
      
    3. 如果{}中的函数体只有一句代码,则{}可以省略

       // 箭头函数
       let sum = (a,b)=>{
           return a + b;
       }
       console.log(sum(10,20));
          
       // 省略()
       let say = name => {
           console.log("hello" + name);
       }
       // 省略{}
       let say2 = name => console.log("hello" + name);
      

作用域

  1. JavaScript中作用域的概念和C语言一样, 也分为全局作用域和局部作用域
  2. 全局作用域
    1. 在任何地方都可以访问到的就是全局作用域
    2. script标签中或一个独立js文件中定义的就是全局作用域
  3. 局部作用域
    1. 只在固定的代码片段内可访问到的变量,例如函数内部。对应局部作用域(函数作用域)
    2. 写在函数内部的都是局部作用域, 只能在当前函数内访问
  4. 注意点:
    1. 如果在函数中定义变量时,如果不添加var关键字, 这个变量是一个全局变量
    2. 块级作用域:
      1. 任何一对花括号{}中的语句集都属于一个块,在这之中定义的所有变量在代码块外都是不可见的,我们称之为块级作用域。
      2. ES5之前没有块级作用域的的概念,只有函数作用域,现阶段可以认为JavaScript没有块级作用域
      3. 在JS中,ES6之前(变量用var修饰),在块级作用域中定义的变量,是全局变量;在ES6之后(用let修饰),在块级作用域中定义的变量,外部不能访问
      4. if、while、do都是块级作用域
     <script>
         //1.全局变量
         var num = 10; // 该变量是全局作用域
         function test() { 
             // 在函数中访问全局作用域num变量
             console.log("test中"+num);
         }
         test();
         // 在外面访问全局作用域num变量
         console.log("外部"+num);
         //2. 全局函数
         function test() { // 该函数是全局作用域
             console.log("test函数");
         }
         // 在外面访问全局作用域test函数
         test();
         function demo() { 
             // 在函数中访问全局作用域test函数
             test();
         }
         demo();
         //3. 局部变量
         function test() {
             var num = 123; // 该变量是局部作用域
             // 可以在同一个局部作用域中访问
             console.log("test中"+ num);
         }
         // 不能在局部范围以外访问
         console.log("外部"+num);
         function test() {
            
         //4. 局部函数
         function demo() { // 该函数是局部作用域
                 console.log("demo函数");
             }
             // 可以在同一个局部作用域中访问
             demo();
         }
         // 不能在局部范围以外访问
         demo();
     </script>
    
     //注意点
     <script>
         function test() {
             // 企业开发千万不要这么写
             num = 123;
             console.log(num);
         }
         test();
         console.log(num);
     </script>
        
     //块级作用域
     {
         var a = 10;
     }
     // 10,用var修饰,即ES6之前,则a为全局作用域
     console.log(a);
    
     // 但是如果用了let,即ES6,那么块作用域外就不能访问到
     {
         let b = 10;
     }
     // 报错
     console.log(b);
    

预解析

  1. JavaScript代码的执行是由浏览器中的JavaScript解析器来执行的。
  2. JavaScript解析器执行JavaScript代码的时候,分为两个过程:
    1. 预解析过程
    2. 代码执行过程
  3. 预解析过程:
    1. 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
    2. 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
    3. 先提升var,再提升function。
  4. 举例

     //变量预解析
     console.log(num); // undefined
     var num = 123;
        
     //函数解析
     test();
     function test() {
         console.log("hello world");
     }
    
  5. 注意点:
    1. 变量和函数同名时, 函数的优先级高

       console.log(num);
       function num() {
           console.log("hello world");
       }
       var num = 666;
       console.log(num);
          
       /*
       //预解析后:
       function num() {
           console.log("hello world");
       }
       var num;
       console.log(num);
       num = 666;
       console.log(num);
        */
      
    2. 不同方式定义函数区别

      1. 预解析时提升的方式不同

         // 1.函数声明
         test();
         function test() {
             console.log("xx学院");
         }
         // 2.函数表达式
         demo(); // 报错
         var demo = function () {
             console.log("xxxxx");
         }
         /*
         //预解析后
         function test() {
             console.log("xx学院");
         }
         var demo;
         test();
         demo();
         demo = function () {
             console.log("xxxxx");
         }
        
      2. 新旧版本浏览器预解析处理方式不同

         /*
         在新版本浏览器中, 代码块中的函数不会被提升
         在旧版本浏览器中, 代码块中的函数会被提升
         新版本输出"123"
         老版本输出"456"
          */
         if(true){
             function test() {
                 console.log("123");
             }
         }else{
             function test() {
                 console.log("456");
             }
         }
         test();
        

JS中的对象

  1. 什么是对象?
    1. 在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、 函数等。
    2. 对象是由属性和方法组成的。
  2. 创建对象的三种方式
    1. 在 JavaScript 中,现阶段我们可以采用三种方式创建对象(object):
      1. 利用字面量创建对象
      2. 利用 new Object 创建对象
      3. 利用构造函数创建对象

创建对象的三种方式

1. 利用字面量创建对象

  1. 对象字面量:就是花括号 { } 里面包含了表达这个具体事物(对象)的属性和方法
  2. { } 里面采取键值对的形式表示
    1. 键:相当于属性名
    2. 值:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)
  3. 对象的调用
    1. 对象里面的属性调用 : 对象.属性名
    2. 对象里面属性的另一种调用方式 : 对象[‘属性名’],注意方括号里面的属性必须加引号
    3. 对象里面的方法调用:对象.方法名() ,注意这个方法名字后面一定加括号
  4. 代码举例:

     // 1.使用字面量创建对象
     var obj = {}; // 相当于var obj = new Object()
     // 2.动态给空对象新增属性
     obj.name = "lnj";
     obj.age = 33;
     // 3.动态给空对象新增方法
     obj.say = function () {
         console.log("hello");
     }
    
     var star = {
         name : 'pink', 
         age : 18, 
         sex : '男', 
         sayHi : function(){ 
             alert('大家好啊~'); 
         }
     };
     //调用
     // 调用名字属性
     console.log(star.name);
     // 调用名字属性
     console.log(star['name']);
     // 调用 sayHi 方法,注意,一定不要忘记带后面的括号
     star.sayHi();
    
  5. 变量、属性、函数、方法总结
    1. 变量:单独声明赋值,单独存在
    2. 属性:对象里面的变量称为属性,不需要声明,用来描述该对象的特征
    3. 函数:单独存在的,通过“函数名()”的方式就可以调用
    4. 方法:对象里面的函数称为方法,方法不需要声明,使用“对象.方法名()”的方式就可以调用,方法 的行为和功能。

2. 利用new Object创建对象

  1. Object() :第一个字母大写
  2. new Object() :需要 new 关键字
  3. 使用的格式:对象.属性 = 值;

     // 1.使用默认类创建一个空对象
     var obj = new Object()
     // 2.动态给空对象新增属性
     obj.name = "xx";
     obj.age = 33;
     // 3.动态给空对象新增方法
     obj.say = function () {
         console.log("hello");
     }
     // 4.使用对象的属性和方法
     console.log(obj.name);
     console.log(obj.age);
     obj.say();
    

3. 利用构造函数创建对象

  1. 构造函数 :是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用。我们可以把对象中一些公共的属性和方法抽取出来,然后封装到这个函数里面。
  2. 在 js 中,使用构造函数要时要注意以下两点:
    1. 构造函数用于创建某一类对象,其首字母要大写
    2. 构造函数要和new一起使用才有意义
  3. 注意:
    1. 构造函数约定首字母大写。
    2. 函数内的属性和方法前面需要添加this ,表示当前对象的属性和方法。
    3. 构造函数中不需要 return 返回结果。
    4. 当我们创建对象的时候,必须用 new 来调用构造函数。
     function Person(name, age, sex) {
         this.name = name; 
         this.age = age; 
         this.sex = sex; 
         this.sayHi = function() { 
             alert('我的名字叫:' + this.name + ',年龄:' + this.age + ',性别:' + this.sex); 
         }
     } 
     var bigbai = new Person('大白', 100, '男'); 
     var smallbai = new Person('小白', 21, '男');
     console.log(bigbai.name); 
     console.log(smallbai.name);
    
  4. 构造函数和对象
    1. 构造函数,如 Stars(),抽象了对象的公共部分,封装到了函数里面,它泛指某一大类(class)
    2. 创建对象,如 new Stars(),特指某一个,通过 new 关键字创建对象的过程我们也称为对象实例化
  5. new关键字
    1. new 在执行时会做四件事情:
      1. 在内存中创建一个新的空对象。
      2. 让 this 指向这个新的对象。
      3. 执行构造函数里面的代码,给这个新对象添加属性和方法。
      4. 返回这个新对象(所以构造函数里面不需要return)。

遍历对象属性

  1. for...in 语句用于对数组或者对象的属性进行循环操作。
  2. 其语法如下:

     for (变量 in 对象名字) { 
         // 在此执行代码 
     }
    
  3. 语法中的变量是自定义的,它需要符合命名规范,通常我们会将这个变量写为 k 或者 key。

     for (var k in obj) { 
         console.log(k); // 这里的 k 是属性名 
         console.log(obj[k]); // 这里的 obj[k] 是属性值 
     }
    

JS 内置对象

  1. 内置对象
    1. JavaScript 中的对象分为3种:自定义对象 、内置对象、 浏览器对象
    2. 前面两种对象是JS基础内容,属于 ECMAScript; 第三个浏览器对象属于我们JS独有的, 我们JS API 讲解
    3. 内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
    4. 内置对象最大的优点就是帮助我们快速开发
    5. JavaScript 提供了多个内置对象:Math、 Date 、Array、String等
  2. 查文档
    1. 学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN/W3C 来查询。
    2. Mozilla 开发者网络(MDN)提供了有关开放网络技术(Open Web)的信息,包括 HTML、CSS 和万维网及 HTML5 应用的 API。
    3. MDN:https://developer.mozilla.org/zh-CN/

Math 对象

  1. Math 概述
    1. Math 对象不是构造函数,它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值 等)可以使用Math中的成员。

       Math.PI         // 圆周率
       Math.floor()    // 向下取整
       Math.ceil()     // 向上取整
       Math.round()    // 四舍五入版 就近取整 注意 -3.5 结果是-3
       Math.abs()      // 绝对值
       Math.max()/Math.min() // 求最大和最小值
      
  2. 随机数方法 random()
    1. random() 方法可以随机返回一个小数,其取值范围是 [0,1),左闭右开 0 <= x < 1random() 方法可以随机返回一个小数,其取值范围是 [0,1),左闭右开 0 <= x < 1
    2. 得到一个两数之间的随机整数,包括两个数在内

       function getRandom(min, max) { 
           return Math.floor(Math.random() * (max - min + 1)) + min;
       }
      

日期对象

  1. Date概述
    1. Date对象和Math对象不一样,他一个构造函数,所以我们需要实例化后才能使用
    2. Date实例用来处理日期和时间
  2. Date()方法的使用
    1. 获取当前时间必须实例化

       var now = new Date(); 
       console.log(now);
      
    2. Date() 构造函数的参数

      1. 如果括号里面有时间,就返回参数里面的时间。例如日期格式字符串为‘2019-5-1’,可以写成new Date('2019-5-1') 或者 new Date('2019/5/1')
      2. 如果Date()不写参数,就返回当前时间
      3. 如果Date()里面写参数,就返回括号里面输入的时间
  3. 日期格式化
    1. 我们想要 2019-8-8 8:8:8 格式的日期,要怎么办?
    2. 需要获取日期指定的部分,所以我们要手动的得到这种格式。

       getFullYear()   //获取当前年
       getMonth()      //获取当前月份(0-11)
       getDate()       //获取当前日期
       getDay()        //获取当前天(周日0-6周六)
       getHours()      //获取当前小时
       getMinutes()    //获取当前分钟
       getSeconds()    //获取当前秒
      
  4. 获取日期的总的毫秒形式
    1. Date 对象是基于1970年1月1日(世界标准时间)起的毫秒数
    2. 我们经常利用总的毫秒数来计算时间,因为它更精确

       // 实例化Date对象 
       var now = new Date(); 
       // 1. 用于获取对象的原始值 
       console.log(date.valueOf()) 
       console.log(date.getTime()) 
       // 2. 简单写可以这么做 
       var now = + new Date(); 
       // 3. HTML5中提供的方法,有兼容性问题 
       var now = Date.now();
      

数组对象(略)

数字符串对象

  1. 根据字符返回位置
    1. 字符串所有的方法,都不会修改字符串本身(字符串是不可变的),操作完成会返回一个新的字符串。
     indexOf('要查找的字符串',开始的位置): 返回指定内容在原字符串中的位置,如果找不到就返回-1,开始的位置是index索引号
     lastindexOf:从后往前找,只找第一个匹配的
    
  2. 根据位置返回字符(重点)

     charAt(index): 返回指定位置的字符串
     charCodeAt(index): 获取指定位置处字符串的ASCII
     str[index]:获取指定位置字符串,H5、IE8+支持,跟charAt等效
    
  3. 字符串操作方法(重点)

     contact(str1,str2...): 用于连接两个或者多个字符串,等效于+
     substr(start,length): 从start位置开始,length取的个数
     slice(start,end):从start位置开始截取到end位置,end取不到。start、end都是索引
     substring(start,end):从start位置开始截取到end位置,end取不到,与slice区别,这个方法不接受负值
    
  4. replace()方法
    1. replace() 方法用于在字符串中用一些字符替换另一些字符。
    2. 其使用格式如下:

       replace(被替换的字符串, 要替换为的字符串);
      
  5. split()方法
    1. split()方法用于切分字符串,它可以将字符串切分为数组。在切分完毕之后,返回的是一个新数组。

       var str = 'a,b,c,d';
       console.log(str.split(','));// 返回的是一个数组 [a, b, c, d]
      
Table of Contents