JS基础
# 1 JS认知
# 1.1 JS组成
- ECMAScript,JS语法
- DOM,页面文档对象模型
- BOM,浏览器对象模型
# 1.2 JS书写位置
- 行内式
- 将单行或少量代买写在HTML标签的事件属性中(以on开头的属性)
- HTML中推荐使用双引号,JS中推荐使用单引号
- 内嵌式
<script></script>
- 外部式
<script scr="my.js"></script>
# 1.3 JS注释
- 单行注释//(ctrl + /)
- 多行注释/* */(shift + alt + a)
# 2 输入输出语句
# 2.1 alert
- 弹出警示框
- 语法
prompt('弹出的语句');
# 2.2 console
- 控制台输出,用于测试
- 语法
console.log('输出的语句');
# 2.3 dir
- 语法
console.dir(元素对象);
- 打印DOM返回的元素对象
# 2.4 prompt
- 弹出输入框
- 语法
prompt('请用户输入的提示语句');
- 输入进来的值是字符串类型
# 3 变量
变量用于存放数据,是内存中申请的一段空间
# 3.1 变量的使用
# 3.1.1 变量声明
var 变量名;
- var是JS关键字,用于声明变量。使用后计算机自动为变量分配内存空间,不需要程序员管
# 3.1.2 变量赋值
变量名 = 值;
# 3.1.3 变量初始化
var 变量名 = 值;
# 3.1.4 同时声明
var 变量名1 = 值,
变量2 = 值;
1
2
2
# 3.1.5 可以不声明直接使用
- 但是会变成全局变量
# 3.2 变量命名规范
- 由字母、数字、下划线、美元符号
- 严格区分大小写
- 不能以数字开头
- 不能是关键字和保留字
# 3.3 检测数据类型
typeof 待检测变量
# 4 数字型Number
数字类型可以用来保存整数值,也可以保存浮点数
# 4.1 整型
# 4.2 浮点型
# 4.3 数字型进制
- 八进制:数字前+0
- 16进制:数字前+0x
# 4.4 数字范围
- 最大值1.79e+308
- 最小值5e-324
# 4.5 特殊值
- 无穷大:Infinity
- 无穷小:-Infinity
- 非数字:NaN
# 4.6 数字判断
isNaN()
判断是不是非数字
# 4.7 其他类型转换成数字型
parseInt(字符串型变量)
变为整型- 会去除数字之后的其他字符串
- 但是不能去除数字之前的字符串
parseFloat(字符串型变量)
变为浮点型- 会去除数字之后的其他字符串
- 但是不能去除数字之前的字符串
Number(变量)
- 利用算术运算隐式转换为数字型
# 5 字符串型String
推荐使用单引号
# 5.1 字符串嵌套
- 外单内双进行嵌套
# 5.2 字符串转义符
- 换行
\n
- tab缩进
\t
- 空格
\b
# 5.3 字符串的拼接
- 用+拼接
- 只要有一个部分是字符串,输出都是字符串,和其他数据类型没关系
- 变量可以直接把内容拼接到字符串里
# 5.4 字符串常用方法
- 返回长度
字符串名.length
- 返回指定位置字符串内容
字符串名.charAt(位置索引)
- 返回指定字符在字符串中首次出现的位置
字符串名.indexOf(查找的字符,起始的位置)
- 判断子字符串的存在
字符串.includes(子字符串)
- 大小写转换
字符串名.toLowerCase()|字符串名.toUpperCase()
# 5.5 其他类型转换成字符串
变量.toString()
String(变量)
函数强制转换- 加号拼接
# 5.6 字符串的不可变
- 指的是里面的值不可变,虽然看上去可以改变内容,但其实是地址变了,内存中新开辟了一个内存空间
- 因为字符串的不可变不要大量拼接字符串
# 5.7 ES5新增字符串方法
# 5.7.1 trim()
- 从字符串的两端删除空白字符
- 语法
str.trim()
- 不影响原字符串本身,返回的是一个新的字符串
# 6 布尔型Boolean
- true可以当1来看
- false可以当0来看
# 6.1 其他类型转换成布尔型
Boolean(变量)
- 代表空的''|0|NaN|null|undefined转换成false
- 其他都是true
# 7 运算符
运算符(operator)也称为操作符,用于实现赋值、比较和执行算术运算等功能的符号
# 7.1 算数运算符
- 浮点数存在阶段误差,不要判断浮点数是否相等
- 算数运算符的优先级和平时一样
# 7.2 递增递减运算符
++
递增,每次加1--
递减,每次减1- 前置递增|递减:运算符在变量前面,先计算后输出
- 后置递增|递减:运算符在变量后面,先输出后计算
var age = 10
console.log(++age + 10); //输出21,前置递增
age = 10
console.log(age++ + 10); //输出20,后置递增
// 但是两个age都是11
1
2
3
4
5
2
3
4
5
# 7.3 比较运算符
==
比较的时候会自动转换数据类型===
同时要求值和数据类型
console.log(18 == '18'); //true
console.log(18 === '18'); //false
1
2
2
# 7.4 逻辑运算符
- 短路运算:当有多个表达式时,左边表达式可以确定结果时就不再进行有右边的运算
# 7.4.1 &&断路
表达式1 && 表达式2
- 表达式1真,返回表达式2
- 表达式1假,返回表达式1
# 7.4.2 ||断路
表达式1 || 表达式2
- 表达式1真,返回表达式1
- 表达式1假,返回表达式2
# 7.5 赋值运算符
# 7.6 运算符优先级
# 8 流程控制
# 8.1 顺序流程控制
直接写就好
# 8.2 分支流程控制
# 8.2.1 if
- 语法结构
if (条件表达式) {
条件成立时的执行语句
}
1
2
3
2
3
# 8.2.2 if-else双分支
- 语法结构
if (条件表达式) {
条件成立时的执行语句
} else{
条件不成立时的执行语句
}
1
2
3
4
5
2
3
4
5
- if和else里只有一个语句能执行
# 8.2.3 多分支语句
- 语法结构
if (条件表达式1) {
条件1成立时的执行语句
} else if (条件表达式2){
条件1不成立条件3成立时的执行语句
} else{
所有条件都不成立时的执行语句
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 8.2.4 三元表达式
- 语法结构
条件表达式 ? 表达式1 : 表达式2
- 执行思路
- 条件表达式真,返回表达式1
- 条件表达式假,返回表达式2
# 8.2.5 switch
- 语法结构
switch (表达式) {
case value1:
表达式与value1匹配时的执行语句;
break;
case value2:
表达式与value2匹配时的执行语句;
break;
default:
都不满足时的执行语句;
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
- 匹配的要求是值和数据类型都相等才算匹配
- 要写break,否则switch会认为一直是匹配上的直接执行后续case的执行语句
# 8.3 循环流程控制
# 8.3.1 for循环
- 语法结构
for (初始化变量;条件表达式;操作表达式) {
循环体
}
1
2
3
2
3
# 8.3.2 while循环
- 语法结构
while (条件表达式) {
循环体
}
1
2
3
2
3
# 8.3.3 do-while循环
- 语法结构
do {
循环体
} while (条件表达式)
1
2
3
2
3
- 限制性循环体再判断条件
# 8.3.4 continue
- 立即跳出本次循环,继续下一次循环
# 8.4 break
- 立即跳出整个循环
# 9 数组Array
# 9.1 创建数组
# 9.1.1 new关键字创建数组
var 数组名 = new Array();
- 通过实例化Array构造对象创建的
var 数组名 = new Array(n);
创建长度为n的空数组var 数组名 = new Array(x,y);
创建[ x,y]数组
# 9.1.2 利用数组字面量创建数组
- 数组字面量[]
- 语法
var 数组名 = [];
- 数组里的数据用逗号分隔
- 数组里的数据称为数组元素
# 9.2 数组索引
- 索引(下标):用来访问数组元素的序列,从0开始
- 通过索引号访问数组元素
数组名[索引号]
- 没有数组元素,访问结果为undefined
# 9.3 数组长度
数组名.length
# 9.4 数组新增元素
# 9.4.1 修改length长度
数组名.length = 5
添加空元素
# 9.4.2 增加索引号
数组名[索引号] = 新加元素
追加元素
# 9.5 检测是否为数组
# 9.5.1 instanceof 运算符
- 语法
待检测内容 instanceof Array
# 9.5.2 .isArray()
- 语法
Array.isArray(待检测内容)
- ie9以上版本才支持
# 9.6 添加数组元素
# 9.6.1 .push()
- 在尾部添加一个或多个数组元素
- 语法
数组.push(添加的元素)
- push完后返回的是新数组的长度
- 原数组也会发生变化
# 9.6.2 .unshift()
- 在开头添加一个或多个数组元素
- 语法
数组.unshift(添加的元素)
- unshift完后返回的是新数组的长度
- 原数组也会发生变化
# 9.7 删除数组元素
# 9.7.1 .pop()
- 删除数组最后的一个元素,一次只能删除一个元素
- 语法
数组.pop()
- pop完后返回被删除的元素
- 原数组也会发生变化
# 9.7.2 .shift()
- 删除数组第一个的一个元素,一次只能删除一个元素
- 语法
数组.shift()
- shift完后返回被删除的元素
- 原数组也会发生变化
# 9.8 数组排序
# 9.8.1 .reverse()
- 翻转数组
- 语法
数组.reverse()
# 9.8.2 .sort()
- 冒泡排序
- 语法
数组.sort()
- 这样排序是先看按照最高位排序,再按后面的位数排序,个位数可以用
数组.sort(function(a,b){
// 按照升序排序
return a-b;
// 按照降序排序
return b-a;
});
1
2
3
4
5
6
2
3
4
5
6
# 9.9 数组索引
# 9.9.1 .indexOf()
- 查找数组中给定元素的第一个索引
- 不存在返回-1
- 语法
数组名.indexOf(元素名,查找起始位置)
# 9.9.2 .lastIndexOf()
- 查找数组中给定元素的最后一个索引
- 不存在返回-1
- 语法``数组名.lastIndexOf(元素名)`
# 9.10 数组转换成字符串
# 9.10.1 toString()
- 把数组转换成字符串,逗号分隔每一项
# 9.10.2 join('分隔符')
- 把数组中的所有元素转换为一个字符串
- 分隔符默认为逗号
# 9.11 数组切割
# 9.11.1 .concat()
- 连接两个或多个数组
- 返回新数组
- 不影响原数组
# 9.11.2 .slice()
- 截取数组
- 返回新数组
- 语法
数组名.slice(开始缩印,结束索引)
# 9.11.3 .splice()
- 删除数组内元素
- 返回被删除的新数组
- 会影响原数组
# 9.12 ES5数组新增方法
# 9.12.1 遍历方法
# forEach()
- 语法
数值名.forEach(function(value,index,array){})
- value:数组当前项的值
- index:数组当前项的索引
- array:被遍历的数组本身
- 在forEach里面return不会终止迭代
# filter()
- 语法
数值名.filter(function(value,index,array){})
- filter方法用于创建一个新的数组,新数组中的元素是通过检测指定数组中符合条件的所有元素,主要用于筛选数组
- 返回的是一个新数组
# some()
- 语法
数值名.some(function(value,index,array){})
- some方法用于检测数组中断额元素是否满足指定条件
- 返回的是一个布尔值。如果查到这个元素,就返回true;如果查不到就返回false
- 如果找到第一个满足条件的元素,则终止循环,不再继续查找
- 在some里面return true会终止迭代
# 10 函数
- 函数:封装了可被调用实行的代码块
# 10.1 函数的使用
# 10.1.1 声明函数
# 利用函数关键字声明(命名函数)
- 语法
function 函数名(形参){}
- function是声明函数的关键字
- 函数名一般是动词
# 函数表达式声明(匿名函数)
- 语法
var 变量名 = function(形参){}
# 通过构造函数生命
- 语法
var 函数名 = new Function('形参','函数体')
- 所有函数都是Function的实例(对象)
- Function里面参数都必须是字符串格式
- 执行效率低,也不方便书写,较少使用
# 10.1.2 调用函数
# 普通函数
- 语法
函数名();
- 语法
函数名.call()
# 对象里的方法
- 语法
对象.函数名()
# 构造函数
- 语法
new 构造函数名()
# 绑定事件函数
- 触发事件自动调用
# 定时器函数
- 定时器自动调用
# 立即执行函数
(function(){})()
自动调用
# 10.2 函数的参数
# 10.2.1 形参
- 函数声明的是形参
- 语法
function 函数名(形参1,形参2):{}
- 是一种不用声明的变量
- 形参不赋值时默认为undefined
# 10.2.2 实参
- 调用函数的是实参
- 语法
函数名(实参1,实参2);
# 10.2.3 实参形参的关系
- 形参接受实参的数值
- 形参和实参可以不匹配
- 实参个数多于形参个数,后面的实参直接抛弃
# 10.3 函数返回
- 语法
return 需要返回的结果;
- return具有终止函数的功能
- return只能返回一个值,如果多个值返回最后一个值
- 函数如果没有return,则返回undefined
# 10.4 arguments
- arguments是当前函数的内置对象,存储了传递的所有实参
- 语法
function 函数名():{
console.log(arguments)
}
1
2
3
2
3
- arguments展示形参为一个伪数组
- 可以遍历
- 具有length属性
- 按索引方式储存数据
- 不具有数组的push、pop等方法
- 只有函数有arguments对象
# 10.5 函数的this
- this的指向是当我们调用函数的时候确定的
- 一般指向调用者
- 构造函数里的this和构造函数原型对象里的this都指向生成的实例对象
# 10.5.1 call()
- 可以调用函数
- 改变this指向
- 语法
函数名.call(this指向,实参)
- 主要作用是实现继承。在子构造函数里用call调用父构造函数
父构造函数名.call(this,参数)
# 10.5.2 apply()
- 可以调用函数,也可以改变this指向
- 语法
函数名.apply(this指向,[实参])
- 实参的传递必须使用数组的方式
- 可以实现数组最大最小值的实现
Math.max.apply(Math,数组)
# 10.5.3 bind()
- 不会调用函数,但能改变函数内部this指向
- 语法
函数名.bind(this指向,实参)
- 返回由指定的this值和初始化参数改造的原函数拷贝
- 应用场景:有的函数不需要立即调用,但又想改变函数内部this指向
# 10.6 高阶函数
- 高阶函数是对其他函数进行操作的含糊,它接收函数作为参数或将函数作为返回值输出
# 11 作用域
# 11.1 作用域概述
- 作用域:限定代码中用到的名字可用性的代码范围
- 作用域的目的是提高程序的可靠性,减少命名冲突
- 作用域分为全局作用域和局部作用域
- 全局作用域:整个scrip标签或者一个单独的js文件
- 局部作用域:只在函数内部,也可以叫做函数作用域
- 不同作用域下命名不冲突
# 11.2 变量的作用域
# 11.2.1 全局变量
- 在全局作用域下的变量
- 除了全局状态下声明变量还有在函数内部不声明直接赋值的变量也是全局变量
# 11.2.2 局部变量
- 在局部作用域下的变量
- 只能在函数内部使用
- 函数的形参也可以看作局部变量
# 11.2.3 全局效率
- 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源
- 局部变量程序执行完毕就会销毁,比较节约内容资源
# 11.3 块级作用域
- 目前js没有块级作用域
- 在es6时新增了块级作用域
- 块级作用域:用{}包含的
# 11.4 作用域链
- 内部函数访问外部函数的变量采取的是链式查找的方式来决定是哪个值
- 作用域链:这种链式查找方式结构
- 就近原则
# 12 闭包
# 12.1 变量作用域
- 函数内部可以使用全局变量
- 函数外部不可以使用局部变量
- 当函数执行完毕,本作用域内的局部变量会销毁
# 12.2 闭包定义
- 闭包(closure)指有权访问另一个函数作用域中变量的函数
# 12.3 闭包作用
- 延伸了变量的作用范围
# 13 拷贝
- 浅拷贝只是拷贝一层,更深层次对象级别的只拷贝引用,只拷贝地址
- 深拷贝拷贝多层,每一个级别的数据都会拷贝
# 13.1 浅拷贝
- ES6新语法
Object.assign(用于存储的变量名,被拷贝的变量名)
# 13.2 深拷贝
- 通过递归函数来进行深拷贝
function deepCopy(newObj,oldObj){
for(var k in oldObj){
var item = oldObj[k];
if(item instanceof Array){
newObj[k] = [];
deepCopy(newObj[k],item);
}else if(item instanceof Object){
newObj[k] = {};
deepCopy(newObj[k],item);
}else{
newObj[k] = item;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 14 预解析
# 14.1 JS代码运行
- 预解析:js引擎会把里面所有的var还有function提升到当前作用域的最前面
- 代码执行:按照代码书写的顺序从上往下执行
# 14.2 变量预解析
- 变量预解析又叫变量提升
- 只提升变量声明不提升赋值操作
# 14.3 函数预解析
- 函数预解析又叫函数提升
- 只提升函数声明不调用
- 函数预解析只适用于用函数关键字声明的情况
# 15 对象
- 对象是一组无需的相关属性和方法的集合
- 属性:事物的特征
- 方法:事物的行为
# 15.1 创建对象
# 15.1.1 利用字面量创建对象
- 对象字面量为{}
var obj = {
//属性
uname = 'qww',
//方法
sayHi : function(){
console.log('hi');
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 里面的属性或者方法采取键值对的形式
- 多个属性或者方法中间用逗号隔开
- 方法后面跟的是一个匿名函数
# 15.1.2 利用new Object创建对象
var obj = new Object();
obj.uname = 'qww';
obj.sayHi = function(){
console.log('hi');
}
1
2
3
4
5
2
3
4
5
- 利用等号赋值的方法添加对象的属性和方法
- 每个属性和方法之间用分号结束
# 15.1.3 利用构造函数创建对象
- 构造函数:把对象里相同的属性和方法抽象出来封装到函数里面
- 语法规范
function 构造函数名() {
this.属性 = 值;
this.方法 = function(){}
}
new 构造函数名();
1
2
3
4
5
2
3
4
5
- 构造函数名字首字母大写
- 构造函数不需要return就可以返回结果
- 调用构造函数必须使用new
- 属性和方法前面必须添加this
- 对象是一个具体的事物,特指某一个;构造函数是一个大类,类似于其他语言的类
- 利用构造函数创建对象的过程也叫对象的实例化
# 15.2 使用对象
# 15.2.1 调用对象属性
对象名.属性名
对象名['属性名']
# 15.2.2 调用对象方法
对象名.方法名()
- 不能忘记添加小括号
# 15.3 new关键字
- new构造函数可以在内存中创建了一个空的对象
- this指向刚才创建的空对象
- 执行构造函数里面的代码,给空对象添加属性和方法
- 返回这个对象(所以构造函数不需要return)
# 15.4 遍历对象
- for in语句可以对数组或者对象的属性进行循环操作
- 语法
for (var k in obj) {
console.log(k); //输出的是属性名
console.log(obj[k]); //输出的属性值
}
1
2
3
4
2
3
4
# 15.5 ES5新增方法
# 15.5.1 Object.definerProperty()
- 定义对象中新属性或修改原有的属性
- 语法
Object.definerProperty(目标对象,属性名,descriptor)
- descriptor表示目标属性所拥有的特性,需要以对象形式书写
- descriptor四个属性
- value:设置属性的值,默认为undefined
- writable:值是否可以重写,默认为false
- enumerable:目标属性是否可以被枚举,默认为false,不允许该属性被遍历出来
- configurable:目标属性是否可以被删除或是否可以再次修改特性,默认为false
# 16 内置对象
- JS中对象分成3种:自定义对象、内置对象、浏览器对象
- 内置对象:JS语言自带的一些对象,供开发者使用,并提供了一些常用的或是最基本的必要功能(属性和方法)
# 16.1 Math内置对象
- Math不是一个函数对象,不是一个构造器,不需要New来调用,而是直接使用
# 16.1.1 Math常用属性和方法
Math.PI
圆周率Math.floor()
向下取整Math.ceil()
向上取整Math.round()
四舍五入,就近取整,-3.5取-3Math.abs()
绝对值,可以隐式转换,会把字符串转换成数字型Math.max/min()
最大、最小值Math.random()
0~1的随机数
# 16.2 日期内置对象
- Date实例用来处理日期和时间
- Date是一个构造函数,必须使用New调用
# 16.2.1 使用Date
- 语法
var date = new Date();
- 如果没有参数返回系统的当前时间
# 16.2.2 参数常用写法
- 数字型
2021,03,09
月份会多1,因为从0开始记录 - 字符串型
'2021-03-09 16:58:10'
常用
# 16.2.3 日期格式化
- 月份返回的会小1个月
- 返回星期的时候,周日返回的是0
# 16.2.4 获取时间戳
- 时间戳是距离1970年1月1日的总毫秒数
Date.valueOf()
Date.getTime()
- 可简化为
var date1 = +new Date();
,最常用的写法 - H5新增的方法
Date.now()
# 17 基本包装类型
- 基本包装类型就是把简单数据类型包装成为了复杂数据类型,使得简单数据类型有了属性和方法
- 过程:
- 把简单数据类型包装为复杂数据类型
- 把临时变量的值给str
- 销毁临时变量
- 为了方便操作基本数据类型,JavaScript提供了三个特殊的引用类型:String、Number和Boolean
# 18 数据类型
# 18.1 堆和栈
其实JavaScript中没有堆和栈的概念,但可以方便理解代码的执行方式
# 18.1.1 栈(操作系统)
- 由操作系统自动分配释放存放函数的参数值、局部变量的值等
- 其操作方式类似于数据结构中的栈
- 简单数据类型存放在栈里面
# 18.1.2 堆(操作系统)
- 存储复杂类型(对象)
- 一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收
# 18.2 简单数据类型
- 简单数据类型又叫作基本数据类型或者值类型
- 值类型:在存储时变量中存储的是值本身
- string、number、boolean、undefined、null
- 简单数据类型null返回的是一个空对象
# 18.2.1 简单数据类型内存分配
- 简单数据类型存放在栈里面,里面直接开辟一个空间存放的是值
# 18.3 复杂数据类型
- 复杂数据类型又叫引用类型
- 通过new关键字创建的对象(系统对象、自定义对象),如Object、Array、Date等
# 18.3.1 复杂数据类型内存分配
- 复杂数据类型首先在栈里存放地址,16进制
- 然后栈中的地址指向堆里的数据
# 19 面向对象
# 19.1 面向对象编程介绍
- 面向过程,POP(Process-oriented programming)。
- 分析出解决问题所需的步骤,然后用函数把步骤一步步实现,使用的时候再一个个依次调用
- 分析好步骤,按照步骤解决问题
- 面向对象,OOP(Object Oriented Programming)
- 把事务分解成为一个个对象,然后由对象之间分工与合作
- 以对象功能划分问题,而不是步骤
- 特点:
- 封装性
- 继承性
- 多态性
- 两者对比
- 面向过程
-1 优点:性能比面向对象高,适合跟硬件联系很紧密的东西
- 1缺点没:有面向对象易维护、易复用、易扩展
- 面向11对象
- 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,是系统更佳灵活
- 缺点:性能比面向过程低
- 面向过程
-1 优点:性能比面向对象高,适合跟硬件联系很紧密的东西
# 19.2 ES6中的类和对象
# 19.2.1 面向对象的思维特点
- 抽取(抽象)对象共用的属性和行为组织(封装)成一个类(模板)
- 对类进行实例化,获取类的对象
# 19.2.2 对象
- 对象是一个具体的事物
- 在JavaScript中,对象是一组无需的相关属性和方法的集合,所有的事物都是对象
- 对象由属性和方法组成
- 属性:事物的特征,在对象中用属性来表示
- 方法:事物的行为,在对象中用方法来表示
# 19.2.3 类class
- ES6中新增了类的概念,可以使用class关键字声明一个类,之后以这个类来实例化对象
- 类抽象了对象的公共部分,泛指某一大类
- 对象特指某一个,通过类实例化一个具体的对象
# 19.2.4 创建类
- 语法
class 类名{类内容}
- 类名习惯首字母大写
- 创建实例
var 对象名 = new 类名();
- 类必须使用new实例化对象
# 19.2.5 类constructor构造函数
- constructor()方法是类的构造函数,用于传递参数,返回实例对象
- 通过new命令生成对象实例,自动调用该方法
- 如果没有显示定义,类内部会自动给我们创建一个constructor()
- 语法
class 类名 {
construction(形参){
实参赋值
}
}
1
2
3
4
5
2
3
4
5
- 构造函数不需要加function
# 19.2.6 类添加方法
- 把方法直接写在类里面即可
- 类里面所有的函数不需要function
- 在类里面所有函数之间不需要添加逗号
# 19.2.7 类的继承
- 子类可以继承父类的属性和方法
- 语法
class 子类名 extends 父类名{}
- 继承中存在就近原则,子类有的方法直接调用,没有再去查找父类
# super关键字
- 用于访问和调用对象父类上的函数。可以调用父类的构造函数,也可以调用父类的普通函数
- 语法
super()
调用父类construction构造函数 - 语法
super.父类方法()
调用父类的函数函数 - super()必须在子类this之前调用
# 19.2.8 注意点
- 在ES6中类没有变量提升,所以必须先定义类,才能通过类实例化对象
- 类里共有的属性和方法一定要加this使用
- 类中this指向问题
- 在construction里面的this指向实例对象
- 方法里面的this指向这个方法的调用者
# 20 构造函数和原型
面试重点
# 20.1 构造函数
- 构造函数是一种特殊的函数,主要用来初始化对象。总和new一起使用
- 构造函数用于创建某一类对象,其首字母大写
- 构造函数要和new一起使用才有意义
- new在执行时会做
- 在内存中创建一个新的空对象
- 让this指向这个新的对象
- 执行构造函数里面的代码,给这个新对象添加属性和方法
- 返回这个新对象(所以构造函数里面不需要return)
- 成员:构造函数中的属性和方法
- 静态成员:在构造函数本上添加的成员,只能由构造函数本身来访问。在构造函数本身上添加的成员
- 实例成员:在构造函数内部创建的对象成员,只能由实例化的对象来访问。在构造函数内部通过this添加的成员
- 构造函数存在内存浪费的问题,创建对象的时候会额外开辟空间以存放方法,且各对象同一方法不存放在一起
# 20.2 构造函数原型 prototype
- 构造函数通过原型分配的函数是所有对象所共享的
- JavaScript规定,每一个构造函数都一个prototype属性,指向另一个对象。这个对象的所有属性和方法都会被构造函数所拥有
- 我们可以把不变的方法直接定义在prototype对象上,这样所有的实例就可以共享这些方法
# 20.3 对象原型__proto__
- 对象都会有一个属性__proto__指向构造函数的prototype原型对象,这让对象可以使用构造函数原型对象的属性和方法
- 对象的__proto__对象原型和构造函数的prototype原型对象是一样的
- __proto__是一个非标准属性,不能对其赋值
- 对象方法查找规则
- 先查找对象是否存在该方法,有就执行对象上的方法
- 通过__proto__去构造函数原型对象里查找执行
# 20.4 构造函数constructor
- 对象原型__proto__和构造函数prototype原型对象里面都有一个属性constructor,被称为构造函数,因为它指回构造函数本身
- constructor用于记录该对象引用哪个构造函数,它可以让原型对象重新指向原来的构造函数
- 如果修改了原来的原型对象,给原型对象幅值的是一个对象,则必须手动地使用constructor指回原来的构造函数
# 20.5 构造函数、实例、原型对象三者之间的关系
# 20.6 原型链
# 20.7 成员的查找机制
- 当访问一个对象的属性(包括方法)时,首先查找这个对象自身有没有该属性
- 如果没有就查找它的原型(也就是__proto__指向的prototype原型对象)
- 如果还没有就查找原型对象的原型(Object的原型对象)
- 依次类推知道找到Object为止(null)
# 20.8 原型对象this指向
- 在构造函数中this指向对象实例
- 原型对象里的this指向对象实例
# 20.9 扩展内置对象
- 通过原型对象,对原来的内置对象进行扩展自定义的方法
- 数组和字符串内置对象不能给原型对象覆盖操作
Array.prototype = {}
,只能是Array.prototype.XXX = function(){}
的方式
# 21 继承
- ES6之前没有给我们提供extends继承。通过构造函数+原型对象模拟实现继承,被称为组合继承
# 21.1 call()
- 调用这个函数,并且修改函数运行时的this指向
- 语法
fun.call(thisArg, arg1, arg2, ...)
- thisArg:当前调用函数this的指向对象
- arg1等:传递的其他参数
# 21.2 借用构造函数继承父类型属性
- 核心原理:通过call()把父类型的this指向子类型的this,这样就可以实现子类型继承父类型的属性
- 语法
//借用父构造函数继承属性
function Father(uname, age) {
//此处的this指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
function Son(uname, age) {
//将父构造函数的this改成子构造函数的this
Father.call(this, uname, age);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 21.3 借用原型对象继承父类型方法
- 继承方法不能通过赋值原型对象的方法实现,这样会导致本来只打算在子类型上新定义的方法会同步到父类型上
- 语法
//借用父构造函数继承属性
function Father() {
}
Father.prototype.money = function(){
console.log(100000)
}
Son.prototype = new Father();
//如果利用对象的形式修改了原型对象,要用constructor指回原来的构造函数
Son.prototype.constructor = Son;
function Son() {
}
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 21.4 类的本质
- class的本质还是一个函数,就是构造函数的另一种写法
- 类有原型对象prototype
- 类的原型对象prototype里有constructor指向类本身
- 类可以通过原型对象的方式添加方法
- 类创造的实例对象有__proto__指向类的原型对象
- ES6类其实就是语法糖,简单写法实现相同功能
# 22 严格模式
- JavaScript除了提供正常模式外,还提供了严格模式(strict mode)。ES5的严格模式是采用具有限制性JavaScript辩题的一种方式
- 严格模式作用
- 消除了JavaScript语法的一些不合理、不严谨之处
- 消除代码不安全之处
- 提高编译器效率,增加运行速度
- 禁用了ECMAScript的未来版本中可能会定义的一些语法,为新版本的JavaScript做好铺垫
# 22.1 开启严格模式
- 严格模式可以应用到整个脚本或个别函数中
- 为脚本开启严格模式:在所有语句之前放一个特定语句'use strict'
- 为函数开启严格模式:在函数里的第一行写一个特定语句'use strict'
# 22.2 严格模式变化
# 22.2.1 变量规定
- 在严格模式下不声明无法赋值变量
- 严禁删除已经声明的变量
# 22.2.2 this指向
- 以前在全局作用域函数中的this指向Windows对象
- 严格模式下全局作用域中函数的this指向undefined
- 以前构造函数不加new会当普通函数调用,严格模式下必须使用new
# 22.2.3 函数变化
- 函数不能有重名的参数
- 函数必须声明在顶层。ES6会引入块级作用域
# 23 正则表达式
正则表达式是用于匹配字符串中字符组合的模式 JavaScript中正则表达式也是对象
# 23.1 特点
- 灵活性、逻辑性和功能性非常强
- 可以迅速地用既简单的方式达到字符串的复杂控制
# 23.2 创建正则表达式
# 23.2.1 利用RegExp对象来创建
- 语法
var 变量名 = new RegExp(/表达式/)
# 23.2.2 利用字面量创建
- 语法
var 变量名=/表达式/
# 23.3 测试正则表达式
- test()正则对象方法,用于检测字符串是否符合该规则
- 语法
正则表达式.test(被测试的文本)
# 23.4 正则表达式中的特殊字符
# 23.4.1 正则表达式的组成
一个正则表达式可以由简单的字符构成,也可以是简单和特殊字符的组合
特殊字符也被称为元字符,在正则表达式中是具有特殊意义的专用符号
/abc/
检测到包含'abc'的内容即可
# 23.4.2 边界符
- ^:表示匹配行首的文本
- $:表示匹配行尾的文本
/^abc/
检测到包含以'abc'的内容开头即可/^abc$/
检测到内容为'abc'才行
# 23.4.3 字符类
- 字符类[]表示有一系列字符可供选择,只要匹配其中一个就可以了
/[abc]/
检测到包含'a'或'b'或'c'的内容即可/^[abc]$/
三选一,只有是a或者是b或者是c这三个字符才返回true- 字符组合
/^[a-zA-Z0-9_-]$/
可选择的内容扩展 - 字符组合
/^[^a-zA-Z0-9_-]$/
如果中括号里面有^表示取反
# 23.4.4 量词符
- 量词符用来设定某个模式出现的次数
- *:重复零次或更多次
- +:重复一次或更多次
- ?:重复零次或一次
- {n}:重复n次
- {n,}:重复n次或更多次
- {n,m}:重复n到m次
# 23.4.5 括号总结
- 中括号:字符集合匹配
- 大括号:量词符
- 小括号:表示优先级
# 23.4.6 预定义类
预定义类值某些常见模式的简写方式
- \d:匹配0-9之间任一数字
- \D:匹配所有0-9意外的字符
- \w:匹配任意的字母、数字和下划线
- \W:除所有字母、数字和下划线以外的字符
- \s:匹配空格(包括换行符、制表符、空格符等)
- \S:匹配非空格的字符
# 23.5 正则替换
- replace()方法可以实现替换字符串操作,用来替换的参数可以是一个字符串或是一个正则表达式
# 23.5.1 正则表达式参数
- 语法
/表达式/[switch]
- switch也称为修饰符,按照什么模式来匹配
- g:全局匹配
- i:忽略大小写
- gi:全局匹配+忽略大小写