JS函数基础

版权声明: https://blog.csdn.net/qq_40999496/article/details/81950554

目录

什么是函数

作用域 

声明提前

按值传递

全局函数

分支结构

循环

内置对象/包装类型

String

正则表达式

RegExp

Math

Date


什么是函数

什么是函数:函数又叫方法,在程序里面函数是用来执行某些特定功能的代码。为了减少重复使用代码,可以把特定功能的代码做成函数,需要使用时拿出来调用

这里和大家解释一下函数与事件的区别:

事件是在特定条件下触发的行为,函数则是实现特定功能的行为的具体的体现。比如你在人格受到侮辱时你会愤怒,那么“当愤怒时”就是事件,而你愤怒的时候会具体做什么,也就是你对这个事件的具体反映,由函数来完成;比如你愤怒时会打架(fighting),那么打架就是函数。简单来说,事件是 ‘怎么了’,函数就是 ‘怎么办’

如何去创建函数:

1、声明:

function 函数名(参数变量列表){

       函数体;

       return   返回值;

}

参数:接收传入函数中必要数据的变量       参数用法和普通变量完全一样,只不过不用var声明

什么时候会用到参数:如果一项任务必须某些数据才能正常执行时,就必须定义参数

返回值:函数执行的结果

什么时候会用到返回值:如果调用者需要获得函数的执行结果时,就用return返回结果

      return的作用:

             1、退出函数执行——可单独使用

              2、退出函数时,顺便返回结果      如果函数没有返回任何结果,就返回undefined

2、调用: 让引擎按照函数的步骤清单执行一项任务

   什么时候调用:函数只有调用才执行,不调用不执行!

   var 返回值=函数名(参数值列表)

作用域       scope: 变量的使用范围

什么是作用域:变量的可用范围        可以避免不同范围的变量之间互相污染

作用域可分为:全局作用域(window)、函数作用域

全局作用域

什么是全局作用域:程序中的任何位置都可以访问的范围       保存全局变量

全局变量:保存在全局作用域中,程序任何位置都可使用的变量      随处可用, 可反复使用      只要希望随处可用的公共变量     只要不属于任何函数的变量,自动都是全局的

优:随处可用, 可反复使用   

缺:易造成全局污染

函数作用域

什么是函数作用域:仅函数内可用的范围       保存局部变量

局部变量:保存在函数作用域中,仅函数内可用的变量    仅函数内可用,不可反复使用       只限于当前函数内使用,函数外不可用时

局部变量有两种:1、在函数内声明的变量       2、函数的参数变量也是局部变量

变量使用顺序: 优先使用函数内的局部变量    局部没有,才去全局找

优:仅函数内可用,不会被污染

缺:不可重用

声明提前

什么是声明提前:在程序开始执行前,都会将var声明的变量和function声明的函数,提前到当前作用域的顶部,集中创建。赋值留在原地。再开始执行程序。

但是声明提前破坏了程序默认的执行顺序

解决:

1、将所有的变量和函数声明都集中在当前作用域顶部

2、ES6:let代替var   let禁止在声明之前提前使用变量    强制将声明集中在当前作用域顶部创建     限制:不能用let反复创建相同名称的变量

3、函数: 第2种创建函数的方式:

         var函数名=function (参数变量列表){... ...}

         用以上方式创建的函数不会被声明提前

按值传递

什么是按值传递:两变量间赋值或将变量传入函数作为参数时,其实只是将原变量中的值复制一个副本给对方

原始类型的值:修改新变量,不影响原变量的值

全局函数

什么是全局函数:ES标准中规定的,浏览器已经实现的,不需要任何前缀.就可直接调用的函数

比如:Number()   String()   Boolean()   isNaN()   parseFloat()  parseInt()

编码解码:特指对地址栏中的url内容进行编码和解码

什么是编码:将url中包含的多字节字符编码为单字节字符

为什么:url规定地址中不能包含多字节字符   如果包含,会乱码

何时:只要url中可能包含多字节字符,都要将其编码为单字节字符

如何:var code=encodeURI(url)

解码:将编码后的单字节字符串解码回多字节原文

何时:只要收到的是编码后的字符串,都要先解码再使用

如何:var str=decodeURI(code)

问题:url中不但不允许多字节字符,而且还不允许出现保留了字符: 比如: /     但是encodeURI无法对保留字编码

解决:用encodeURIComponent代替encodeURI     用decodeURIComponent代替decodeURI

eval:专门执行一个字符串格式的js语句

分支结构

分支结构:让程序根据不同的条件执行不同的操作

什么时候用到:只要让程序根据不同的条件执行不同的操作

怎么用:

  1、一个条件,一件事,满足就执行,不满足就不执行:

    如果操作简单:短路:条件&&(操作1,操作2,...)

    如果操作复杂:if结构

      if(条件){

            操作;

       }

  2、一个条件,两件事,二选一执行

    如果操作复杂: if...else结构

    if(条件){

          满足条件才执行的操作

      }else{

           不满足条件时执行的操作

       }

如果操作简单: 三目/三元/条件运算

  条件?操作1:操作2;

如果只是根据不同的条件,使用不同的值:

  条件?值1:值2

  如果满足条件使用值1,否则使用值2

  3、多个条件,多件事,多选一执行

    如果操作复杂: if...else if...结构

     if(条件1){

            操作1

     }else if(条件2){

            操作2

      }else if(...){

            ...

      }else{

            默认操作

      }

注意:

1、如果程序进入后一个条件,则暗示前一个条件不满足

2、最后一个else可省略,后果,如果一个条件都不满足,则什么也不做

如果操作简单:三目

  条件1?操作1:

  条件2?操作2:

     ... ? ...:

      默认操作 ——不能省略

如果只是根据不同条件选择不同的值:

  条件1?值1:

  条件2?值2:

     ... ? ...:

      默认值

如果所有条件都是等于比较:还可用switch case结构

switch(表达式){//首先计算表达式的值

  case 值1: //如果表达式的值*全等*于值1

    操作1; //则执行操作1

    break;

  case 值2://否则如果表达式的值*全等*于值2

    操作2; //则执行操作2

    break;

  case  ... :

     ... ... ;

    break;

  default: ——可省略

    默认操作;

}

问题:switch意为入口    只要匹配一个case,就进入执行,并触发之后所有case的操作。

解决:打断每个case之间的联系: break;  break: 专门负责中止并退出结构

如何:在每个case之间都要加break

循环

循环:让程序反复执行相同代码段

何时:只要让程序反复执行一项任务时

如何:三要素:

  1、循环条件:让循环可以继续执行的条件   只要循环条件满足,就可以反复执行循环    直到循环条件不满足时,就退出循环

  2、循环变量:循环中用作比较和判断的变量

    考虑:1. 从几开始   2. 到几结束   3. 每次递增/递减几

  3、循环体:循环要反复执行的代码段

  如果循环条件始终为true,则循环永远无法退出——死循环

while循环:先判断循环条件,再决定是否执行循环

何时:要求必须先满足条件,才能执行循环时

 //声明并初始化循环变量

  var 变量=值;

  while(循环条件){

       反复执行循环体;

      修改循环变量的值;

 }

do...while循环:先至少执行一次循环,再判断循环条件,决定是否反复执行

何时:只要希望即使条件不满足,也至少能执行一次时

  //声明并初始化循环变量

  var 变量=值;

  do{

   反复执行循环体;

   修改循环变量的值;

}while(循环条件) ;//当满足(循环条件)时

 while vs do...while

   只要第一次条件都满足,则两者完全一样

   如果第一次条件不满足,while是一次都不执行   do while至少可执行一次

for循环:其实就是while循环的简化

何时:只要循环变量的变化有规律

  for(var 变量=值;循环条件;修改循环变量的值){

   反复执行循环体;

}

简写:

  1. 分支/循环结构中,如果条件之下只有一条语句,则可省略{}, 但强烈不建议这样做——容易出歧义

  2. 其实,第一部分可同时声明并初始化多个变量,多个变量间用逗号分隔:

  3. 其实,第三部分可同时执行多个短小的语句,用逗号分隔,但是,简写不能破坏原执行顺序   如果省略循环体,则for循环后必     须加 " ; "

强调:js中没有块级作用域       分支结构/循环结构内声明的变量,出了结构依然可用

循环嵌套

什么是循环嵌套: 一个循环的循环体内,又执行了另一个内层循环

内置对象/包装类型

内置对象

什么是:ES标准中规定的,浏览器已经实现的对象

包括:11个

  String  Number  Boolean ——包装类型

  Array  Date  RegExp  Math

  Error

  Function  Object

  Global——在浏览器中被window替换

包装类型

什么是:专门封装原始类型的值并提供操作原始类型值的API

为什么:原始类型的值本身不具有任何的功能   才需要包装类型对象的帮助,完成功能

何时:只要试图用原始类型的值调用函数时,都会自动创建对应包装类型的对象,封装要操作的值,并使用函数执行功能。

如何:不用手动使用

   比如: n.toFixed(2) => new Number(n).toFixed(2);

            "张".charCodeAt() => new String("张").charCodeAt();

String

什么是string:由多个字符组成的只读字符数组

string vs 数组:

        相同:1、下标; 2、.length; 3、.slice()

        不同:类型不同: API不通用

API

大小写转换:将str中的字母都转为统一的小写/大写

  str.toLowerCase()      str.toUpperCase()

何时:不区分大小写时,都要先转为一致的大小写,再比较或判断

比如:验证码, 用户名, 电子邮件

获得指定位置的字符: str.charAt(i) => str[i]

获得指定位置字符的unicode号:

  str.charCodeAt(i) 获得str中i位置的unicode号

将unicode号转回字:

    String.fromCharCode(unicode号)

获取子字符串:3种

  str.slice(starti,endi+1)

  str.substring(starti,endi+1) 用法同slice,只不过不支持负数参数

  str.substr(starti,n) 从starti开始,获取n个字符

查找关键词:4种

  1、查找一个固定的关键词

    var i=str.indexOf("关键词",fromi);

    在str中fromi位置之后,查找下一个"关键词"的位置

    返回:如果找到,返回关键词的下标位置 i      如果没找到,返回-1

    var i=str.lastIndexOf("关键词");

    在str中找最后一个关键词的位置i

    问题:每次只能查找一种关键词

    解决:正则表达式模糊匹配多种关键词:

  2、判断是否包含敏感词

    var i=str.search(/正则/i);

     在str中找第一个符合正则要求的敏感词的位置

     返回值:如果找到,返回下标位置     如果没找到,返回-1

     问题:默认正则表达式都是区分大小写

     解决:在第二个/后加后缀i, ignore,表示忽略大小写  

    问题:永远只能找第一个,无法找所有    仅返回位置,无法返回内容

  3、查找所有敏感词的内容

     var kwords=str.match(/正则/ig);

     返回值:kwords中保存所有找到的敏感词    如果找不到,返回null

     问题:默认正则表达式只匹配第一个符合条件的敏感词

     解决:在第二个/后加g, global 全部

     问题:只能获得内容,无法获得每个敏感词的位置

  4、即查找每个敏感词的内容,又查找位置:regExp.exec()

替换

什么是:将字符串中符合规则的敏感词替换为新内容

如何:2种

  1、简单替换: 将所有敏感词替换为同一种新值

      str=str.replace(/正则/ig,替换的新值)

     强调:所有字符串API都无权修改原字符串,只能返回新字符串

  2、高级替换:根据敏感词的不同,动态选择替换为不同的值

      str=str.replace(/正则/ig,function(kw){

               kw //自动获得本次找到的敏感词

               return 根据不同的kw返回不同的值

       })

  衍生:删除: 将关键词替换为 " "

切割

什么是:将字符串按指定的关键词切割为多段子字符串

如何:2种

1. 简单:分隔符是固定的:

var subStrs=str.split("分隔符")

返回: 多个子字符串的数组

      切割后的结果中,不包含分隔符的

  2. 复杂:分隔符不是固定的

     var subStrs=str.split(/正则/)

  固定套路:将字符串打散为字符数组:

     var chars=str.split("");

正则表达式

什么是:规定字符串中字符出现规律的规则

何时:2大用途

  1. 通过规则,模糊查找多种关键词

  2. 验证用户输入的格式

如何:

1. 关键词原文本身就是最简单的正则表达式

2. 字符集

     什么是:规定一位字符备选字符列表的集合

     何时:只要一位字符有多种可能备选时

     如何:[备选字符列表]

     强调:不要用逗号分隔      每个[]只规定一位字符的备选字

     简写:

           1. 如果部分备选字符的unicode是连续的,可用-省略中间字符

                     比如:一位数字: [0-9]

                                一位小写字母:[a-z]

                                一位大写字母:[A-Z]

                                一位字母: [A-Za-z]

                                一位汉字:[\u4e00-\u9fa5]

              2. 除了xxx

                     [^xxx] 比如: 除了4和7都行!

3. 预定义字符集

  什么是:对常用特定字符集的更简化写法

  包括:4个

    \d => [0-9]

    \w => [A-Za-z0-9_]

    \s => 空字符: 空格, Tab...

    . 匹配任意字符

4. 量词

  什么是:规定一位字符集出现次数的规则

  何时:只要规定一位字符集出现的次数

  如何:量词紧跟在修饰的字符集之后

          2大类

                  1. 有明确数量边界的:

                      字符集{n,m} 最少n个,最多m个

                      字符集{n,}  至少n个,多了不限

                      字符集{n}  必须n个

                  2. 没有明确数量边界:

                      字符集?  可有可无,最多1次

                      字符集*  可有可无,多了不限

                      字符集+  至少一个,多了不限

5. 选择和分组

   选择:或

         何时:只要在多个规则中任选其一匹配时

         如何:规则1|规则2

         只要满足两个规则之一即可!

    分组:()

          何时:只要希望一个量词同时修饰多个字符集时     就要将要修饰的字符集放入一个()中作为一组。再用量词修饰()

          为什么:默认一个量词只能修饰相邻的前一个字符集

          比如:身份证号:15位数字  2位数字 1位数字或Xx

                               整体可有可无,最多一次

                                \d{15}      ( \d\d    [0-9Xx] ) ?

               手机号:

                     +86或0086  可有可无,最多1次

                      空格        可有可无,多了不限

                      1,3,4,5,7,8中挑一个       9位数字      (\+86|0086)?\s*1[34578]\d{9}

                      (微|w(ei)?)\s*(信|x(in)?)

6. 指定匹配位置:3个

         开头:^  比如: 匹配开头的空字符: ^\s+

         结尾:$  比如: 匹配结尾的空字符: \s+$

         比如:开头或结尾的空字符: ^\s+|\s+$

         单词边界:\b  包括: 空格, 标点, 开头, 结尾

         比如:匹配单词no: \bno\b

RegExp

什么是:专门封装一条正则表达式,并提供用正则表达式执行验证和查找的API

何时:

  1. 验证字符串的格式

  2. 即查找内容,又查找位置

如何创建:

    1. 直接量: var reg=/正则/ig;

      何时:如果正则表达式是固定不变的

      问题://之中不支持js表达式,也就是不支持动态生成正则表达式

    2. 用new: var reg=new RegExp("正则","ig")

      何时:如果正则表达式需要动态拼接生成

  API:

  1. 验证字符串的格式

    var bool=reg.test(str);验证str是否符合reg的规则要求

   返回:bool,可直接当做判断条件

   问题:test默认只要部分匹配就返回true

   解决:从头到尾完整匹配: 必须前加^后加$

  2. 即查找所有关键词内容,又查找位置

   reg.exec(str) 依次查找str中下一个关键词的内容和位置

   返回值:数组: [0: 关键词内容, index: 下标位置]    如果找不到, 返回null

   问题:每次只返回本次找到的一个关键词

   解决:用循环反复调用reg.exec

   原理:每次调用exec,做3件事

       1. 将本次找到的关键词保存在数组0位置

       2. 将本次找到的关键词位置保存在数组index位置

       3. 修改reg对象的lastIndex=index+关键词的字数

        reg.lastIndex : 记录下次开始查找位置, 默认为0

Math

什么是:专门保存数学计算的常量和函数的对象

何时:只要进行数学计算

如何创建:Math不能new!不用创建!

     所有常量和API都用Math直接调用!

API:

 取整

   1. 上取整: 只要超过,就取下一个整数

     Math.ceil(num)

   2. 下取整: 舍弃小数部分

     Math.floor(num) 只能对纯数字

     vs parseInt(str) 能去掉数字之后非数字字符,再取整

   3. 四舍五入取整: 够5进1,不够舍弃

     Math.round(num) 优: 返回number类型的数值,可直接用于计算。

                   缺: 不能指定小数位数,只能取整

     vs n.toFixed(d)  缺: 返回字符串类型,计算前必须先转换为数字。

                   优: 可指定小数位数,按任意小数位数四舍五入。

 乘方和开平方:

   乘方:Math.pow(底数,幂)

     比如:10的2次方:Math.pow(10,2)=100

   开平方:Math.sqrt(num)

     比如:Math.sqrt(9) = 3

 最大值/最小值:

   Math.max(值1,值2,...)

   Math.min(值1,值2,...)

   问题:不支持获得数组中的最大值

   解决:Math.max.apply(null,arr)

     其中:apply表示"调用"的意思   还可自动打散数组类型参数!

 随机数:

   0<=Math.random()<1

   公式:在任意范围min~max内生成随机整数

     var r=parseInt(Math.random()*(max-min+1)+min);

   简化:如果从0开始

     var r=parseInt(Math.random()*(max +1));

Date

什么是:专门封装一个时间点,并提供操作时间的API

何时:只要存储时间或计算时间

如何创建:

   1. 创建日期对象并自动获得当前系统时间

     var now=new Date();

    强调:new Date()只能获得客户端本地时间

   2. 创建日期对象并封装自定义时间

     var date=new Date("yyyy/MM/dd hh:mm:ss");

             new Date(yyyy,MM-1,dd,hh,mm,ss)

   3. 复制一个日期对象

     为什么:日期计算都是直接修改原日期对象    计算后,无法保存计算前的原日期

     何时:如果用户希望同时保留计算前后的开始和结束时间时,都要先将开始时间复制一个副本,再用副本计算结束时间。

     如何:var date2=new Date(date1);

   4. 用毫秒数创建日期对象

     为什么:将来数据库中保存的时间都是毫秒数

     何时:只要将毫秒数转化为当地时间格式

       var date=new Date(ms)

     其中new Date会将ms转化为操作系统当前所在时区的对应时间显示

     获得日期中的毫秒数: var ms=date.getTime();

     原理:其实日期对象中保存的是1970年1月1日0点至今的毫秒数

     为什么:毫秒数不受时区影响

API:

 1. 8个单位:

    FullYear  Month   Date     Day  ——没有s

    Hours   Minutes  Seconds  Milliseconds 都以s结尾

 2. 每个单位都有一对儿get和set方法

   其中:get负责获得指定单位上的数值        set 负责修改指定单位上的数值

   比如:date.getFullYear()   date.getMonth()...

        date.setFullYear(n)   date.setMonth(n)...

     强调:setXXX(n)可自动调整时间进制:

   特例:Day没有set

 3. 取值范围

   除date外,其余都是从0开始到进制-1结束

     date从1开始,到31结束

     Month: 0~11 都比现实中小1

     Date: 1~31 和现实相同

     Day: 0~6和现实相同 星期日为0

     Hours: 0~23和现实相同

     Minutes/Seconds: 0~59和现实相同

计算:

  1. 两日期对象可相减:结果毫秒差

    何时:倒计时

  2. 对每个单位做加减

    1. 取值:var d=now.getDate(); //d=8

    2. 做加减:d+=30; //d=38

    3. 放回去:now.setDate(d) //自动调整进制               // 6/7

    简化:now.setDate(now.getDate()+n)

日期格式化

  .toString() 返回当地时间格式的完整版本

  .toLocaleString() 返回当地时间格式的简化版本

  .toLocaleDateString() 仅保留日期部分

  .toLocaleTimeString() 仅保留时间部分

  .toGMTString() 获得0时区的标准时间

猜你喜欢

转载自blog.csdn.net/qq_40999496/article/details/81950554