「JS系列之基础整理」扫盲(1)

687 阅读7分钟

各位看客,本人将会整理js相关一些案例,目前主要划分为【基础整理】【es6归纳】【案例分享】【踩坑之旅】四个板块,本期以【基础整理】先扫盲知识点,一些常用的知识点会有相关demo说明,其他知识将不在鳌述。得,我是阿树,让我们一起做一些扫盲前的了解吧!

首先,我们需要知道浏览器分成渲染引擎JS引擎两部分:

  • 渲染引擎: 就是我们所谓的内核,它是用来解析HTML和CSS的,至于如何渲染解析,如果大家感兴趣,后续我单独整理一些资料供大家参考;
  • JS引擎: 说的通俗一点,就是我们和浏览器之间的翻译官,之所以JS被成为脚本语言,是因为浏览器并不认识JS代码,所以它需要通过JS引擎来将其翻译成计算机认识的机器语言。

接着,JS 是分为 ECMAScriptBOMDOM三部分的:

  • ECMAScript: 我们可以理解其为圣经,是其给出了JS的核心知识以及相关编程语法;
  • DOM: 文档对象模型,它为我们提供了一系列的API,我们可以通过这些对页面上的各种元素进行操作;
  • BOM: 浏览器对象模型,我们可以通过它提供的一些API与浏览器直接进行交互,比如浏览器的跳转刷新、窗口的大小等等。

最后,我们需要了解一下JS在编写的时候需要写在哪里:

  • 行内式: 一般来说:该方法用的较少,直接在标签内进行代码的编写不利于维护,也影响性能
<button onclick=" alert('你咋不上天呢?')">点击我弹出内容</button>
  • 内嵌式
<script>
  console.log('这世界很酷')
</script>
  • 外部引入JS文件 需要注意的是:如果script的标签引入了外部文件,其标签内是不允许在写JS代码的。一般来说 JS文件引入均放在html文件尾部
<script src="outFile.js"></script>

有了以上的了解,让我们一起开启JS的基础扫盲吧:

一、变量

1.1 变量是什么

  • 本质:变量就是在内存中申请了一个存储空间,方便我们存放数据。
  • 通俗:变量就是存放数据的容器。
  • 类比:自动售货机中的每一个方格,我们通过指定方格按键,来获取方格中的货物。同样,我们通过变量名来获取,变量中的数据。

1.2 变量怎么使用

变量的使用就好似我们建仓库存放货物,第一步就是声明变量即创建仓库,第二步给变量赋值即给仓库存放货物,第三部使用变量名即提取货物。

1.2.1 声明变量:

var name 
// 声明了一个名称为name的变量,相当于给仓库起了个名字为name
// var 是关键字 是用来声明变量的

小常识: 熟悉 js 中的标识符、关键字、保留字

  1. 标识符

所谓标识符,就是指变量、函数、属性的名字,或者函数的参数

第一字符必须是一个字母、下划线(_)、或一个美元符号($);其它字符可以是字母、下划线、美元符号或数字;不能把关键字、保留字、true、false和null等用作标识符。

  1. 关键字

ECMA-262描述了一组具有特定用途的关键字,这些关键字可用于表示控制语句的开始或结束,或者用于执行特定操作等。按照规则,关键字也是语言保留的,不能用作标识符。以下就是ECMAScript的全部关键字:

caseelsenewvar
breakdoinstanceoftypeof
finallyreturnvoidcontinue
forswitchwhiledebugger
functionthiswithdefault
ifthrowintry 、delete
  1. 保留字

ECMA-262描述了另外一组不能用作标识符的保留字。尽管保留字在这门语言中还没有任何特定的用途,但他们有可能在将来被用作关键字:

abstractenumintshort
booleanexportinterfacestatic
byteextendslongsuper
charfinalnativesynchronized
classfloatpackagethrows
constgotoprivatetransient
debuggerimplementsprotectedvolatile
doubleimportpublic

第5版把在非严格模式下运行时的保留字缩减为下列这些:

classenumextendssuper
constexportimport

第5版在严格模式下对以下保留字加了限制:

classenumextendssuper
constexportimportimplements
packagepublicinterfaceprivate
staticletprotectedyield

1.2.2 变量赋值:

name = '世界这么大,我想去看看!' // 给 name 中塞入 '世界这么大,我想去看看!' 数据即货物

1.2.3 变量提取:

console.log(name) // 将name所代表的数据读取出来,即从name仓库中提取'世界这么大,我想去看看!'这个货物

1.2.4 变量更新:

var age
age = 10
age = 18 
// 这时候18将10覆盖,即age代表的数据就是18,
// 相当于age这个仓库只能一次性存储,想要存储新的货物,必须将之前的清空

var arr
arr = ['1']
arr.push('2') 
// 这时 arr中的货物是['1', '2']这是因为仓库的类型不同,
// 存储的选择也就有所不同,当然我们也可以将之前的覆盖,但这个更多的是可以新增货物。

1.2.5 变量使用错误的三种场景:

var sex 
console.log(sex) 
// 只声明 不赋值
// 这时候 读取出来的是 undefined  就相当于我们只是给仓库起了名字,还没有创建

console.log(year)
// 不声明 不赋值
// 这时候会报错, 因为我们连这个仓库名都没有

month = 10
console.log(month)
// 不声明 只赋值
// 这时候我们提取出来10 就相当于黑户 没有官方手续的仓库

1.2.6 变量初始化

在声明变量的同时给其赋值

var dream = '我是初始化值'

1.2.7 变量命名规范

  • 区分大小写;
  • 有字母、数字、下划线( _ )、美元符号($)组成;
  • 不能以数字开头;
  • 不能是关键字、保留字;
  • 使用驼峰命名规则(大驼峰---MyAge、小驼峰---myAge);
  • 通常语意化命名;

二、数据类型

JavaScript是一种弱类型语言,即使我们在声明变量的时候不去声明其类型,在代码执行的时候,js殷勤也会根据其 ‘=’右边的 赋值的值类型判断其数据类型。

2.1 简单数据类型

2.1.1 Number(数字型)

数字型包含整型浮点型两种数据。数字型的三个特殊值:

  • NaN NaN的设计,解决了js中任何数除以零报错等终止程序的场景,因为其返回的是NaN,能够让程序继续运行。关于NaN还有两个特点需要注意:
    • 任何关于NaN的算数操作返回的都是NaN;
console.log(NaN / 10) // NaN
    • NAN与任何值都不相等,包括其本身。
console.log(NaN == NaN) // fasle
  • Infinity, 无穷大,大于任何数值
console.log(Infinity > 1000) // true
  • -Infinity, 无穷小,小于任何数值
console.log(-Infinity < -1000) // true

我们可以使用 isNaN() 来判断一个变量是否为数字型。如果变量是数字 返回 false 如果变量不是一个数字 返回 true

let num = 123
let name = 'xiao'
console.log(isNaN(num)) // false
console.log(isNaN(name)) // true

2.1.2 String(字符串)

字符串可以由单引号(')或双引号(")表示。 string类型有些特殊,因为字符串具有可变的大小,所以显然它不能被直接存储在具有固定大小的变量中。由于效率的原因,我们希望JS只复制对字符串的引用,而不是字符串的内容。但是另一方面,字符串在许多方面都和基本类型的表现相似,而字符串是不可变的这一事实(即没法改变一个字符串值的内容),因此可以将字符串看成行为与基本类型相似的不可变引用类型

  • 字符串转义字符: 转义符 | 含义 |转义符 | 含义 | :---:|:---:|:---:|:---:| \n | 换行符 | \" | 双引号 | \\ | 斜杠 | \' | 单引号 | \t | tab缩进 | \b | 空格 |

2.1.3 Boolean(布尔型)

布尔型有两个值 true 和 false,等价于 1 和 0.JavaScript中所有类型的值都有与这两个Boolean值等价的值。要将一个值转换为其对应的Boolean值,可以调用类型转换函数Boolean()

let name = 'test'
let newName = Boolean(name) 
console.log(newName) // true

2.1.4 Undefined

Undefined类型只有一个值,即特殊的undefined。在使用var声明变量但未对其加以初始化时,这个变量的值就是undefined。

2.1.5 Null

Null类型是第二个只有一个值的数据类型,这个特殊的值是null。从逻辑角度来看,null值表示一个空对象指针,而这也正是使用typeof操作符检测null时会返回object的原因。需要注意的是,undefined值是派生自null值的,因此ECMA-262规定对它们的相等性测试要返回true。

console.log(typeof Null) // object
let name
let age = null
console.log(name == age) // true

2.1.6 symbol

Symbol 是一种特殊的、不可变的数据类型,可以作为对象属性的标识符使用,表示独一无二的值。这个数据类型是ES6新增类型,后续整理ES6时再做详细说明。

2.2 简单数据类型转换

2.2.1 转换为字符串

  • toString()
let age = 100;
console.log(age.toString())
  • String() 强制转换
let age = 100;
console.log(String(age))
  • +符号拼接() 隐式转换
let age = 100;
console.log(age + '')

2.2.2 转换为数字类型

  • parseInt(string) 转换成整型数字型
let name = '100';
console.log(typeof parseInt(name))
  • parseFloat(string) 转换成浮点型数字型
let name = '100';
console.log(typeof parseFloat(name))
  • Number(string) 转换成数字型
let name = '100';
console.log(typeof Number(name))
  • (* / -) 隐式转换
let name = '100';
console.log(typeof Number(name - 10))

2.2.3 转换为布尔型

  • Boolean()函数
    1. 代表空的、否定的值会被转换成false 如:null,0,undefined,NaN,‘’
    1. 其余的值都会被转换成 true
console.log( Boolean('')) // false
console.log( Boolean(0)) // false

三、运算符

3.1 算数运算符

加(+)、减(-)、乘(*)、除(/)、取余(%)

3.2 递增递减运算符

递增(++)、递减(--)
放在变量前边是称之为 前置递增(递减) 先自加 后返回值
放在变量后边是称之为 后置递增(递减) 先返回值 后自加

3.3 比较运算符

'>', '<', '>=', '<=', '==', '!=', '===', '!=='
其中需要注意的是 ‘===’ 和 ‘==’ 的区别
‘===’ 要求两边的值 与 类型均相等 才为true
‘==’ 要求两边的值相等 就为true

3.4 逻辑运算符

逻辑与‘&&’、逻辑或‘||’、逻辑非‘!’

  • && (8 > 4 && 9 < 100) 只有当所有的表达式均为true 结果才为true
  • || (8 < 4 || 9 < 100) 只要有一个表达式结果为true 结果就为true
  • ! (!(9 < 100)) 取反符,如果表达式为true 则结果为false

逻辑短路运算
当有多个表达式的时候,如果左边的结果已经可以决定最终的结果了,那就不执行后边的表达式了

  • &&

语法 表达式1 && 表达式2
如果第一个表达式为真,返回表达式2 如果第一个表达式为假,返回表达式1

  • ||

语法 表达式1 || 表达式2
如果第一个表达式为真,返回表达式1 如果第一个表达式为假,返回表达式2

 let num = 10;
 console.log(100 || num++) // 100
 console.log(num) // 10
 console.log(100 && num++) // 10
 console.log(num) // 11
 console.log(100 && ++num) // 12
 console.log(num) // 12

3.5 赋值运算符

=、 +=、 -=、 *=、 /=、 %=

  • sum += 5 相当于 sum = sum + 5;
  • sum -= 5 相当于 sum = sum - 5;
  • sum /= 5 相当于 sum = sum / 5;
  • sum %= 5 相当于 sum = sum % 5;

3.6 运算符优先级

优先级运算符顺序
1小括号()
2一元运算符++、--、!
3算术运算符先*、/、%,后 + -
4关系运算符>,>=,<,<=
5相等运算符==、!=、===、!==
6逻辑运算符先 && 后 ||
7赋值运算符=
8逗号运算符

四、 流程控制

流程控制指的就是我们所编写的代码按照什么样的顺序执行,总体分为三类:顺序结构、分支结构、循环结构

4.1 顺序结构

顺序结构就是代码按照我们编写的顺序逐行进行解析执行,没有拐点。

4.2 分支结构

分支结构就是我们所编写的代码在执行的时候,遇到条件判断,根据条件的结果不同,从而进入不同的代码体执行代码的结构。

4.2.1 if 语句

if(条件表达式) {
	条件成立所执行的代码体
}

4.2.2 if --- else 语句

if(条件表达式) {
	条件成立所执行的代码体
} else {
	条件不成立所执行的代码体
}

4.2.3 if --- else if --- else 语句

if(表达式1) {
	表达式1成立所执行的代码体
} else if(表达式2) {
	表达式2成立所执行的代码体
} else {
	表达式均不成立所执行的代码体
}

4.2.4 switch 语句 多分枝语句

如果不再写break,那么会发生击穿,继续执行后续的case;

switch (表达式) {
  case1: 表达式的值===值1所执行的代码体; break;
  case2: 表达式的值===值2所执行的代码体; break;
  case3: 表达式的值===值3所执行的代码体; break;
  ······
  default: 表达式的值与case中的值均不匹配所执行的代码体; break;
}

4.3 循环结构

4.3.1 for循环

for (初始化变量;条件表达式;操作表达式) {
  循环体
}
for (let i = 0; i <= 5; i++) {
  console.log(i)
}
4.3.1.1 for循环执行顺序:
  • 执行初始化变量 let i = 0;只执行一次;
  • 判断是否满足条件 i <= 5;
  • 满足执行循环体,不满足跳出循环
  • 循环体执行完成后,执行 i++;
  • 重复2、3、4 直到跳出循环。
4.3.1.2 双重for循环
for (外层初始化变量;外层条件表达式;外层操作表达式) {
  for (内层初始化变量;内层条件表达式;内层操作表达式) {
    循环体
  }
}
4.3.1.3 九九乘法表 案例

实现思路

  • 双重for循环 外层控制行9行 内层控制列 9列
  • 每次完成一行需要换行 \n实现,完成一列需要加空格 \t来实现
let result = ''
for(let i = 1; i <= 9; i++) {
  for(let j =1; j <= i; j++) {
    result += j + '*' + i + '=' + j * i + '\t' 
  }
  result += '\n'
}
console.log(result)

效果展示 :

4.3.2 while循环

while (条件) {
  循环体
}
while (i<5) {
  x=x + "当前数字是 " + i + "<br>";
  i++;
}

while循环执行顺序

  • 判断条件是否满足
  • 满足执行循环体,不满足执行循环后续代码;
  • 循环体执行完成继续判断条件是否满足...

4.3.2 do...while循环

do/while 循环是 while 循环的变体。该循环会在检查条件是否为真之前执行一次代码块,然后如果条件为真的话,就会重复这个循环。

do {
  循环体
} while (条件);

do {
  console.log('当前值', i)
  i++;
} while (i<5);

do...while 的执行顺序

  • 首先执行一次循环体
  • 执行循环体完成后,判断条件是否满足
  • 满足继续执行循环体,不满足执行后续代码...

4.4 return , break, continue的区别

4.4.1 continue

continue只是中止本次循环,接着开始下一次循环

案例

function testContinue() {
    for (let i = 0; i < 5; i++) {

        if (i == 3) {
            continue;
        }
        console.log("--return------------" + i);
    }

    console.log("--return-------for循环外-----");
}
testContinue()
console.log('函数之外的代码')

结果展示

4.4.2 break

break用于完全结束一个循环,跳出循环体

案例

function testBreak() {
    for (let i = 0; i < 5; i++) {

        if (i == 3) {
            break;
        }
        console.log("--testBreak------------" + i);
    }

    console.log("--testBreak-------for循环外-----");
}
testBreak()
console.log('函数之外的代码')

结果展示

4.4.2 return

return关键字并不是专门用于跳出循环的,return的功能是结束一个方法。

案例

function testReturn() {
    for (let i = 0; i < 5; i++) {

        if (i == 3) {
            return;
        }
        console.log("--testReturn------------" + i);
    }

    console.log("--testReturn-------for循环外-----");
}
testReturn()
console.log('函数之外的代码')

结果展示

四、 小结

说实在的,这些基础知识网上已经海量存储了,自己整理这些也不见得比别人要好,但是自己这边想借着这次机会,系统的过一遍,省的之后麻烦。刚开始这些知识点相对简单,案例相对较少,所以比较枯燥,下一期我这边会整理关于数组的一些东西,这期整理的内容有些多了,大家能看到最后的应该不多,衷心的希望大家能够给出意见指导,我后续补充更新~~!我是阿树,我们下期见~~~

五、参考文献:

  • JavaScript高级程序设计(第三版)
  • B站 黑马程序员 pink老师相关视频