JS基础浓缩
一、JS
是一种运行在客户端的脚本语言
- 客户端: 相对于服务端, 暂时理解为浏览器
- 脚本语言: 源代码 --> 预解析 --> 运行; 运行一行, 解析一行
二、js
分为三个部分
ECMAScript
: 规定语法的规范- DOM: 操作界面元素的一套方法
- BOM: 操作浏览器功能的一套方法
三、注释
- 单行注释
- 多行注释
- 文档注释: js函数说明, 打包的时候不会被清理掉
四、常见的输入输出语句
- 提示弹窗:
alert('我还是个宝宝')
- 确认弹窗:
confirm('你还是个宝宝吗?')
- 文本输入弹窗:
pormpt('请输入您的银行卡密码')
- 向页面写入:
- 内容:
document.write('你好')
- 标签:
document.write(<p>放个屁</p>)
- 在控制台里输出一段日志:
console.log('我是路飞')
五、计算机的组成
- 硬件
CPU 内存 硬盘 - 软件
- 系统软件(操作系统)
- Windows系列:
windows 98/2000/xp/vista/7/8/10(PC端)
windwos server 20000/2003/2008 (服务端) - Unix 系列 (不开源的操作系统,付费)
MacOS(苹果电脑操作系统) iOS(苹果手机操作系统)
Linux(开源操作系统) Android
- Windows系列:
- 应用软件
QQ Chrome LOL WebStorm
- 系统软件(操作系统)
六、变量(可以变化的量)
- 定义: 是内存中存储数据的标识符
- 使用变量常见方式:
- 声明的同时, 赋值
- 先声明, 再赋值
- 不声明, 直接赋值(慎用, 会有问题)
- 不声明, 不赋值, 直接使用(window(BOM)的属性:name, top)
- 同时声明多个变量
- 命名规则:
- 字母/数组/下划线/$
- 不能以数字开头
- 不能使用中横线, 会把中横线理解成为减号
- 不能使用关键字和保留字
- 严格区分大小写(计算机编程里都是)
- 命名规范:
- 命名要有意义, 做到顾名思义
- 遵守驼峰命名法
- 交换两个变量的值
var a = 20;
var b = 30;
方法一
var c = b;
b = a;
a = c;
方法二
a = a + b; //a = 50;b=30;
b = a - b; //b = 20;a = 50
a = a - b; //a = 30;b = 20
方法三
异或运算(位运算)
方法四
a = [b, b = a][0]
七、js里的数据类型
1.相关定义
- 作用: 规定数据运算时的规则
- js是一门弱类型的语言
- 数据类型为两大类:
- 基本数据类型/简单数据类型/值类型/原始数据类型 : 数字、字符串、布尔、undefined、null
- 引用数据类型/复杂数据类型
- 字面量/直接量: 可以直接看到值和类型的量
2.基本数据类型
1.Number类型:
console.log('hello' - 'he')
//NaN
隐式转换console.log(isNaN('hello'))
//true
判断是否是一个非数字,'hello'
是一个非数字console.log((0.1 * 1000 + 0.2 * 1000) / 1000)
浮点数计算, 会有精度问题. 解决办法
2.字符串的使用
console.log('你好时间hello'.length)
; // length
属性用来获取字符串的长度
3.布尔类型的使用
console.log(3 > 2)
// true
true
在计算机是用1来保存的, false是用0来保存
4.undefined和null的使用
-
- 如果一个变量只声明没有赋值, 它的默认值就是
undefined
- 如果一个变量只声明没有赋值, 它的默认值就是
-
- 如果一个函数没有明确的返回值, 那么这个函数的返回值就是
undefined
- 如果一个函数没有明确的返回值, 那么这个函数的返回值就是
-
- 如果访问一个对象不存在的属性, 结果也是
undefined
null
表示一个不存在的对象
- 如果访问一个对象不存在的属性, 结果也是
- \( o)/~
undefined
出现的三种常见情况
5.获取一个变量的数据类型
使用运算符
typeof => number/string/boolean/undefined/object
typeof null => object 这是计算机界的bug
6.转换
-
转换成为字符串
-
- 使用
简单数据.toString()
方法 (undefined
和null
没有此方法)
- 使用
-
- 使用
String(简单数据)
函数
- 使用
-
- 让数据和字符串做加法运算
简单数据 + ""
转换成为数字
- 让数据和字符串做加法运算
-
- 使用
parseInt(str)
方法
- 使用
-
parseFloat(str)
-
Number(str)
-
- 让字符串和数字做加法以外的其他算术运算
-
+str
或-str
转换成为布尔值
-
Boolean(str)
-
!!str
-
0 NaN 空字符串 undefined null false
会转换成为false
3.基本数据类型和引用数据类型的区别
基本数据类型保存的是值本身, 而引用数据类型保存的是数据的引用(地址)
八、运算符
1. 算术运算符
+
-
*
/
%
2. 赋值运算符
=
+=
-=
*=
/=
%=
3. 自增自减运算符
a++
++a
a--
--a
4. 逻辑运算符
&&
||
!
-
逻辑运算符的短路问题
-
&&
短路: 只有所有的的运算数都是true
, 结果才是true
. 只要有一个是false
, 结果就是false
, 遇到false
就停止了 -
||
短路: 只要有一个运算数是true
, 结果就是true
. 只有所有的运算数都是false
, 结果才是false
, 遇到true
就停止了
逻辑运算的取值
-
&&
: 取第一个为false
的值, 如果所有的运算都是true
, 取最后一个值 -
||
: 取第一个为true
的值, 如果所有的运算都是false
, 取最后一个值
5. 比较运算符
-
!=
: 只比较内容, 不会比较数据类型 -
!==
: 不止比较内容, 还比较数据类型
比较运算符的特殊情况
-
1.如果是一个数字和字符串进行比较, 会把字符串转换成为数字,
number
>str
,str
=>number
- 2.如果两个都是字符串, 会按照字符串编码的出现顺序进行比较
-
3.
NaN
和任何数据做比较运算, 结果都是false
-
4.如果是一个数字和一个布尔值进行比较, 布尔值会被转换成为数字,
true
被转换成为1
,false
被转换成为0
运算符的优先级
- 先算术运算, 再逻辑运算
- 先与再或
>
>=
<
<=
==
===
!=
!==
九、语句
1.表达式和语句的概念
-
表达式
- 由运算符连接的式子
- 1.一个表达式肯定有一个 明确的结果
- 2.表达式一定不能出现在等号的左边 语句
- 语句的作用是 告诉浏览器该做什么
- 顺序结构 分支结构 循环结构
2.分支结构
if...else
语句 ==> 三元表达式判断条件 ? 条件成立时的语句 : 条件不成立时的语句
if...else if
语句. 可包含所有的情况, 不会有遗漏(性能低, 会一个条件一个条件的找, 直到找到需要的条件, 才停)switch...case
语句 (性能高, 直接找对应的条件, 执行), 注意:switch...case
语句里, 使用的是===
break
语句如果不写,switch...case
语句会有穿透问题
3.循环结构while
语句的使用
while
do...while
for
break
和continue
一般用在循环语句里break
: 用来结束整个循环continue
: 用来结束本轮循环, 开始下一轮循环
十、引用数据类型(复杂数据类型)
1.数组
- 数组概念: 把一堆数据(通常是同一类型的数据), 按照一定的顺序放到一个集合里, 这个集合我们就称为数组
- 创建数组:
- 使用
Array
构造函数var arr = new Array(5, 7);
- 使用数组字面量
var arr1 = [5, 6, 7, 8];
- 使用
- 遍历数组:
for(var i = 0; i < arr.length; i++) { console.log(arr[i]) }
- 翻转数组:
- 冒泡排序:
2.函数
-
理解: 一段准备好的代码
-
函数三要素:
函数名
参数
返回值
-
命名规范:
- 遵守驼峰命名法
- 一般都是
动词 + 名词
的形式来命名
-
参数:
- 如果实参个数 < 形参个数, 不足的形参默认是
undefined
- 实参个数 > 形参个数, 多余的舍弃
- 所有的实参在函数内部都会有一个内置的对象
arguments
来保存, 它是一个伪数组
- 如果实参个数 < 形参个数, 不足的形参默认是
-
返回值
- 一个函数可以只有
return
语句, 而不返回任何值. 这个return
只是用来结束函数 - 如果一个函数没有明确的返回值, 这个函数的返回值就是
undefined
- 一个函数可以只有
-
函数的声明与调用:
function 函数名() { 函数体 }
函数名()
-
递归调用: 在一个函数内部, 再调用自己(注意: 一定要留一个出口)
-
回调函数: 把一个函数当做另一个函数的参数, 这个函数就是回调函数. 一个回调函数的本质是一种编程模式(为一个常见的问题创建解决方案. 参考博客:https://www.cnblogs.com/gaosheng-221/p/6045483.html)
-
判断数据类型的方法
typeof 函数名/简单类型数据
//function/string/number
arr instanceof Array
//true
判断复杂数据类型
-
作用域
变量可以发挥作用的区域变量可以发挥作用的区域
: 1. 全局作用域: 函数外的区域
: 2. 全局变量: 整个文件都可以访问到
: 3. 局部作用域: 函数内部的区域(函数作用域)
: 4. 局部变量: 只能在它当前的局部作用域里访问
: 5. 隐式全局变量: 在函数里直接使用变量, 不用var
js
作用域的注意事项
: 没有块作用域的概念.es6
中新增了块级作用域, 块作用域由{}包括,if
语句和for
语句里面的{}也属于块作用域.
: 1.var
定义的变量, 没有块的概念, 可以跨块访问, 不能跨函数访问.
: 2.let
定义的变量, 只能在块作用域里访问, 不能跨块访问, 也不能跨函数访问.
: 3.const
用来定义常量, 使用时必须初始化(即必须赋值), 只能在块作用域里访问, 而且不能修改.
词法作用域
: 变量的查找规则
: 1. 全局变量在所有的位置都可以被访问的
: 2. 如果自己当前作用域里有变量, 就不会再往全局作用域里找
: 自己有就用自己的, 自己没有的去全局找, 全局找不到就报错~ -
预解析的概念
预解析的规则
: 1.把函数声明提前到当前作用域最前面. 只提前声明, 不提前调用
: 2.把var
声明的变量提前到当前作用域的最前面. 只提前声明, 不提前赋值
: 3.先提前function
, 再提前var
,function
优先级要高
3.对象
- 创建对象
- 使用
Object
构造函数创建var teacher = new Object()
- 使用对象字面量创建
var teacher = { gender: '男', name: '姜老师' }
- 使用自定义构造函数(自己定义一个构造函数, 这么理解可真流弊啊)
- 批量创建对象(工厂设计模式)
- 使用
构造函数:构造函数本身就是一个函数,作用是用来创建对象的
1. 构造函数的函数名都是用名词而不是动词
2. 每一个单词的首字母都大写
3. 没有返回值!
4. 构造函数必须要和关键字 new 一起使用,否则无法创建对象
function Person(name,age,gender,score) {
this.name = name;
this.age = age;
this.gender = gender;
this.score = score;
}
能不能在对象创建的时候,就直接给对象设置属性?
var p = new Person("zs",18,"男",90);
console.log(p);
console.log(p.constructor.name); //Person
工厂设计模式
function createPerson(name, age, gender, score) {
var p = new Object();
p.name = name;
p.age = age;
p.gender = gender;
p.score = score;
return p;
}
- 关键字
new
的作用- 申请并且初始化一段内存空间
- 把
this
指向申请好的内存空间 - 调用构造函数, 给对象赋值
- 把申请好的内存空间返回
- 关键字
this
的作用- 在构造函数里, 配合关键字
new
使用,this
指的就是申请好的内存空间 - 如果是一个普通函数,
this
指的是window
- 如果直接在函数外部使用
this
,this
指的是window
- 在对象里使用的
this
, 如果把this
放到对象的方法里使用,this
指的是调用这个方法的对象
- 在构造函数里, 配合关键字
- 使用点语法操作对象的属性
- 使用点语法可以获取和修改对象的属性
- 如果访问了一个对象不存在的属性, 那么它的结果就是
undefined
- 如果给对象设置了不存在的属性, 就相当于给对象添加了一个新的属性
js
对象特点: 动态属性
- 使用中括号操作对象的属性
- 如果是想要通过变量来获取对象属性对应的值, 必须使用中括号, 不能使用点语法
- 如果对象的
key
和值是'1141': []
这样的, 也要用中括号
- 遍历对象的属性:
for(var key in dog){ console.log(key); console.log(dog[key])}
- 删除对象的属性:
delete
- 可以删除对象的属性
- 可以删除没有
var
声明的全局变量 - 删除成功, 返回
true
; 删除失败, 返回false
- 牛逼的对象:
Math
Date
Math
Math.max(4, 5, 9, 3)
Math.min(4, 5, 9, 3))
Math.floor(34.9)
Math.ceil(34.2)
Math.round(34.2)
Math.random()
Date
- 获取
2019-1-2 日 周一
var date1 = new Date();
var date2 = new Date("2019-1-2");
var date3 = new Date(2019,0,2);
var date4 = new Date(1498099000356)
console.log(date1, date2, date3, date4)
- 获取时间戳
Date.now()
var date = new Date(); var date1 = date.valueOf(); console.log(date1);
var date = new Date(); console.log(+date);
- 日期格式化
var date = new Date(); /console.log(date); => Tue Feb 27 2018 11:20:58 GMT+0800 (中国标准时间) /console.log(date.toString()); => Tue Feb 27 2018 11:20:58 GMT+0800 (中国标准时间) /console.log(date.toDateString()) => Tue Feb 27 2018 /console.log(date.toTimeString()) => 11:21:50 GMT+0800 (中国标准时间) /console.log(date.toLocaleString()) => 2018/2/27 上午11:20:58 /console.log(date.toLocaleDateString()) => 2018/2/27 /console.log(date.toLocaleTimeString()) => 上午11:22:16 自己拼接`2019-01-03 11:23:08 星期二`样式 var year = date.getFullYear() => 2019 var month = date.getMonth() + 1 => 月份是从0开始计算的 month = month < 10 ? '0' + month : month var riqi = date.getDate() riqi = riqi < 10 ? '0' + riqi : riqi var hours = date.getHours() hours = hours < 10 ? '0' + hours : hours var minutes = date.getMinutes(); minutes = minutes < 10 ? '0' + minutes : minutes; var seconds = date.getSeconds() seconds = seconds < 10 ? '0' + seconds : seconds; var day = date.getDay() var str = year + '-' + month + '-' + riqi + ' ' + hours + ':' + minutes + ':' + seconds + ' 星期' + day console.log(str)
- 获取
4.数组
- 创建数组
- 使用
Array
构造函数 =>var arr1 = new Array(5, 8)
- 使用数组字面量 =>
var arr2 = [5, 9, 4]
- 使用
- 判断数组
console.log(arr1 instanceof Array)
=>true
console.log(Array.isArray(arr1))
=>true
- 数组的增删方法
arr.push(50, 60)
=> 在数组最后添加元素arr.pop()
=> 从数组的最后面删除一个元素arr.unshift(10, 30)
=> 在数组的最前面插入元素arr.shift()
=> 从数组的最前面删掉一个元素
- 翻转数组
arr.reverse()
- 数组的排序
arr.sort()
- 默认是把元素都当做字符串, 按照字符串出现的编码顺序进行排列
arr.sort(function (a, b) { /return a - b; 升序排列 return b - a; 降序排列 })
- 按字符串的长度排序
arr.sort(function (a, b){ /return a.length - b.length; return b.length - a.length; })
- 数组拼接的方法
arr1.concat(arr2).concat(arr3)
, 生成一个新数组, 不改变原数组 - 数组的截取
slice
不改变原数组
arr.slice()
arr.slice(1)
arr.slice(3, 5)
splice
改变原数组
arr.splice(8)
arr.splice(2, 3)
arr.splice(2, 3, '插入的元素a', '插入的元素b')
- 数组查找相关的方法
arr.indexOf(2)
=> 数组中有2, 就返回2的下标(第一次出现的), 没有, 就返回-1arr.lastIndexOf(2)
=> 2在数组中最后一次出现的下标, 没有, 返回-1
- 将数组转换成为字符串
数组 => 字符串 arr.join('|') 字符串 => 数组 str.split('-') eg: 遍历字符串, 并将遍历出的每个字符后面添加'@', 输出至当前的文档页面 document.write(str.split('').join('@')) 字符串 =拆=> 数组 =拼=> 字符串
5.字符串(简单数据类型, 此处写其操作方法)
- 替换字符串中的内容
var str = 'big box';
str.replace('big', 'small')
console.log(str) // 'small box'