根据前端技能树补缺JS知识
JS简介
一种运行在客户端的编程语言,实现人机交互效果
作用有:
- 网页特效
- 表单验证
- 数据交互
- 服务端编程(node.js)
JS组成:
- ECMAScript(JavaScript语法基础)
- 变量、分支语句、循环语句、对象
- Web APIs
- DOM页面文档对象模型
- 操作文档,比如页面元素移动、大小、增删
- BOM浏览器对象模型
- 操作浏览器,页面弹窗、检测窗口宽度、存储数据到浏览器
- DOM页面文档对象模型
JS引入方式:
- 行内
onclick="alert()"
这样的写法即是行内JS
- 内部
- 写在
</body>
的上面,即HTML的底部,这是因为浏览器会按照代码先后顺序加载HTML
- 写在
- 外部
- 使用
<script src="..."></script>
引入,script一旦设置了src属性,标签间的代码将会被忽略
- 使用
JS注释:
- 单行
/
- 多行
/* */
结束符:
- 以
;
结束,但可写可不写
JS IO语法:
- 输出:
document.write()
向body内输出内容,其中使用的HTML语法也会被解析alert
弹出对话框console.log()
控制台打印输出console.dir()
控制台打印对象
- 输入:
let name = prommpt()
弹出框输入
字面量
例如字符串‘Hello World’
,其中Hello World
就是字符串字面量
变量
变量声明
Let
关键字声明变量(ES6中定义局部变量)(ES5中使用var,但var声明的变量均为全局变量,导致作用域混乱污染代码)
Let & Var
Var
- var变量的作用域时整个封闭函数
- 如果在var变量声明之前打印该变量,将会返回undefined
var的一大作用是变量提升:
由于变量的声明总是在任意代码执行之前,所以Var变量认为在代码的任意位置声明变量总是等效于在代码的开头声明,即变量可以在被声明之前使用,这个行为被称作“hoisting”,就像把所有的变量声明都移动到了函数或者全局代码的开头
而这一特性也导致了var存在很多不方便的地方例如:
- 可以重复声明
- 变量均为全局变量
- 没有块级作用域
Let
let允许声明一个作用域被限制在块
作用域的变量
- 作用域规则:
- Let声明的变量的作用域只在其声明的块或子块内部
- let在同一个函数或块作用域中重复声明同一变量会报错
- 暂时性死区TDZ
- 一个代码块开始知道代码执行到声明变量的行之前,let和const声明的变量都处于暂时性死区TDZ中
- 访问这些变量会导致
ReferenceError
错误
变量命名
JS的变量可以使用字母数字下划线和**$**符号,不能以数字开头
通常JS使用小驼峰命名法
常量
- 常量保存的值不允许重新赋值
- 常量声明的时候必须赋值
- 常量作用域与let相同
数据类型
JS是弱数据类型的语言:变量只有赋值后才知道变量类型
基本数据类型——变量中存储值,用栈存储
number
- +、-、*、/、%
- NaN: not a number代表计算错误
- NaN是一个粘性的,无论与什么数字操作都是NaN
- 甚至NaN === NaN的值为False
string
boolean
undefined:没有赋值
- undefined + 1 = NaN
null:赋值了但内容为空,是一个对象
- null + 1 = 1
引用数据类型——变量中存储地址,在栈中存一个堆中的地址,实际数据在堆中存储
- object
字符串
- 单双引号没有区别
- 反引号`也可以
- 推荐使用单引号
- 单引号中需要嵌套双引号,双引号同理,或者使用
\
转义 - 模板字符串:
- 使用反引号表示
- 变量使用
${}
包裹
数组
- 数组有序
- 数组字面量用
[]
表示 - 数组的声明:
let arr = [item1, item2]
- 长度可访问:
arr.length
增
arr.push()
添加到数组末尾arr.unshift()
添加到数组开头
删
arr.pop()
删除最后一个元素arr.shift()
删除第一个元素arr.splice(start, deleteCount)
删除一段
对象
- 一种无须数据集合
- 引用数据类型
- 对象声明
let obj = {}
let obj = new Object()
- 增
obj.newAttr = newValue
- 删
delete obj.attr
- 改
obj.attr = newValue
- 查
obj.attr
obj['attrName']
- 对象方法:
functionName(): function(){}
检测数据类型
使用typeof num
(typeof()
的缩写)查看某一变量的数据类型
数据类型转换
隐式类型转换
执行时编译器将自动进行类型转换:
- +号两边只要有一个字符串,就会把另一个转化为字符串
- +号后跟一个字符串,将会把字符串转化为数字
- -号会使空字符串转换为0
- null经过数字转换后为0
- undefined经过数字转换后为0
- 除了+以外的算术运算符都会把数据转化为数字类型
显式类型转换
Number()
直接将字符串转换为数字parseInt()
保留整数,只保留字符串开头的能转化为整数的部分(小数也舍去)parseFloat
保留字符串中开头的浮点数
Boolean类型转化
- “”,0,undefined, null, false, NaN转化为bool类型均为False
- 其余为True
运算符
赋值运算符
- =
- +=
- -=
- *=
- /=
- %=
一元运算符
- 自增:++(前置后置与C语言相同)
- 前置先+再赋值
- 后置先赋值再+
- 自减:–
比较运算符
- >
- <
- >=
- <=
- ==
- 只判断值:会发生隐式类型转换
- undefined == null返回true
- ===:判断值和类型
- !==:是否不全等
- NaN不等于任何值,包括本身
- 尽量不要比较小数,因为有精度问题
- 不同类型之间的比较会引发隐式类型转换
- 开发中尽量使用===
逻辑运算符
- &&
- ||
- !
运算符优先级
- ()
- 一元运算符: ++、–、!
- 算术运算符:先* / % 后 + -
- 关系运算符: > >= < <=
- 相等运算符:==、 !=、 === 、! ==
- 逻辑运算符:先&&后||
- 赋值运算符: =
- 逗号运算符:,
三元运算符
terms ? expression1 : expression2
语句
- 表达式:可以被求值的代码
- 语句:不一定有值
分支语句
- if
- 单分支
- 双分支
- 多分支
- 三元运算符
- switch(与C相同)
- switch判断分支时必须全等
循环语句
- for
- for(变量起始; 终止条件; 变量变化)
- for…in
for(let k in arr)
返回数组下标,但值为字符串类型for(let k in obj){console.log(obj[k])}
- while
函数
作用域
- 全局作用域
- 作用于所有代码执行的环节(整个script标签内)
- 一个独立的JS文件
- 局部作用域
- 作用于函数内部的代码环境
- 也叫函数作用域
匿名函数
- 函数表达式
- 将匿名函数赋值给变量
- 通过变量调用函数
let fn = function(){}
- 立即执行函数
- 避免全局变量之间的污染
(function(){console.log(11)})()
使用这一写法时两个连续的立即执行函数间必须使用分号分隔(function(){}())
Math内置对象
- random
- 生成一个[0,1)之间的数
- ceil 向上取整
- floor 向下取整
- round 四舍五入 对于负数要小心
- max
- min
- pow
- abs
- …