一 : 递归
1、概念
递归就是直接或间接的调用自身的一种"函数"。递归是一种强大的编程技术。他把一个问题分解为一组"相似"的问题,每一组都使用"通用方法"去解决。简单来说一个递归函数就是调用函数自身去解决它的子问题。
2、递归是什么
2.1 递归通俗地讲就是函数自己调用自己,它具有以下三要素:
1、一个大问题可以分解为更小的问题, 而且用同样的方法解决
2、分解后的子问题求解方式一样,不同的是规模在变小
3、存在递归终止条件
递归, 先递进,再回归
2.2 注意:
2.2.1 在使用递归函数时一定要设置退出函数的条件,否则会发生死循环造成严重问题
2.2.2 递归函数的作用和循环效果一样,由于递归很容易发生“超过最大调用堆栈大小”错误(Maximum call stack size exceeded),所以必须要加退出条件
3、递归的目的:
递归的目的是用于解决特殊的问题,这类问题需要具备以下的特点 :
1. 大问题可以拆分成小问题
2. 小问题可以继续拆分为小小问题 无论问题规模的大小 解决方式都一样
4、递归的用法:
第一步:封装一个能解决单一问题的函数(类似循环体)
第二步:在这个函数中调用当前函数 调整问题的规模(类似循环中的变量更新)
第三步:在函数中设置递归出口 如果没有递归出口 递归调用无法结束(类似循环中的判断条件)
二 : 数字的进制
1、概念:
在JavaScript中,Number数据类型可以使用四种数字进制:十进制,二进制,八进制和十六进制。
2、十进制数字 逢十进一 基数 0 1 2 3 4 5 6 7 8 9
2.1 注意:十进制可以以0开头,后面接其他十进制数字,但是假如下一个接的十进制数字小于8,那么该数字将会被当做八进制处理。
2.2 备注: 进制之间转换可以使用toString方法,把指定数值转成指定进制字符串, toString方法返回的结果是一个"字符串"
Number对象.toString( 进制 )
2.3 扩展知识: 使用Math.random()配合toString(16)可以实现得到随机十六进制数
3、八进制数字 逢八进一 基数 0 1 2 3 4 5 6 7
3.1 介绍:八进制数字语法是以0为开头的。假如0后面的数字不在0到7的范围内,该数字将会被转换成十进制数字。
4、二进制数字 逢二进一 基数 0 1
4.1 介绍:二进制数字语法是以零为开头,后面接一个小写或大写的英文字母B(0b或者是0B)。 假如0b后面的数字不是0或者1,那么就会提示语法错误。
5、十六进制数字 逢十六进一 基数 0 1 2 3 4 5 6 7 8 9 a b c d e f
5.1 介绍:十六进制数字语法是以零为开头,后面接一个小写或大写的英文字母X(0x或者是0X)。假如0x后面的数字超出规定范围(0123456789ABCDEF),那么就会提示这样的语法错误(SyntaxError)
5.2 parseInt()方法补充 :这个方法我们主要用于提取整数, 不会进行四舍五入操作 返回值是数值类型
parseInt(string [, radix] ) 解析一个字符串并返回指定基数的十进制整数, radix 是2-36之间的整数,表示被解析字符串的基数。
5.3、注意: 如果parseInt()如果第一个参数不是一个字符串,则将其转换为字符串 (使用 ToString抽象操作)。字符串开头的空白符将会被忽略。
5.4、parseFloat()
5.4.1 parseFloat(string) 函数解析一个参数(必要时先转换为字符串)并返回一个浮点数(小数)
5.4.2 parseFloat() 从字符串中提取小数 将字符串转换为number类型
5.4.3 parseFloat() 从一个字符串提取小数 如果第一个字符不是数字会得到NaN 如果是会进行提取
5.4.4 提取规则 如果遇到了除了第一个.以外的非数字 就会停止提取
5.4.5 当我们其他类型转成数值类型失败的时候,就会得到一个NaN的关键字
5.4.6 判断值是否为NaN, 不可以使用 == 或者 ===
// 判断值是否为NaN, 需要使用一个内置函数 isNaN()
// isNaN(变量名) 如果是NaN就返回true 如果不是NaN的就是false
// 注意: isNaN 会先将一个变量的数据类型自动的转换为Number类型 如果是NaN就会得到true 如果是一个数字的话就是得到false
三、作用域:
1、作用域概述:
作用域是当前的执行上下文,值 (en-US)和表达式在其中“可见”或可被访问。如果一个变量 (en-US)或表达式不在当前的作用域中,那么它是不可用的。作用域也可以堆叠成层次结构,子作用域可以访问父作用域,反过来则不行。
2、JavaScript 的作用域分以下三种:
全局作用域:脚本模式运行所有代码的默认作用域
函数作用域(局部作用域):由函数创建的作用域
简单说,作用域就是什么地方能用,什么地方不能用
3、变量的作用域
3.1 什么是变量的作用域?
指变量在什么地方可以使用,什么地方不可以使用。
3.2 在JavaScript中,根据作用域的不同,变量可以分为两种:
1. 全局变量
在全局作用域下声明的变量叫做全局变量(在函数外部定义的变量)。
1.1 全局变量在代码的"任何位置"都可以使用
1.2 在全局作用域下 var 声明的变量 是全局变量
1.3 特殊情况下,在函数内不使用 var 声明的变量也是全局变量(不建议使用)
2. 局部变量
在局部作用域下声明的变量叫做局部变量(在函数内部定义的变量)
2.1 局部变量只能在"该函数内部"使用
2.2 在函数内部 var 声明的变量是局部变量
2.3 函数的"形参"实际上就是局部变量
2.4 函数内部通过var声明的变量,也是局部变量
2.5 形参也是局部变量
3、作用域链:
3.1、概念 : 一般情况下,变量取值 是到创建这个变量的函数的作用域中取值。但是如果在当前作用域中没有查到值,就会向上级作用域去查,直到查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
3.2、JavaScript 代码是由浏览器中的 "JavaScript解析器"来执行的。JavaScript 解析器在运行 JavaScript 代码的时候分为两步:
第一步: 预解析阶段
1、预解析阶段:在当前作用域下, JS 代码执行之前,浏览器会默认把带有 "var声明的变量" 和 "function关键字声明函数"在内存中进行"提前声明"或者"提前定义"。
2、预解析包括变量提升和函数提升。
2.1 变量预解析(变量声明提升):
变量提升(变量预解析): 变量的声明会被提升到当前作用域的最上面,变量的赋值不会提升。
2.2 函数预解析(函数提升):
函数的声明会被提升到当前作用域的最上面,但是不会调用函数。
2.3 同时存在变量提升以及函数提升, 变量名跟函数名是相同的时候, 函数提升优先级更高 , js 函数又被称为第一等公民。
2.4 函数表达式声明函数问题:
函数表达式创建函数,只会执行"变量提升"
函数表达式就是把一个匿名函数赋值给一个变量
第二步: 代码执行阶段
先进行预解析阶段,再进行代码执行阶段
代码执行阶段: 默认情况下,从上到下执行JS语句。