javascript 基础
书写位置
第一种: 写在script
标签中
第二种: 引入一个 js 文件
注意:
- script 可以放在很多地方,但是我们一般规范写在 body 的最后面;
- 使用 src 引入的标签不能再在标签内写 js 代码 (写了不会执行)
!> 通过 src
请求到的 js
文件,会被解析到 script
标签内,并且覆盖原 script
标签内的 js
代码
!> script 标签的 src 属性可以写任何路径或文件,并不仅仅只能写 js 文件
注释
注释代码不会被执行,仅仅起到一个提示的作用。注释可以对复杂的代码进行解释,方便后期的维护和开发。
单行注释 :
// 这是单行注释, 单行注释只能写一行代码
// 快捷键: ctrl + /多行注释 :
/*
这是多行注释,在多行注释中可以
换行
快捷键 ctrl + shift + /
不可嵌套
*/
输出语句 (5 种)
alert : 警告框
// alert会弹出一个警告框
alert('hello world')confirm : 确认框
// confirm弹出一个确定框
confirm('我帅吗?')prompt : 输入框
// prompt:弹出一个输入框,可以输入值
prompt('请输入你的真是年龄')document.write : 网页中写入内容
// 可以识别标签
document.write('hello world')
document.write('<h1>hello world</h1>')
document.write(Date()) // 输出当前时间console.log:控制台输出
// F12打开控制台,在console中可以看到打印的信息
console.log('hello word')
变量
// var 声明变量 |
变量命名要求(变量是[标识符][1]的一种)
- 以字母、下划线或美元符号($)开头
- 由字母、下划线、美元符号($)和数字组成
- 标识符区分大小写
- 标识符不能使用关键字和保留字
- 如果重新声明 JavaScript 变量,该变量的值不会丢失
var car='yellow'; var car
car 的值依然是 ‘yellow’
关键字 (有特殊意义的一些单词)
break
do
instanceof
typeof
case
else
new
var
in
catch
finally
return
void
continue
for
switch
while
try
debugger
function
this
with
default
if
throw
delete
保留字
abstract
enum
int
short
boolean
export
interface
static
extends
long
super
Char
final
native
Class
synchronized
package
throws
Const
goto
private
transient
degubber
implements
volatile
double
import
public
byte
float
protected
交换两个变量的值
- 使用临时变量 (必须掌握)
var temp = a |
- 不使用临时变量
a = a + b |
基本数据类型
Number
- 浮点数
var num = 3.1416 // 3.1416 |
- 整数
var num = 10 // 10 |
- 特殊值
NaN
Infinity
var num = 1 / 0 // Infinity (无穷大) |
通过
isNaN(num)
可以判断是否是一个数字,返回 false 的时候,表示是一个数字
- 浮点数精度丢失问题
// 在进行浮点数运算的时候,可能会出现精度丢失的问题 |
String
只要是在单引号或双引号内的就是 String
类型
var name1 = 'hello' |
若在字符串中使用引号,字符串中的引号不要与字符串的引号相同,或在字符串添加转义字符
\
字符串可以是对象
var x = 'john' |
Boolean
布尔型,只有 true
和 false
两个值,且是小写
true : 1
、2
、1.1
、-1
、'0'
、'1'
、[]
、Infinity
、-Infinity
、…
false : 0
、''
、null
、NaN
、undefined
所有非 0 数都是 true,0 是 false
var sex = true |
真值: 在 JavaScript 中,**Truthy**(真值)指的是在布尔值上下文中,转换后的值为真的值。所有值都是真值,除非它们被定义为 假值(即除 false
、0
、""
、null
、undefined
和 NaN
以外皆为真值)
Array
var car = new Array() |
关键词
new
用于声明新变量的类型
Object
由花括号分隔,属性和方法的容器;对象的属性以名称和值对的形式 (name : value) 来定义;多个属性由逗号分隔。对象的方法定义了一个函数,并作为对象的属性存储。对象方法通过添加 ()
调用
var cat = new Object() |
对象属性有两种访问方式:
name = cat.name |
对象方法的访问:
eat = cat.eat() // 输出函数执行结果 |
Null
只有一个值:null
,表示对象不存在
var cat = null // 将cat的值清空 |
- str.match()方法匹配不到返回 null
- 通过 document.querySelector、getElementById() 获取不到元素返回 null
Undefined
只有一个值:undefined
- 已声明未赋值的变量
var a |
- 没有明确返回值的变量
// 获取对象不存在的属性 |
typeof 操作符
是一个操作符而不是函数,圆括号可以使用,但不是必需的
var num |
数据类型转换
转换成字符串
- 调用
toString()
方法 (显式转换)
var a = 1 |
null 、undefined 没有 toString() 方法
- 调用
String()
构造函数(显式转换)
var str1 = String(a) |
- 直接和字符串做加法运算(推荐方法) (隐式因式转换)
// 任意数据类型的变量和字符串做加法运算结果都是字符串 |
转换成数值
-
Number(a)
var num1 = Number('123') |
- 使用
parseInt()
var num2 = parseInt('12.3') |
- 使用
parseFloat()
完成
var num3 = parseFloat('12.34') |
- 让字符串和数字做除了加法以外的运算(隐式转换)
var d = '345' |
// 数组转换成 数值 |
补充
parseInt()
函数解析一个字符串参数,指定该字符串为指定基数的进制值,并返回一个 10 进制的整数,如果被解析参数的第一个字符无法被转化成数值类型,则返回NaN
参考 parseInt
// 语法 |
parseFloat()
函数解析一个字符串参数并返回一个浮点数,如果给定值不能被转换成数值,则会返回 NaN。
// 语法 |
转换成布尔值
- 使用
Boolean()
完成
var a = 45 |
0, NaN, 空字符串,undefined, null, false 会被转换成为 false
- 使用
!!
console.log(typeof !!a) // boolean |
- 自动转换
if ('') { |
变量转换表
Value | Boolean | Number | String |
---|---|---|---|
undefined | false | NaN | “undefined” |
null | false | 0 | “null” |
true | true | 1 | “true” |
false | false | 0 | “false” |
“” | false | 0 | “” |
“123” | true | 123 | “123” |
“1a” | true | NaN | “1a” |
0 | false | 0 | “0” |
1 | true | 1 | “1” |
Infinity | true | Infinity | “Infinity” |
NaN | false | NaN | “NaN” |
{} | true | NaN | “[object Object]” |
数组 | true | 空数组为 0,存在一个元素且为数字转数字,其他 NaN | [1, ‘123’, [], undefined, null, NaN, true ] => “1,123,,,,NaN,true” |
操作符
算数操作符
+
、-
、*
、/
、%
var num = 5 + 6 // 11 |
赋值操作符
a = a + 1
即a++
,a = a - 1
即a--
>a = a + 5
可简写成a += 5
,类似的还有a -= 5
、a *= 5
、a /= 5
、x %= y
赋值运算符左边不能是常量或表达式
var age = 10 |
关系操作符
>
、<
、>=
、<=
==
相等 、!=
不相等 、===
全等 、!===
不全等
in
instanceof
var result = 6 > 4 |
运算符的结果类型为 Boolean
>
、<
、>=
、<=
、==
相等、!=
不相等 (字面量比较)在比较前先执行类型转换
- 如果有一个操作数是布尔值,则在比较相等性前先将其转换为数值—false 转换为 0,true 转换为 1
- 如果一个操作数是字符串,另一个操作数是数值,则在比较相等性前将字符串转换为数值
- 如果两个值都是字符串,则按照字符串的字符编码进行逐位比较
- 如果一个操作数是对象,另一个不是,则调用对象的 valueOf()方法,用得到的基本类型值按照前面的规则比较
- 如果两个操作数都是对象,则比较它们是否指向同一个对象
- null 和 undefined 是相等的
- 在比较相等性之前,不能将 null 和 undefined 转换为其他任何值
- 如果有一个操作符是 NaN,则相等操作符返回 false,不相等操作符返回 true;即使两个操作数都是 NaN,也一样
===
全等、!==
不全等
两个操作数在未经转换的情况下相等返回 true,不相等返回 false
0 == false // true |
in
判断对象是否能够访问到该属性
instanceof
判断一个对象是否是另一个对象的实例
逻辑操作符
!
非、&&
与、||
或
!
对 Boolean 值取反
var flag = true |
&&
如果第一个值转换成 boolean 值之后为 true, 则输出第二个值;如果第一个值转换成 boolean 值之后为 false,则输出第一个值,且第二个值不在执行。(取第一个为 false 的值,如果都为 true ,则输出最后一个值。)
var result = true && 3 // 3 |
&&
使用場景
function animate(fn) { |
||
如果第一个值转换成 boolean 值之后为 true, 则输出第一个值,且第二个值不在执行;如果第一个值转换成 boolean 值之后为 false,则输出第二个值,以此类推,(取第一个为 true 的值,如果都为 false ,则输出最后一个值。)
var result = true || 3 // true |
||
使用场景
// 1.兼容性问题: |
操作符的优先级
从高到低如下:
() 优先级最高
一元运算符 ++ – !
算数运算符 先 * / % 后 + -
关系运算符 > >= < <=
相等运算符 == != === !==
逻辑运算符 先 && 后 ||
赋值运算符 =
判断语句
if 语句
- 单独的 if 语句
// 语法 |
if..else
语句
// 语法 |
if..else if ..else
语句
if (条件1) { |
三元运算符
条件 ? 表达式1 : 表达式2 |
switch 语句
if..else 适用于范围的判断,switch..case 适用于具体的值的判断
// 语法 |
注意 :
break 可以省略,如果省略,代码会继续执行下一个 case
switch 语句在比较值时使用的是 全等 操作符, 因此不会发生类型转换(例如,字符串’10’ 不等于数值 10)
循环语句
while 循环
基本语法 :
// 当循环条件为true时,执行循环体 |
代码示例:
// 计算1-100之间所有数的和 (讲) |
do..while 循环
do..while 循环和 while 循环非常像,二者经常可以相互替代,但是 do..while 的特点是不管条件成不成立,都会执行一次。
基础语法 :
do { |
代码示例 :
// 初始化变量 |
for 循环
for 循环语法:
// 1. for循环使用分号分隔 |
执行顺序:1243 —- 243 —–243(直到循环条件变成 false)
- 初始化语句
- 判断语句
- 自增或者自减
- 循环体
for 循环代码示例:
// 打印1-5之间所有数 |
思考 1:
// 1 求1-100之间所有数的和、平均值 |
思考 2:
// 1 计算1-100之间不能被7整除的数的和 |
思考 3(双重 for 循环):
// 1 网页打印5*5方形★阵 document.write() |
for ..in 循环
详见遍历对象
break 和 continue
break: 结束/中止循环(可以用在 switch 语句和循环语句中)
立即跳出当前整个循环,即循环结束,开始执行循环后面的内容(直接跳传出大括号)
continue: 结束本次循环,进行下一次循环 (只能用在循环语句中)
立即跳出当前循环,继续下一次循环(跳到 i++的地方)
在一个循环里,continue 和 break 后面不能在写任何语句,因为永远无法执行到
思考 1 :
// 输出结果是什么? 1 2 3 4 6 |
总结 :
- 循环有很多种,但是以后用得最多的是 for 循环
- 当不明确循环次数的时候,可以使用 while 循环
- 当无论如何都要执行一次代码的时候,可以使用 do..while 循环
- 循环可以相互替代
Array 数组
- 将多个元素,按一定顺序排列放到一个集合中 , 那么这个集合我们就称之为数组
- 可以存放任意类型的数据(一般一个数组只存放一种类型)
- 特点 : 用逗号隔开,有顺序,有长度,数组长度可以动态调整
- 用途 : 存储大量的数据
// 为什么要有数组? |
创建数组
通过 构造函数 创建数组
var arr = new Array() // 创建了一个空数组
var arr = new Array(4) // 创建了一个数组,长度为4,里面全是空值
var arr = new Array('4') // 创建了一个数组,长度为1,内容为字符串 '4'
var arr = new Array(2, 3) // 创建了一个数组,里面存放了2个数字通过 数组字面量 创建数组
var arr1 = [] // 创建一个空数组
var arr2 = [4] // 创建了一个数组,长度为1,内容为数字 4
var arr2 = [2, 3] // 创建一个包含2个数值的数组,多个数组项以逗号隔开
var arr3 = ['2', 'b'] // 创建一个包含两个字符串的数组
数组的长度与下标
数组的长度 : 跟字符串一样,数组有一个 length 属性,, 指数组中存放的元素的个数
var arr = [] // 空数组 长度为 0
var arr = [1, 3, 5]
arr.length // 长度就是3
arr.length = 0 // 设置length属性改变数组中元素的个数数组的下标(又称索引) : 因为数组有序的,有序的就应该有自己的序号,而这个序号就是每个元素对应的下标,下标从 0 开始 , 到 arr.length-1 结束
// 数组取值,如果下标不存在,则返回 undefined
var arr = ['zs', 'ls', 'ww']
arr[0] // zs
arr[2] // ww
arr[5] // undefined
// 数组的赋值
// 格式:数组名[下标] = 值
// 如果下标有对应的值,会把原来的值覆盖,如果下标不存在,会给数组新增一个元素。
var arr = ['red', 'green', 'blue']
arr[0] = 'yellow' // 把red替换成了yellow
arr[3] = 'pink' // 给数组新增加了一个pink的值
// 如果下标有跨度,中间全是empty 不合法
// 在数组末尾添加新的元素
arr[arr.length] = 值
arr.push(值)
数组的遍历
遍历 : 对数组的每一个元素都访问一次就叫遍历
数组遍历的基本语法:
for (var i = 0; i < arr.length; i++) { |
冒泡排序
// 将数组中的数从小到大排列 |
函数
把一段相对独立的具有特定功能的代码块封装起来,形成一个独立实体,就是函数
函数的作用就是封装一段代码,只需要声明一次,就可以被多次调用
提高代码的复用率,提高可维护性
函数三要素包括:函数名、参数、返回值
函数的声明与调用
// 函数声明 |
特点:
- 函数声明的时候,函数体并不会执行,函数体只有在调用的时候才会执行
- 可多次调用
练习:
// 1. 封装一个打招呼的函数 |
函数的参数(arguments)
- 形参 ( 形式参数 ) : 在函数声明时, 设置的参数。作用是占位置 。
- 实参 ( 实际参数 ) : 在函数调用时传入的参数。 作用 : 函数调用时,会把实参的值赋值给形参,这样形参就有了值,在函数体里,可以直接使用形参!
语法 :
// 带参数的函数声明 |
- 如果实参的个数大于形参的个数,多余的实参会被 保存到函数的 arguments 对象里,arguments 对象里保存了所有的实参,arguments 是一个伪数组(可以像数组一样使用)
- 如果实参的个数小于形参的个数,不够的参数会用 undefined 来补充
// 实参个数大于形参个数 |
函数的返回值
当函数执行完的时候,我们期望函数给我一些反馈(比如计算的结果),这个时候可以让函数返回一些东西。也就是返回值。函数通过 return 返回一个返回值
返回值语法:
// 声明一个带返回值的函数 |
函数返回值注意事项:
- return 语句代表一个函数的结束,后面不能再有语句(语句不会执行)
- 函数可以没有返回值,函数如果没有 return,那么返回结果是 undefined
- 函数的参数可以有多个,但是返回值只能有 1 个
return
在函数包含判断语句时,可以用来直接停掉一个函数的执行
练习:
// 1. 求两个数的最大值,并且返回。 |
函数内部调用函数
在函数内部是可以继续调用别的函数的。
// 求阶乘 |
函数是一种数据类型(function)
函数可以作为参数
通常,我们把作为参数传递的函数叫做回调函数
function fn1(fn) { |
函数可以作为返回值
在 js 高级中,闭包会使用到
function fn1() { |
匿名函数与自执行函数
自执行函数
函数可以自执行
;(function fn() { |
匿名函数
匿名函数:没有名字的函数
// 匿名自调用函数 ,用完一次就没了 |
匿名函数如何使用:
1. 将匿名函数赋值给一个变量,这样就可以通过变量进行调用 |
匿名函数自执行的作用:防止全局变量污染。
函数的断点调试
- 跳到下个断点, 如果后面没有断点了,那么代码直接执行完
- 单步调试 : 下一步 没有断点的话,函数就直接跳过
- 单步调试 : 进入函数
- 单步调试 : 跳出函数
- 单步调试 : 下一步 不管有没有断点,都会一步一步的走,纯碎的下一步
- 让所有的断点失效
- 自动根据错误断点
函数的重载
如果多个函数的函数名相同,但是参数或返回值不同,这些函数是不同的函数
参数不同指 1. 参数的个数不同 2. 参数的数据类型不同
js 中不允许函数的重载,即在 js 中,只要函数名一样,就是同一个函数,如果两个函数名相同,后边的会覆盖前边的
对象
对象 : 是一组无序的键(key)值(value)对的集合,有对应的属性和方法
特点 :
1. 声明的变量 = {}
2. 键值对出现
3. 逗号隔开
4. 属性可以是任意类型
// 数组多个元素之间使用,隔开 |
this 的基本概念
创建对象-1 (2 种方式 单创)
单纯的创建一个对象
对象字面量
字面量 : 直接量,通过看数值,直接看出来类型的
var p = {} |
通过 Object 构造函数创建
var p = new Object() // 创建一个空的对象 |
设置对象的属性
// 设置对象的属性 语法 对象名.属性 = 值 |
创建对象-2 (2 种方式 批量)
批量创建对象
在实际开发中,经常需要创建多个相同类型的对象,比如游戏中的怪物,班级的学生等。
使用工厂函数创建对象
// 定义一个函数,用于创建学生对象 |
优点:可以同时创建多个对象
缺点:创建出来的没有具体的类型,都是 object 类型的
自定义构造函数:triangular_flag_on_post:
工厂函数的缺点 就是无法确定对象的具体类型
构造函数 ,是一种特殊的函数。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与 new 运算符一起使用在创建对象的语句中。
function Teacher(name, age) { |
- 构造函数首字母要大写(推荐做法)
- 构造函数要和 new 一起使用才有意义
- 构造函数的作用是用于实例化一个对象,即给对象添加属性和方法
new 在执行时会做四件事情
1. new 会创建一个新的空对象,类型是Teacher |
查看一个对象的类型(类型识别)
typeof // 只能查看基本数据类型的类型 |
typeof
用于查看基本数据的数据类型, number string boolean undefined
null 比较特殊,结果是 object
如果查看复杂数据类型,返回的都是 object 类型
函数的结果是 function
// typeof 判断 |
instanceof 判断
// 语法 |
用来检测 constructor.prototype
是否存在于参数 object
的原型链中
不能用于类型识别
// instanceof 判断 |
constructor.name
Undefined/Null 没有 constructor 属性
var myArr = [] |
Object.prototype.toString
适用于任何类型的检测,不能识别自定义对象类型
Object.prototype.toString.call('str') // '[object String]' |
操作对象的属性
.
语法 —– 对象名.属性名 ( 看似变量,不是字符串 )
[]
语法 —- 对象名 属性字符串 ,也叫关联数组的方式
// 获取对象属性的语法: |
二者的区别:当属性名是一个字符串存储在变量中的时候,只能使用关联数组的方式。
应用场景 : 遍历对象
删除对象属性
// 删除对象属性 |
遍历对象
通过 for..in
循环语法可以遍历一个对象
// 遍历对象 |
原始类型与引用类型
- 原始类型(简单数据类型/值类型)
Number
String
Boolean
Undefined
Null
- 引用类型(复杂数据类型)
Object
Array
function
自定义的对象
var num1 = 123 |
原始数据类型和引用数据类型,主要是根据内存存储方式来区分的
- 原始类型储存在栈(Stack)中,存的是值本身(值类型),进行赋值的时候,赋值的是值本身
- 引用类型储存在堆(Heap)中,并非储存变量真实数值而是引用(也叫地址),进行赋值的时候,赋值的是地址,而不是数据本身
// 1. |
object.valueOf()
返回值为该对象的原始值,如果对象没有原始值,则 valueOf
将返回对象本身
对象 | 返回值 |
---|---|
Array | 返回数组对象本身 |
Boolean | 布尔值 |
Date | 存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC |
Function | 函数本身 |
Number | 数字值 |
Object | 对象本身 (这是默认情况) |
String | 字符串值 |
Math 和 Error 对象没有 valueOf 方法 |
内置对象
JS 内置对象就是指 Javascript 自带的一些对象,供开发者使用,这些对象提供了一些常用的的功能。
常见的内置对象有 Math、String、Array、Date 等
- 跳转到定义
ctrl+左键
- 火狐开发者网站 MDN
- W3School 网站
如何学习一个方法?
- 方法的功能
- 参数的意义和类型
- 返回值意义和类型
- demo 进行测试
Math 对象
属性 PI
Math.PI
最大值/最小值
Math.max() |
- 取整
Math.ceil() // 向上取整 |
- 随机数
Math.random() // 返回一个[0,1)之间的数,能取到0,取不到1 |
- 绝对值
Math.abs() // 求绝对值 |
- 次幂和平方
Math.pow(num, power) // 求 num 的 power 次方 |
- 练习
// 随机生成一个 rgb 颜色? |
Date 对象
Date 对象用来处理日期和时间
- 创建一个日期对象
// 不传参数:创建一个当前时间的对象 |
- 日期格式化(了解)
date.toString() // 默认的日期格式 ,包括日期和时间 |
- 获取日期的指定部分
getMilliseconds() // 获取毫秒值 |
- 时间戳
var date = +new Date() // 1970年01月01日00时00分00秒起至现在的总毫秒数 |
Array 对象
数组对象在 javascript 中非常的常用
- 数组转换
// 语法:arr.join(separator) |
- 数组的增删操作
arr.push() // 从后面添加一个或多个元素,逗号隔开,返回新数组的 length |
- 数组的翻转与排序
arr.reverse() // 翻转数组 |
// 思考: |
- 数组的拼接与截取
// concat:数组合并,返回一个新数组,原数组不受影响 |
- 数组查找元素
// indexOf 方法返回数组中某个元素第一次出现的位置,如果找不到,返回 -1 |
- 清空数组
// 1. arr.splice(0,arr.length) // 删除数组中所有的元素 |
- 数组综合练习
var arr = ['c', 'a', 'z', 'a', 'x', 'a', 'a', 'z', 'c', 'x', 'a', 'x'] |
!> 补充数组对象方法
forEach()
// 语法 |
arr.map()
// 语法 |
arr.filter()
// 语法 |
arr.some()
// 语法 |
arr.every()
// 语法 |
arr.includes()
判断数组是否含有某值,输出 true 或 false
var new1 = arr.includes(5) |
必须完全匹配才会返回 flase(实用性不如正则)
arr.find()
// 语法 |
arr.findIndex()
// 语法 |
arr.reduce()
// 语法 |
// 扁平化数组 |
// 对象数组叠加计算 |
基本包装类型
简单数据类型是没有方法的。为了方便操作基本数据类型,JavaScript 还提供了三个特殊的引用类型:String/Number/Boolean
基本包装类型:把基本类型包装成复杂类型
var str = 'abc' |
Number 对象
Number 对象是数字的包装类型,数字可以直接使用这些方法
num.toFixed(2)
:返回保留 2 位小数的新数的字符串格式num.toString()
:转换成字符串并返回
Boolean 对象
Boolean 对象是布尔类型的包装类型
toString() // 转换成字符串并返回 |
undefined 和 null 没有包装类型,所以调用 toString 方法会报错
String 对象
字符串可以看成是一个字符数组(伪数组)。因此字符串也有长度,也可以进行遍历。String 对象很多方法的名字和 Array 的一样。
操作字符串的方法不会改变原来的字符串,需要新字符串去接收
- 查找指定字符串
str.indexOf(‘‘) // 获取某个字符串第一次出现的位置,如果没有,返回-1 |
- 去除空白
str.trim() // 去除字符串两边的空格,内部空格不会去除 |
- 大小写转换
str.toUpperCase() // 全部转换成大写字母 |
- 字符串拼接与截取
// 字符串拼接 可以用 concat,用法与数组一样,但是字符串拼串我们一般都用 + |
- 字符串切割
// 将字符串分割成数组(很常用) |
- 字符串替换
// 语法 |
replace() 方法的参数 replacement 可以是函数而不是字符串。在这种情况下,每个匹配都调用该函数,它返回的字符串将作为替换文本使用。该函数的第一个参数是匹配模式的字符串。接下来的参数是与模式中的子表达式匹配的字符串,可以有 0 个或多个这样的参数。接下来的参数是一个整数,声明了匹配在 stringObject 中出现的位置。最后一个参数是 stringObject 本身。
- 访问
str[i] |
- 练习
1. 截取字符串’我爱中华人民共和国’,中的’中华’ |
// 寻找重复最多的字符以及个数 |