概述

  1. 基本组成
    ECMAScript、DOM、BOM
  2. JS的特点
  • 解释型语言
  • 类似于C和Java语法结构
  • 基于原型的面向对象

基本使用

JS编写的位置

  1. 可以将js代码写在标签属性中
  2. 虽然可以写在标签属性中,但是属于结构和行为耦合,不方便使用,不推荐
  3. 可以通过script标签引入外部文件,可以多文件使用,但是用了引用外部文件,在该标签内的内容就不生效
  4. 是按照从上往下的方式

JS的基本语法

  1. JS中严格区分大小写
  2. JS中的语句以分号作为结尾,如果不以分号结尾,浏览器会自动为其添加,但是会消耗系统资源
  3. JS中会省略多个空格和换行

字面量和变量

  1. 字面量是指无法改变的值,例如:1、2、3、4
  2. 变量能够保存字面量,一般情况下,都使用变量,很少使用字面量
// 声明变量
var a;
// 为变量赋值
a = 123;
// 声明变量同时为其赋值
var a = 123;
// 可以通过变量描述字面量
var age = 80;

标识符

  1. JS中的可以由我们自己命名的都是标识符
  2. 变量名、函数名、属性名都属于标识符
  3. 标识符需要遵循的规则如下
  • 标识符可以由数字、字母、下划线、$组成
  • 标识符不能以数字开头
  • 标识符不能是ES中的关键字或者保留字
  • 标识符一般都采用驼峰命名法:首字母小写,每个单词的开头大写
  • JS底层保存的是Unicode编码,理论上utf-8所有的内容都可以作为标识符

数据类型

可以用typeof检查变量类型
— 基本数据类型

String、Number、Boolean、null、undefined

  1. String 字符串
  • JS中字符串需要用引号引起来
  • 双引号和单引号都可以,但是不要混用
  • 引号不能嵌套,双引号不能套双引号,单引号不能套单引号,可以单引号套双引号,或者双引号套单引
  • 在字符串中可以使用\作为转义字符
  1. Number 数值
  • 包括整数和浮点数(小数)
  • Number.MAX_VALUE表示整数最大值,如果超出了这值会返回Infinity(正无穷),-Infinity(负无穷)
  • Number.MIN_VALUE表示大于0的最小值(5e-324)
  • NaN(Not a Number)是一个特殊的数字表示不是一个数字
  • JS中整数运算基本可以保证精度,但是如果进行浮点计算,可能会得到一个不精确的结果
  • 千万不要使用JS进行精确度要求比较高的运算
  1. Boolean 布尔值
  • 布尔值只有两个值:true、false
  • 用于作逻辑判断
  1. Null 空值
  • NULL类型的值只有一个,就是null
  • null通常用来表示为空的对象
  1. Undefined 未定义
  • Undefined类型的值也只有一个,就是undefined
  • 当声明一个变量,但是并不给变量赋值时,它的值就是undefined
  • 使用typeof检测undefined,返回的是undefined
    — 引用数据类型

Obeject 对象

  1. 除了5种基本数据类型,其他的都是对象(object)
  2. 如果基本数据类型的数据,都是独立的,之间没有联系,不能成为一个整体
  3. 对象属于一种复合的数据类型,在对象种可以保存多种不同数据类型的属性
  4. 对象的分类:
  • 内建对象:
    — 由ES标准中定义的对象,在任何的ES中都可以使用
    — Math、String、Number、Object、Function、…都是内建对象
  • 宿主对象:
    — 宿主对象是运行环境提供的对象,主要是指由浏览器提供的对象
    — 比如BOM、DOM
  • 自定义对象:
    — 由开发人员自己创建的对象
    — 使用new关键字调用的函数,是构造函数constructor,new Object()
    — 构造函数是专门用来创建对象的函数

自定义对象

创建对象
  • 【方法一】
  • var a = new Object()
  • 【方法二】
  • var a = {属性名:属性值,属性名:属性值,...,属性名:属性值}
  • 【方法三】
  • 使用工厂方式创建对象都是Object,无法区分对象是人还是狗
  • 【方法四】 构造函数
  • 使用构造函数,来创建对象,构造函数和普通函数没有什么区别,但是构造函数习惯上首字母大写,区分:构造函数需要使用new关键字来使用
  • 使用构造函数创建的对象,称之为一类对象,也将构造函数称之为一个类
  • 通过构造函数创建的对象,称为该类的实例
  • 在构造函数中添加方法,则每个对象都会添加一个方法,应该进行改造,否则会导致时间增加
  • 【构造函数的执行流程】
  1. 立即创建一个对象
  2. 将新建的对象设置为函数中的this,在构造函数中可以使用this来引用新建的对象
  3. 逐行使用函数中的代码
  4. 将新建的对象作为返回值返回
  • 【exmaple】
function Person(name, age, gender) {
  this.name = name;
  this.age = age;
  this.gender = gender;
}
var per = new Person('w', 18, '女');
  • 【instanceof函数】
  • 可以使用instanceof函数检查一个对象是否是一个类的实例,如果是则返回true,否则返回false
  • 所有使用构造函数创建的实例对象都是一个object实例
原型对象
  1. 我们所创建的每一个函数,解析器都会向函数添加一个属性prototype,这个属性对应一个对象,这个对象就是我们所说的原型对象
  2. 如果只作为普通函数使用,原型对象没有任何作用
  3. 如果函数以构造函数的形式调用时,它所创建的对象都会有一个隐含的属性,这个属性指向构造函数的原型对象,我们可以通过proto访问这个属性
  4. 原型对象就像一个公共区域,所有同一个类的实例都可以访问到这个原型对象,我们可以将对象中共有的内容放到这个原型对象中
  5. 当我们访问一个对象的属性时,首先会现在对象自身寻找,如果找不到则会到原型对象中去找,如果没有在到原型对象的原型对象中去找,直到找到object对象的原型,object对象的原型没有原型,如果在object依然没有找到,则返回undefined
  6. 在创建时可以将对象共有的属性和方法,统一添加到构造函数的原型中,这样不用为每一个对象都添加,也不会影响到全局作用域
属性

— 对象的属性名不强制要求遵循标识符的规范,但是使用时还是尽量按照标识符的规范;如果说需要使用特殊的属性名,不能采用.的方式来操作,需要使用[]的方式来使用
— 使用[]的方式传递属性更加灵活,在[]里的值可以是可以变量,变量值是多少属性名就会是多少
— 在对象中保存的值是属性
— 向对象增加属性的方法

  • 对象.属性名 = 值 (修改也是如此,只是值是新值)
  • 对象[“属性名”] = 值
    — 读取对象的属性值
  • 对象.属性名
  • 对象[“属性名”]
    — 删除对象的属性值 delete 对象.属性名
    — JS对象的属性值可以是任何的数据类型,也可以是一个对象
    — in运算符可以检查一个对象中是否含有指定的属性,如果有则返回true,没有则返回false,”属性名” in 对象名
    — 对象是保存到堆内存中的,每创建一个对象,就会在堆内存中新开辟一个空间,而变量保存的是对象的内存地址(对象的引用),如果两个变量保存的是同一个对象引用,当一个变量修改属性,另一个也会受到影响
    — 比较两个基本数据类型的值时,就是比较值;比较两个引用数据类型时,比较的是对象的内存地址,如果两个对象是一模一样的,但是地址不同,这两个对象也是不同的
    — 枚举自变量中的属性
    使用for (var xxx in 对象名)语句
方法
  1. 对象的属性值可以是任何数据类型值,也可以是个函数
  2. 如果一个函数作为一个对象的属性保存,那么称这个函数是这个对象的方法,调用函数就说明对用对象的方法
字面量
  1. 通过字面量来创建对象:var obj = {属性名:属性值,属性名:属性值,....,属性名:属性值}
  2. 属性名可以加引号,也可以不加,但是运用到一些特殊名字,就必须使用引号
  3. 如果一个属性后面没有属性了就不要加’,’

内建对象

  1. ES标准帮我们弄建立的对象
  2. 数组就是一个内建对象
array(数组)
  1. 与普通对象的区分:对象使用的是属性名,属性名是字符串,而对于数组而言是用数字作为索引操作元素
  2. 索引:从0开始的整数就是索引
  3. 数组的存储性能比普通对象好,在开发中经常使用数组来存储一些数据
    【创建数组对象】
  • var arr = new Array(val1, val2, ..., val n);,如果只传了1个数值,会变成创建一个长度为该数值的数组,使用typeof会返回object
  • 使用字面量来创建数组var arr = [x1, x2, ..., xn]
    【向数组添加元素】
  • arr[index] = 值
    【读取数组的元素值】
  • arr[index]如果索引不存在不会报错,会返回undefined
    【数组的长度】
  • arr.length可以获取连续数组长度,对于不连续的数组,会返回最大索引+1
  • 可以通过缩小length来删除元素,可以通过增长length来拓宽长度
  • arr[arr.length] = 值每次向最末尾增加元素
    【数组的元素】
  • 数组中的元素可以是任意的数据类型(对象、数组….)
  • 数组中含有数组的是二位数组
    【数组的方法】
  1. push()可以向数组的末尾添加一个或多个元素,并返回数组的新的长度
    var result = arr.push('xx','xx','xx');
  2. pop()删除并返回数组中的最后一个元素
  3. unshift()可以向数组的开头增加一个或多个元素,并返回数组的新的长度
    var x = arr.unshift('xx','xx','xx')
  4. shift()可以删除并返回数组中的第一个元素
  5. slice(start, end)函数可以截取数组的部分并返回新数组,不会改变原数组,包含start索引,但是不包含end索引的值,当end索引没写时,就会从start索引开始截取,end也可以是负数,如果是负数,则是从后往前的位置
  6. splice(start, end, new1, new2)函数可以删除数组中的指定函数,spice()会影响到原数组,并将被删除的元素作为返回值返回,第一个参数为开始删除的索引下标,第二个参数为删除的长度,第三个及以后参数可以传递一些新的元素,并将这些元素插入到索引下标开始的位置
  7. concat(x,y,z…,n)函数可以连接两个或多个数组,并将新的数组返回,该方法不会对原数组产生影响
  8. join(指定连接符[不传为,])函数可以将数组转为一个字符串,该方法不会对原数组产生影响,而是将转换后的字符串作为结果返回
  9. reverse()会影响原数组,对数组进行反转
  10. sort(function(a, b){})会影响原数组,对数组进行排序,是按照unicode编码来排序的,对数字进行排序可能会得到错误的结果,可以自己指定排序的规则,可以在sort中添加一个回调函数,来指定规则,需要定义两个形参,数组中a一定在b的前面,浏览器根据回调函数返回值来决定,如果返回一个大于0的,则会交换位置,如果返回一个小于0的,则不会交换位置,如果说返回0,则认为两个值相等,则不会交换位置

【遍历数组】
【方法一】

for (var i = 0; i < arr.length; i++) {
  console.log(arr[i]);
}

【方法二】

  • forEach()函数
  • forEach()方法需要一个函数作为参数,像这种函数由我们创建但是不是由我们调用的函数称为回调函数
  • 浏览器会在回调函数中传递三个参数:第一个参数(正在遍历的元素)、第二个参数(正在遍历的元素的索引值)、第三个参数(遍历的数组)
Date

【创建Date实例】

  • var date = new Date(),如果没有传参数则就是现在的时间,如果传参数需要日期格式为月/日/年 时:分秒
    【获取当前日期是几日】
    var day = date.getDate()
    【获取当前日期是周几】
  • var day = date.getDay()返回0-6的值,其中0是指周日
    【获取当前日期的月份】
  • var month = date.getMonth()返回0-11的值,其中0表示1月,11表示12月
    【获取当前日期的年份】
  • var year = date.getFullYear()返回完整的年份
    【获取当前日期的时间戳】
  • var time = date.getTime(),时间戳是指从格林威治标准1970年1月1日到当前日期所花费的毫秒数,容易使计算机进行保存,计算机底层都是保存的时间戳
  • var time = Date.now();,可以利用这个时间戳计算程序执行的时间
Math
  1. Math属于工具类,它不是一个构造函数,不需要创建对象,里面封装了数学运算相关的属性和方法
    【方法】
  • Math.abs()可以用于求绝对值
  • Math.ceil(x)对数x进行向上取整,小数位只要有就会+1
  • Math.floor(x)对数x进行向下取整,小数部分会被舍弃
  • Math.round(x)对数x进行四舍五入取整
  • Math.random()可以生成0-1之间的随机数,不包括0也不包括1
  • 生成一个0-x之间的随机数:Math.round(Math.random() * x)
  • 生成一个x-y之间的随机数:Math.round(Math.random() * (y - x) + x)
  • 获取多个数之间的最大值:
    Math.max(x, y, z, ..., n);
  • 返回x的y次幂:Math.pow(x, y);
  • 对x进行开方:Math.sqrt(x)

包装类

  1. JS中为我们提供了三个包装类,可以通过这三个包装类将基本数据类型的数据转换为对象
  2. 在实际应用中不会使用基本数据类型的对象,在比较时可能会出现一些不可以预期的结果
  3. 当我们对一些基本数据类型的值去调用属性和方法时,浏览器会临时使用包装类将其转换为对象,然后再调用对象的属性和方法,调用结束后又将其转为基本数据类型
【String()】对象
  • 可以将基本数据类型的字符串转换成String对象
  • 在底层字符串是以字符数组的形式保存的
  • length属性可以获取字符串的长度
  • charAt(x)可以返回字符串中指定位置(x)的字符,不会改变原字符var res = str.charAt(x);
  • charCodeAt(x)可以返回字符串中指定位置(x)的字符的unicode编码var res = str.charCodeAt(x);
  • String.fromCharCode(x)可以获取指定字符编码(x)去获取字符
  • concat(x)方法可以连接字符串,var res = str.concat(x),功能和’+’一样
  • indexOf(x, y)方法可以检索一个字符串是否含有指定内容(x),如果字符串中含有该内容(x),则会返回第一次出现的索引,如果字符串中没有该内容,则会返回-1,可以指定开始查找的位置(y)
  • lastIndexOf(x, y)方法和indexOf(x, y)类似,但是lastIndexOf(x, y)是从后往前找,也可以指定从后往前找的开始位置
  • slice(x, y)方法可以从字符串中截取指定的内容,不会影响原字符串,而是将截取到的内容返回,x为开始的索引,y为结束的索引,包括x,但不包括y,y可以省略,如果省略则是截取到尾,也可以传递负数,负数代表从后往前的位置
  • substring(x, y)方法和slice(x, y)方法类似,但是substring不能传递参数为负数,如果传递了负数,会改为默认值0,并且如果第一个参数大于第二个参数,则会交换这两个位置的数值
  • substr(x, y)方法,截取开始位置的索引,x为开始索引,y为长度
  • split(x)方法需要一个字符串(x)作为参数,会根据该字符串去拆分数组var res = str.spliit(","),如果传递的是空串,则每个字符都会被拆分
  • toUpperCase()将字符串进行大写,并返回值
  • toLowerCase()将字符串进行小写,并返回值
正则表达式
  1. 正则表达式用于定义一些字符串的规则
  2. 计算机可以根据正则表达式来检查一个字符串是否符合表则
  3. 获取字符串中符合规则的内容提取出来
    【创建正则表达式对象】
    【方法一】
    var reg = new RegExp("正则表达式", "匹配模式")
  • 第二个参数可以是i忽略大小写,也可以是g全局匹配模式
  • 构造函数表达式比较灵活可以传递变量
    【方法二】字面量方法
    vae reg = /正则表达式/匹配模式
  • ‘|’来表达或的意思
  • []也可以表达或的意思
  • [a-z]表示任意的小写字母
  • [A-Z]表示任意的大写字母
  • [^ ] 除了
  • ^表示开头
  • ‘$’表示结尾
    【量词】
  • 通过量词可以设置一个内容出现的次数,
  • {n}正好出现n次,量词只对它前边的一个内容起效
  • {m,n}出现m-n次
  • {m,}出现m次以上
  • ‘+’表示至少1次,相当于
  • ‘*’表示至少0次,相当于
  • ‘?’表示0次或1次,相当于
  • ‘.’表示任意字符,如果想要表示’.’在正则表达式中使用”来作为转义字符
  • 注意:使用构造函数时,由于它的参数是一个字符串,因此如果要使用”也需要编写’\’
  • ‘\w’表示任意的数字、字母、_
  • ‘\W’表示除了字母、数字、下划线
  • ‘\d’表示任意的数字
  • ‘\D’表示除了数字
  • ‘\b’表示边界
  • ‘\B’表示边界
  • ‘\s’表示空格
  • ‘\S’表示除了空格
  • 如果想要对几个内容一起生效需要对内容使用'()’
    【example】
reg = /a|b/  //字符串中有a或者有b
reg = /a/ //字符串中含有a
reg = /[ab]/ //字符串中有a或者有b
reg = /[a-z]/ //表示任意小写字母 
reg = /a[bde]c/ //表示含有abc或adc或aec
reg = /[^ab]/ //表示除了包含a或b
reg = /[^0-9]/ //表示出了包含数字
reg = /b{3}/ //是否有连续的3个b
reg = /(ab){3}c/ //是否有连续的ab3次
reg = /ab{1,3}c/ //是否有1-3次的b
reg = /^a/ //表示是否以a开头
reg =/a$/ //表示是否以a结尾
// 判断一个字符串是否是一个合法手机号
reg = /^1[3-9]([0-9]){9}$/;
// 

【正则表达式的方法】

  • test()方法可以用来检查一个字符串是否符合正则表达式的规则,如果符合则会返回true,否则返回false
字符串和正则表达式
  1. split()可以将一个字符串拆分成一个数组,方法中可以传递一个正则表达式作为参数,会根据正则表达式来进行拆分数组,这个方法不指定全局,都会进行全部拆分
  2. search()可以搜索字符串中是否含有指定内容,一个接受一个正则表达式作为参数,然后会根据正则表达式去检索字符串,如果有会返回第一次出现的索引,如
    果没有则会返回-1,不能全局只能查找到第一个
  3. match()可以根据正则表达式,从一个字符串中将符合条件的内容提取出来;默认情况下我们的match只会找到第一个符合条件的内容,找到后就停止搜索,可以设置正则表达式为全局匹配模式,这样就会匹配到所有内容,会将匹配到的内容封装到一个数组中返回,即使只查询到一个结果
  4. replace(“被替换的内容”,”新的内容”)可以将字符串指定内容替换为新的内容,默认情况下只会替换第一个,被替换的内容可以使用正则表达式
    【examples】
// split()
var str = "a1b2c3d4e5";
var result = str.split("/[0-9]/");
// search()
var str1 = "hello abc hello adc"
var res = str1.search("/a[bd]c/");
// match()
var res2 = str.match("/[a-z]/gi");
// replace()
var res3 = str.replace("/[0-9]/g","@@");
【Number()】
  • 可以将基本数据类型的字符串转换成Number对象
【Boolean】/
  • 可以将基本数据类型的字符串转换成Boolean对象

强制类型转换

  1. 可以将数据类型进行转换成Number、String、Boolean
  2. 转成String类型的方法
    【方法一】:
  • 调用被转化数据类型的toString()方法[调用x的y方法,就是x.y()]
  • 在页面中直接打印一个对象时,事实上是输出的是toString()方法的返回值
  • 该方法不会影响到原变量,它会将转换的结果返回
  • 注意null和undefined这两个值没有toString()方法,如果调用则会报错
    【方法二】:
  • 调用String()函数,并将被转换的数据作为参数传递给函数,返回转换后的值
  • 对于Number和Boolean会直接调用toString()方法
  • 对于Null和Undefined会直接转化为”null”和”undefined”
  1. 转成Number类型的方法
    【方法一】:
  • 使用Number()函数
  • 字符串->数字:纯数字->数字,存在非数字->NAN,空串或全是空格->0
  • Boolean->数字:true->1、false->0
  • Null->0
    -undefined->NAN
    【方法二】:
  • 使用parseInt() 把一个字符转化为整数,可以将有效的整数内容取出来,转化为Number
  • parseInt(a, x) a表示数值,x表示进制
  • 使用parseFloat() 把一个字符转化为浮点数
  • parseFloat()、parseInt()如果转化非String类型,会先转化成String类型,然后再进行操作
  1. 转化成boolean
    【方法一】:
  • 使用Boolean()函数
  • 数字->boolean 除了0和NAN,都是true
  • 字符串->boolean 除了空转,都是true
  • null->false
  • undefined->false
  • 对象->true

其他进制的数字

  1. 如果想要表示16进制的数字,则需要以0x开头
  2. 如果想要表示8进制的数字,则需要以0开头
  3. 如果想要表示2进制的数字,则需要以0b开头
  4. 像”070″这种字符串,有些浏览器用parseInt进行会当成8进制

运算符

算数运算符(操作符)

  1. 通过运算符可以对一个、多个值进行运算,并取得运算结果
  2. typeof就是一个运算符,它会将值以字符串的形式返回
  3. 算数运算符
  • 一般不会对原变量进行改变,会返回一个值
  • 对非number值进行运算,会将非number转化成number(除了字符串加法)
  • 和NAN进行运算都会是NAN
  • 任何值和number作’-、*、/’运算都会将值转化成Number
  • 可以将一个值通过’+0’、’-0’、’/1’转化成Number
  • 可以将一个值通过+转化成Number
  • 任何值和string字符串进行’+’操作,就是拼串操作,会将值转化成字符串
  • 可以将一个值通过+”转化成字符串

逻辑运算符

  1. !可以用来对一个值进行非运算
  • 可以对此进行一个boolean类型进行取反操作
  • false->true true->false
  • 可以为一个任意数据类型进行!!操作,进行转化成boolean类型
  1. &&运算
  • 只有两个值都是true才返回true
  • 只要有一个为false就返回false
  • 如果第一个值为false,则会直接返回false,不会再与后面的做判断
  • 对于非boolean会先转化成boolean再进行运算,返回原值,不是true和false
  • 如果第一个值为false,则直接返回第一个值
  • 如果第一个值为true,则直接返回第二个值
  1. ||运算
  • 只要有一个true,就返回true
  • 两个都是false,才会返回false
  • 如果第一个值为true,则会直接返回true,不会再和后面的做判断
  • 如果第一个值为false,则会直接返回第二个值
  • 如果第一个值为true,则会直接返回第一个值

赋值运算符

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

关系运算符

>、>=、<、<=、==、!=、===、!==

  • >、>=、<、<=
  1. 非数值型会和数值型比先转化成数值型,才会进行比较
  2. 任何值和NaN作比较都会是false
  3. 如果两边都是字符串,不会转成数值型,会比较unicode;比较时是一位一位进行比较的
  4. 注意如果在比较两个字符串的数字时,一定要注意转型
  • ==、!=
  1. 在进行’==’关系比较时,会进行数值转化,大部分情况下,都会转化成数值型
  2. null == 0 返回false
  3. null == undefined 返回true 因为undefined衍生自null
  4. NaN不和任何值相等,包括自身
  5. 可以通过isNaN()函数来判断一个值是否为NaN
  6. ‘!=’的操作和’==’类似
  • ===、!==
  1. ‘=‘和’!‘不会做类型转化
  2. 如果两个值的类型不同,直接返回false

条件运算符(三元运算符)

  1. 条件表达式?语句1:语句2;
  2. 执行的流程:条件运算符在执行时,首先对条件表达式进行求值,如果该值为true,则执行语句1,并返回执行结果,如果该值为false,则执行语句2,并返回执行结果
  3. 如果说条件表达式的值为非boolean值则会转化成boolean值

运算符的优先级

  1. &&的优先级高于||
  2. 查看优先级表

unicode编码

  1. 在JS中可以用\u+四位编码进行表示
  2. 如果想要在网页中进行显示,需要通过&#进行表示

代码块

  1. 语句是从上向下一条一条执行的
  2. 同一个{}中的语句我们称为一组语句,也称为一个代码块

语句

  • 条件判断语句
  1. if语句只能控制其随后的一条语句
  2. 如果希望if语句能控制多条语句,可以将这些语句放到一个代码块中
  3. if、if..else、if..else if..else
  • 条件分支语句
  1. switch case
  • 循环语句
  1. while
  2. do while
  3. for 循环
  • break和continue

函数

  1. 函数也是一个对象
  2. 函数中可以封装一些代码,在需要时可以执行这些功能(代码)
  3. 创建一个函数对象:
    【方法一】:
  • var fun = new Function("");,可以将要封装的代码以字符串的形式传递给构造函数(很少使用)
    【方法二】使用函数声明来创建一个函数:
  • function fun(形参1, 形参2, 形参3,...形参n) { ....内容 }
    【方法三】使用函数表达式来创建一个函数
  • var 函数名 = function([形参1, 形参2, 形参3, ..., 形参n]);
  1. 封装到函数中的代码不会立刻执行,函数只有在调用的时候才会被执行
  2. 调用函数:函数对象名();

函数的参数

  1. 可以在函数()中来指定一个或多个形参(形式参数)
  2. 多个形参之间用’,’隔开,声明形参就相当于在函数内部声明了对应的参数
  3. 在函数调用中,可以在()中指定实参(实际参数),实参将会赋值给对应的形参
  4. 调用函数时解析器不会检查实参的类型,所以要特别注意是否接受到非法的参数,需要对参数进行类型的检验
  5. 调用函数时解析器不会检查实参的数量,如果实参的数量少于形参的数量,则没有对应的实参的形参是undefined
  6. 函数的实参可以是任意的数据类型

函数的返回值

  1. return后的值用作为函数的执行结果返回
  2. 可以定义一个量,来接收该结果
  3. 在return后的语句都不 会被执行
  4. 如果函数中没有写return,则也会返回undefined
  5. return可以结束整个函数
  6. 返回值可以是任意的数据类型,也可以是一个对象

立即执行函数

  1. 函数定义完,就会被立即执行,这种函数是立即执行函数
  2. 立即执行函数往往只会执行一次

函数作用域

  • 在JS中有两种作用域:全局作用域、局部作用域
  • 【全局作用域】
    — 直接编写在script标签中的JS代码,都在全局作用域
    — 全局作用域在页面打开时开启,在关闭时销毁
    — 在全局作用域中有一个全局对象window,它代表一个浏览器窗口,由浏览器创建可以直接使用
    — 创建的对象都会作为window对象的属性保存
    — 创建的函数都会作为window对象的方法保存
    — 在页面的内容部分都可以被访问到
  • 【局部作用域】
    函数作用域
    — 调用 函数时创建函数作用域,函数执行完毕以后,函数作用域销毁
    — 每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的
    — 在函数作用域中可以访问到全局作用域的变量
    — 在全局作用域没办法访问到局部作用域
    — 当在函数作用域中操作一个变量会先在自身作用域中查找是否有该变量,如果有会直接使用,否则会向上一级作用域中查找,直到全局作用域中查找,如果全局没有,则会报错
  • 【变量的声明提前】
    — 使用var关键字声明的变量,会在所有代码执行之前被声明(但是不会赋值)
    — 如果没有使用var关键字声明的变量,则变量不会被声明提前
    — 使用函数声明创建函数,函数会被提前创建
    — 使用函数表达式创建函数,变量会提前创建,但是是undefined,不会声明提前
    — 在函数作用域中也有声明提前
    — 在函数作用中,函数声明也会在所有代码执行之前执行

函数的方法

— call()、apply()

  • 可以将一个对象指定为第一个参数,对象会成为函数执行时的this
  • call()方法可以将实参在对象之后依次传递
  • apply()方法需要将实参封装到一个数组中统一船体

this

  1. 解析器在调用函数时,每次都会向函数传递一个隐含的参数(this),this是一个对象(上下文对象)
  2. 根据函数调用方法的不同,this会指向不同的对象
  3. 以函数形式调用,this就是window对象
  4. 以方法形式调用,this就是调用它的那个object对象
  5. 使用call()、apply()调用时,this是指那个对象
  6. 在事件的响应函数中,响应函数是给谁绑定的,this就是谁

arguments

  1. 在调用函数时,浏览器每次都会传递两个隐含的参数(this、arguments)
  2. arguments是一个类数组对象,可以通过索引来操作数据,也可以获取长度
  3. 在调用函数时,定义不定义形参,我们所传递的实参都会保存在arguments中
  4. arguments的操作类似与数组的操作
  5. arguments有一个属性callee,这个属性就是当前证在指向的函数的对象

垃圾回收

  1. 在JS中有自动的垃圾回收机制,会自动将这些垃圾对象从内存中销毁,我们不需要进行垃圾回收的操作
  2. 我们需要将不在使用的对象设置为null

常用函数

  1. prompt(‘提示信息’)函数可以弹出一个带有输入的框,输入的值作为函数返回值返回
  2. document.write(‘xxx’)向网页中写入xxx内容
  3. console.time("计时器的名字"),开启一个计时器;console.timeEnd("计时器的名字"),关闭一个计时器
  4. Math.sqrt()可以对一个数进行开方
  5. hasOwnProperty(“xxxx”)函数可以判断一个对自身象是否有该xxx属性
  6. confirm(提示语)可以弹出一个具有取消和确认的提示框,确认会返回true,取消会返回false

DOM Document Object Mdoel文档对象模型

  • JS中是通过DOM来对HTML文档进行操作
  • 文档:表示的就是整个的HTML网页文档
  • 对象:表示将网页中每一个部分转化成了一个对象
  • 模型:使用模型来表示对象之间的关系,这样方便我们获取对象
  • 节点:构成网页的最基本部分
    — 文档节点:整个HTML文档
    — 元素节点:HTML文档中的HTML标签
    — 属性节点:元素的属性
    — 文本节点:HTML标签中的文本内容

事件

  • 文档或浏览器窗口中发生的一些特定的交互事件
  • 事件就是用户和浏览器之间的一些交互行为
  • 事件发生后最重要的就是处理事件,事件对应的一些属性中设置一些js代码,当事件被触发时,这些代码将会被执行,但是这种写法结构和行为耦合,不方便维护,不推荐使用
  • 事件处理方式:可以为其对应事件绑定处理函数的形式来响应事件 ,这种函数称之为响应函数
  • 为window绑定一个onload事件,该事件对应的响应函数将会在页面加载完成之后执行,这样能确保我们的代码执行时所有的DOM对象都已经加载完毕了

DOM查询

  1. getElementById("id名")查找指定id名的节点
  2. getElementsByTagName("标签名")根据标签名获取一组节点,会返回一个类数组对象,即使查询到的元素只有1个也会封装到数组中
  3. getElementsByName("name名")根据name标签类获取一组节点,会返回一个类数组对象
  • innerHTML用于获取元素内部的HTML代码,对于自结束标签是没有意义的
  • innerText用于获取到元素内部的文本内容,与innerHTML类似,但是会自动去除HTML标签
  • 读取class属性时应该使用className
  1. childNodes属性会获取包括文本所在的节点,DOM标签之间的空白也会被当成文本节点,但是IE及以下的浏览器,不会将空白文本当成子节点
  2. children属性可以获取当前元素的所有子元素而不是子节点
  3. firstChild可以获取当前元素的第一个子节点包括空白文本节点
  4. firstElementChild可以获取当前第一个子元素,但是不支持IE8及以下的子元素
  5. parentNode可以获取当前节点的父节点
  6. previousSibling可以获取当前节点的前一个兄弟节点,但是也可能获取空白的文本节点
  7. previousElementSibling可以获取当前节点的前一个兄弟元素
  8. 文本框的value值就是文本框中填写的内容
  9. 获取body标签var body = document.getElementsByTagName("body")[0]; var body = document.body;
    在document中有一个属性body,它保存的是body的引用
  10. 获取html标签var html = document.documentElement
  11. document.all表示页面中所有的元素:var all = document.all;all = document.getElementsByTagName(*);
  12. 根据元素的class属性查询一组元素节点元素document.getElementsByClassName("class名"),但是兼容差,IE8以下不支持
  13. document.querySelector(“选择器”)需要一个选择器的字符串作为参数,可以根据一个CSS选择器来查询一个元素节点对象,如果满足条件的元素有多个,那么它只会返回满足条件的第一个元素
  14. document.querySelectorAll(“选择器”),用法和querySelector()类似,但是它会返回满足条件的所有条件,即使满足条件的只有1个,也会返回一个数组

DOM新增

  1. document.createElement("标签名")创建一个元素节点对象,它需要一个标签名作为参数,并将创建好的对象作为返回值
  2. document.createTextNode()创建一个文本节点,并将新的节点返回
  3. appendChild()向父节点中添加一个新的节点,用法:父节点.appendChild(子节点)
  4. 父节点.insertBefore(newchild, oldchild)在指定的子节点前面插入新的子节点,父节点调用
  5. 通过innerHTML进行添加,但是一般不进行完全的修改,一般会结合appendChild()等函数进行一起使用

DOM修改

replaceChild()可以使用指定的子节点替换已有的子节点,语法:父节点.replaceChild(新节点,旧节点)

DOM删除

removeChild()可以删除一个子节点,语法:父节点.remove(子节点)

元素的样式

【通过内联样式】

  1. 通过JS来修改元素的样式,语法:元素.style.样式名 = 样式值
  2. 如果说CSS的样式名终含有-,这种明明是不合法的,需要将这种样式名进行修改,将’-‘去除,将’-‘后的元素进行修改
  3. 通过style属性设置的样式都是内联样式,而内联样式有比较高的优先级,通过JS修改的样式往往会立即显示
  4. 如果在样式中写了!important,则此时样式会有最高的优先级,即使JS也不能覆盖该样式,此时会导致JS修改样式失效,所以尽量不要为样式添加!important
  5. 通过style读取和设置的都是内联样式,无法读取样式表中的样式
    【获取元素当前显示的样式】
  6. 元素.currentStyle.样式获取的是当前元素正在显示的样式(不一定读的是样式表),如果当前元素没有设置样式,则获取它的默认值,但是只有IE8支持该方法
  7. 在其他浏览器中可以使用getComputedStyle(获取样式的元素, 可以传递一个伪元素,一般都传null).样式这个方法来获取当前的样式,需要两个参数,会返回一个对象,对象中封装了当前元素的样式,但是如果说获取的样式没有设置,则会获取到真实的值,而不是默认值,不如没有设置width,他不会获取到auto,而是一个长度,但是不兼容IE8
  8. 通过currentStyle和getComputedStyle获得的属性都是只读的不能修改
  9. 同时兼容浏览器:
  function getStyle(obj, name) {
    if(window.getComputedStyle) {
      return getComputedStyle(obj, null)[name];
    } else {
      return obj.getCurrentStyle[name];
    }
 }

【获取元素的样式相关属性】
【只读属性】

  1. clientWidth、clientHeight属性返回的数字可以直接进行计算,返回的是元素的内边距和内容区,不包括border
  2. offsetWidth、offsetHeight属性获取整个的宽度和高度,包括内容区、边框
  3. offsetParent属性可以获取当前元素的定位父元素,会获取到离当前元素最近的开启了定位的祖先元素,如果祖先元素都没有开启定位,会返回body元素
  4. offsetLeft、offsetTop相对于其定位父元素的偏移量
  5. scrollWidth、scrollHeight可以获取整个滚动区域的宽度和高度
  6. scrollLeft、scrollTop可以获取水平、垂直滚动条的距离
  7. scrollHeight – scrollTop == clientHeight,scrollWidth - scrollLeft == clientWidth等式满足时,表示水平、垂直滚动条都到底了

事件

  1. onmousemove该事件将会在鼠标在元素中移动时触发
  2. 事件对象:当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数,在事件对象中封装了当前事件相关的一切信息包括鼠标的坐标,键盘哪个按键被按下,鼠标滚轮滚动的方向,但是在IE8及以下的浏览器中,是将事件对象作为window对象的属性保存的,但是window.event火狐浏览器不支持
    事件对象的属性:
    clienX、clientY表示鼠标的水平位置和垂直位置,相对于可见窗口
    PageX、PageY表示鼠标的水平位置和垂直位置,相对于当前页面(这两个属性在IE8中不支持)
  3. 兼容性处理
event = event || window.event; //IE8的事件对象是放在window上的
// body页面溢出后,不同浏览器对于认为的滚动条在谁身上是不一定
var st = document.body.scrollTop || document.documentElement(HTML标签).scrollTop;
var sl = document.body.scrollLeft || document.documentElement.scrollLeft;

事件的冒泡

  1. 所谓的冒泡指的是事件的向上传导,当后代元素上的事件被触发时,祖先上的相同事件也会被触发
  2. 在大部分的开发中冒泡都是有用的,如果不想要事件冒泡,可以为其取消事件冒泡event.cancleBubble = true

事件的委派

  1. 当为超链接绑定单击响应函数时,新增的超链接必须重新绑定,只有旧的超链接才有单击响应函数
  2. 只绑定一个事件,可以应用到多个的元素上,即使元素是后添加的
    【做法】
  • 将事件绑定到元素的共同祖先元素上
    【事件的委派】
  • 指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
  • 事件委派利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能

事件的绑定

【方法一】
使用对象.事件 = 函数的形式绑定响应函数,它只能同时对一个元素的一个事件绑定一个响应函数,不能绑定多个,如果绑定了多个,后面的会覆盖前面的
【方法二】
可以通过addEventListener()方法为元素绑定响应函数

  • 参数1:事件的字符串不要on
  • 参数2:回调函数,当事件触发时该函数会被调用
  • 参数3:是否在捕获阶段触发事件,需要一个布尔值,一般都传false
  • 可以同时为一个元素的相同事件同时绑定多个响应函数,这样事件被触发时,响应函数将会按照绑定的顺序执行
  • this是绑定事件的对象
  • IE8不支持但是其他的浏览器支持
    【方法三】
  • IE8支持attachEvent(),其他浏览器不一定支持
  • 参数1:事件的字符串需要on
  • 参数2:回调函数
  • 执行顺序和addEventListener()相反
  • this是window
    【兼容性问题】
function bind(obj, eventStr, callback) {
  if (obj.addEventListener) {
    obj.addEventListener(eventStr, callback, false);
  } else {
    obj.attachEvent("on" + eventStr, function() {
    callback.call(obj);    
});
  }

}

事件的传播

【捕获阶段】:在捕获阶段时从最外层向目标元素进行事件的捕获,但是默认此时不会进行事件的执行
【目标阶段】:事件捕获到目标元素,捕获结束后开始在目标元素上触发事件
【冒泡阶段】:事件从目标元素向它的祖先元素传递,依次触发祖先元素上的事件

  • 如果希望在捕获阶段就开始执行,可以将addEventListener()中的第三个参数修改成true,但是这个参数一般为false
  • IE8不会有捕获阶段

拖拽的实现

【流程】:

  1. 当鼠标在被拖拽元素上按下时,开始拖拽onmousedown
  2. 当鼠标在被拖拽元素跟着鼠标移动 onmousemove
  3. 当鼠标在被拖拽元素上松开时,结束拖拽onmousedown
  • 当我们拖拽一个网页的内容时,浏览器会默认去搜索殷勤中搜索内容,此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,如果不希望发生该行为可以通过return false来解决,但是对于IE8来说不支持
  • 对于IE8来说可以用setCapture和releaseCapture来解决

鼠标滚轮

  • onmousewheel来绑定鼠标滚轮滚动的事件,但是有的浏览器可能不支持
  • 火狐可以使用DOMMouseScroll
  • wheelDelta可以获取鼠标滚动的方向,向上为负,向下为正
  • 当我们有滚动条时,滚动条会随之滚动,如果不希望发生可以取消默认行为,return false即可
  • 可能有些浏览器不支持,需要注意

键盘事件

  1. onkeydown、onkeyup对应键盘被按下和键盘被释放,一般都将该事件绑定给可以获取焦点的对象或者是document
  2. 对于onkeydown来说如果一直按着某个按键不松手,则事件会一直被触发
  3. 对于onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他会非常快,这是为了防止用户的误操作
  4. 在文本框中输入内容,属于onkeydown的默认行为,如果不想输入则可以通过return false来取消默认行为,也可以判断当某个值时不被输入
  5. 对于onkeyup松开一次只会触发一次
  6. 通过event.keycode可以判断哪个按键被按下
  7. 通过event.altKey、event.crtlKey、event.shiftKey判断alt、crtl、shift有没有被按下

BOM

  1. BOM为浏览器对象模型,BOM可以通过JS来操作浏览器,在BOM中为我们提供了一组对象,用来完成对浏览器的操作
  2. BOM对象
    — Window:代表整个浏览器的窗口,同时window也是网页中的全局对象
    — Navigator:代表当前浏览器的信息,通过该对象可以识别不同的浏览器
    — Location:代表浏览器的地址栏信息,通过Location可以获取地区栏信息,或者操作浏览器跳转页面
    — History:代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,由于隐私原因,该对象不能获取到具体的历史信息,只能操作浏览器向前或向后翻页,该操作只在当次访问时有效
    — Screen:代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息
    — 这些BOM对象在浏览器中都是作为window对象的属性保存的,也可以通过window对象来使用,也可以直接使用

— 由于历史原因,navigator对象中的大部分属性已经不能帮助我们试别浏览器了

  • 一般我们只会使用userAgent来判断浏览器的信息,整个字符串包含有用来描述浏览器的信息,结合正则表达式使用
  • 如果通过UserAgent不能判断,还可以通过一些浏览器中特有的对象来判断浏览器的信息

History

  • history.length可以获取到当前访问的链接的数量
  • history.back()可以回退到上一个页面,作用和浏览器的回退一样
  • history.forward()可以跳转到下一个页面,作用和浏览器的前进一样
  • history.go()可以跳转到指定页面,表示向前跳转一个页面,需要1个整数作为参数,参数1相当于forward(),参数2相当于往前跳2个,-1表示往后跳1个,-2表示往后跳2个

Location

  1. Location对象封装了浏览器的地址栏的信息
  2. 如果直接打印location则可以获取到地址栏的信息(当前页面的完整路径)
  3. 如果直接将location = 一个完整路径或相对路径,则页面会自动跳转到该路径,并且会生成相应的历史记录
  4. assign("一个完整路径或相对路径")方法用来跳转到其他页面,作用和直接修改location作用一样
  5. reload()用于重新加载当前页面,作用和刷新按钮一样,如果在方法中传递了一个true,则会强制清空缓存刷新页面
  6. “replach()可以使用一个新的页面替换当前页面,调用完毕后也会跳转页面,但是不会生成历史记录,不能回退

window

  1. 如果希望一段程序可以每个一段时间执行一次,可以使用定时调用
  2. setInterval(回调函数,每次调用间隔的时间)方法,可以将一个函数每隔一段时间执行一次,单位是毫秒,该函数会有一个返回值会返回一个Number类型的数字,该数字作为定时器的唯一标识
  3. clearInterval(定时器标识)可以关闭一个定时器,方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器,可以接受任何参数,如果参数是一个有效的定时器标识,可以停止对应的定时器,如果参数不是有效的定时器标识,则什么也不做;如果只希望有一个定时器,需要在开启定时器之前关闭上一个定时器
  4. 延时调用一个函数不马上执行,而是隔一段时间以后再执行,而且只会执行一次,延时调用和定时调用之间是可以互相代替的

类的操作

  1. 通过style属性一行一行进行修改,会导致浏览器就重新渲染一次页面,会消耗比较多的紫云啊
  2. 可以通过修改元素的class属性来间接修改样式,这样只需要修改一次,就可以同时修改多个样式,浏览器只需要重新绚烂一次,性能比较好,这种方式可以将表现和行为进一步分离

JSON

  1. JS中的对象只有JS自己认识,其他语言都不认识
  2. JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别,并且可以转换为任意的语言,JSON在开发中主要用于数据的交互
  3. JSON中允许的值:数值、字符串、NULL、布尔值、对象、数组
  4. JSON的类型:对象(只能是普通对象)、数组
  5. 在JS中,为我们提供了一个工具类,就叫JSON,这个对象可以帮助我们将一个JSON转换为JS对象,也可以将一个JS对象转为字符串
  6. JSON->js对象:JSON.parse(JSON字符串),会将该字符串转换为JS
  7. JS对象->JSON:JSON.stringify(JS对象)
  8. JSON这个对象IE7及以下不兼容,可以用eval()这个函数可以执行一段字符串形式的JS代码并将执行结果返回,如果使用eval()执行的字符串中含有{},它会将{}当成代码块,如果不希望将其当成代码块解析,则需要在字符串加一个'()’,在开发中尽量不要使用,执行性能较差,还具有安全隐患
  9. 如果想要兼容IE7及以下可以引入一个json文件就可以解决

ES6

let关键字

【let声明变量的特性】

  • 变量不能重复声明,对于var而言可以重复声明
  • 块级作用域 全局、函数、eval中定义的变量只能代码块里面生效
  • 不存在变量提升,对于var而言会将提前声明
  • 不影响作用链,如果该级没有就会向上寻找

常量

  • 一定要附初始值
  • 一般常量使用大写(潜规则)
  • 常量的值不能修改
  • 块级作用域
  • 对于数组和对象的元素修改,不算做常量的修改,不会报错,因为数组和对象存的是内存地址,只要地址不变,就认为没有进行修改

变量结构赋值

ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值

  • 数组的解构
    【example】
const a = ['name', 18, '北京'];
let [name, age, address] = a;
console.log(name, age, address);
  • 对象的解构
    【example】
const st = {
  name: '小王';
  age: 18;
};
let {name, age} = st;
console.log(name, age);

模板字符串

  • ES6引入新的声明字符串的方式[‘“’]、”、””
  • 内容中可以直接出现换行符
  • 也可以进行变量拼接,在使用单引号和双引号时都是用字符串进行拼接,但是如果说使用新的声明字符串符号,在字符串里想要引用变量的值,可以使用${变量名}
    【example】
let str = ''

简化对象写法

  • ES6允许在大括号中,直接写入变量和函数,作为对象的属性和方法,这样的书写更加简洁
  • 对象中的函数可以将:funcition省略不写
    【example】
let name = '王';
let age = 18;
let change = function() {
  console.log('hello');
}
let obj = {
  name,
  age,
  change, 
  ad() {
    console.log('你好');
  }
}

箭头函数

  • ES6允许使用=>定义函数
  • this是静态的,this始终指向函数声明时所在作用域下的this的值,使用call函数无法改变this的值
  • 不能作为构造实例化对象
  • 不能使用arguments变量
  • 小括号可以省略: 当形参只有一个的时候
  • 代码提只有一条语句的时候,此时return必须省略,而且语句的执行结果就是函数的返回值
  • 箭头函数适合与this无关的函数回调,定时器,数组的方法回调
  • 箭头函数不适合与this有关的函数会掉,事件回调,对象的方法
let fun1 = function() {
  console.log(this.name);
};
// 可以改写成
let fun2 = () => {
  console.log(this.name);
};
// 省略小括号
let fun3 = n => {
  console.log(n);
};
// 省略花括号
let fun4 = n => n * n;
console.log(fun3(1));
console.log(fun4(2));

参数默认值

  • ES6允许给函数参数赋初始值
  • 形参初始值,具有默认参数的参数一般位置要往后靠
  • 可以与解构赋值结合
    【examples】
let fun5 = function({name='小黑',age, address}) {
  console.log(name, age, address);
}

let obj = {
  name:'小王',
  age:18,
  address:'福建'
};
fun5(obj);

rest参数

  • ES6引入rest参数,用于获取函数的实参,用来代替arguements,arguments是对象,而rest是数组,rest参数使用方法:...args,位置一定要放在最后
  • 读取的并不是所有的实参,而是多个没有定义形参的实参值,在函数的形参需要定义...args
  let fun6 = function(a, b, c)  {
    console.log(arguments);
  };
  let fun7 = function (a, b, ...args){
    console.log(...args);
  };
  fun6(1, 2, 3);
  fun7(1, 2, 3, 4, 5, 6);

扩展运算符

  • ...扩展运算符能将数组转换成逗号分隔的参数序

    【应用场景】
  • 可以进行数组合并
  • 进行数组的克隆
  • 可以将伪数组转为真数组
    【examples】
let arr1 = [1, 3, 4];
let arr2 = [2, 5, 6];
let arr3 = [...arr1, ...arr2];
let arr4 = [1, 2, 3];
let arr5 = [...arr4];
console.log(arr5);

symbol

  • 表示一个独一无二的值,是一种类似于字符串的数据类型
  • 不能使用for..in遍历
    【创建Symbol】
  • let s = Symbol();可以传入一个参数,但是传入的参数相同,值是不一样的
  • let s = Symbol.for();也可以传入一个参数,传入的参数相同,值是一样的
  • 不能与其他数据进行运算
    【应用】
  1. 可以为对象添加唯一属性
  2. Symbol的属性可以用来做很多事情,作为对象的一个属性来进行处理

迭代器

  • 迭代器是一种接口,可以为不同数据类型提供统一的访问机制,任何结构只要部署了iterator接口,就可以完成遍历操作
  • 如果可以使用的话,说明该对象中含有Symbol.iterator属性,该属性中会有一个next方法,每次调用完,会将指针自动指向数据结构的第一个成员,然后不停调用直到指向最后一个成员,每次调用next方法返回一个包含value和done属性的对象
  • let i in 对象i为键的值
  • let i of 对象i为值
  • 可以自定义遍历器

生成器

  • 异步编程 纯回调函数,函数比较特殊函数名之前有一个*,可以生成一个iterator对象
  • 调用后不会执行,而需要通过.next()方法执行
  • 函数内可以通过yield进行返回
  • 每次调用一次.next()会执行一部分代码,可以配合iterator使用
  • 生成器函数可以传入参数(在生成器函数调用时,传入的参数)
  • next方法也可以传入参数(第一次调用next方法,传入的参数没意义,第二次调用next方法传入的参数将作为第一次yield的返回值,第三次调用next方法传入的参数将作为第二次yied的返回值,以此类推)
  • 生成器可以解决地狱回调的问题

Promise对象

then方法

  • promise.then()方法返回的也是一个Promise对象,对象状态由回调函数的执行结果决定,如果回调函数返回的结果是非Promise类型的属性,返回的Promise对象的状态属性未成功(resolved),如果回调函数返回的结果是Promise对象且成功,那么返回的Promise对象的状态属性也为成功,如果失败,是失败状态,数据都是返回的数据
  • Promise封装可以解决读取文件时地狱回调的问题(利用then方法)

catch方法

p.catch(回调函数)可以指定回调失败时的操作

集合

【声明集合的方法】

let s = new Set();
let s2 = new Set([, , , ]);
  • 集合会自动为我们去重
    ** 【集合的方法】**
  • add()添加元素
  • delete()删除元素
  • clear()清空数据
  • has()判断是否有某个元素
    【集合的属性】
  • 集合的元素个数:集合对象名.size
  • 可以使用迭代器一起使用,遍历集合

Map

  • 声明map:let m = new Map();
  • 添加元素:m.set('键','值');,键值可以是任何数据类型
  • 删除元素:m.delete('键');
  • 获取元素:m.get('键'(键变量名));
  • 清空元素:m.clear();
  • 遍历map,利用迭代器for (let i of m)

【创建类】

class 类名{
  constructor(){

  }
  // 之间不用逗号隔开,方法必须使用省略的方法, 
  // 不能使用ES5的对象完整形式
  // eg.
  call() {

  }
}

【静态成员】
可以使用static来构造类实例对象共有的数据类型
** 【继承】**

  • 使用extends,利用super调用父类的构造函数
    ** 【重写】**
  • 可以对父类有的方法进行重写,调用时会调用子类的
    【get和set】
get price(){ //获取price属性时会执行该函数

}
set price() { //修改price属性时会执行的函数
}

数值拓展

  • Number.EPSILON()是Javascript表示的最小精度
  • Number.isFinite()判断一个数是不是有限数
  • Number.isNaN()判断一个数是否为NaN
  • Number.parseInt()字符串转为整数
  • Math.trunc将数字的小数部分省略
  • Math.sign判断一个数是正还是负,返回的值分别为1,0,-1

模块化

  • export import
    【引入方式】
  • 通用的导入方式、解构赋值形式、简单方式(只适用于默认暴露)
    【暴露】
  • 分别暴露、统一暴露、默认暴露、
  • 可以有一个入口文件,进行统一的模块化引入,通过script标签进行引入,记住要模块的类型是”module”

ES6-babel对ES6模块化代码转化

  • npx babel 转化的代码路径 -d 转化后的代码路径 -- presets-babel-preset-env
  • 打包 npx browserify 路径 -o
    转化后的文件路径

ES7

  1. includes方法用来检测数组中是否包含某个元素,返回boolean类型,而indexOf返回的是下标
  2. **表示幂运算

ES8

  1. async函数
  • 返回值为promise对象
  • promise对象由async函数执行的返回值来决定,只要不是返回一个Promise类型的对象,则返回的都是Promise成功的对象且返回值就是PromiseValue
  • 如果返回的对象是Promise对象,如果是成功的且PromiseValue的值是成功的值,如果是失败的且PromiseValue的值是失败的值
  1. await函数
  • await必须写在async函数中
  • await右侧的表达式一般是promise对象
  • await返回的是promise成功的值
  • await的promise失败了,会抛出异常,需要通过try catch捕获
    const p1 = new Promise((resolve, reject)=>{
        reject('ok的?');
    });
    async function fun11() {
        try{
            let result = await p1;
            console.log(result);
        } catch(e) {
            console.log('p[p[]]');
            console.log(e);
        }
    }

// async和await结合读取
const fs = require('fs');

function read() {
    return new Promise((resolve, reject) => {
        fs.readFile('1.txt', (err, data)=>{
            if (err) {
                reject(err);
            } else {
                resolve(data);
            }
        })
    });
}

async function fun11() {
    let res = await read();
    console.log(res.toString());
}

fun11();

对象方法拓展

  1. 获取所有的键Object.keys(对象名);
  2. 获取所有的值Object.values(对象名);
  3. 获取所有的键值对Object.entries(对象名)返回的是一个数组
  4. 获取的是对象属性描述对象Object.getOwnPropertyDescriptors(对象名);

ES9

拓展运算符

  1. 在ES6中拓展运算符只针对数组,在ES9中可以将一个对象使用…进行展开

正则拓展

  1. 命名捕获分组可以使用?<变量名>
  • 之后可以通过变量名去访问具体捕获到的值
    let str1 = `<a href='www.baidu.com'>你好</a>`;
    let reg = /<a href=(?<url>.*)>(?<text>.*)<\/a>/;
    const res9 = reg.exec(str1);
    console.log(res9.groups.url);
  1. 正向断言
    (?=具体值)后边是不是等于具体的值
    (?<=具体值)前边是不是等于具体的值
  2. dotAll模式
    s是匹配所有换行包括空格等

ES10

对象拓展方式

Object.fromEntries()将一个数组转化成对象
Object.entries()将一个对象转化为二位数组

trimStart() trimEnd()

  • 清除开始空格字符和清楚结束空格字符

flat与flatMap

  • flat()方法将数组降维度,可以传一个参数,参数为深度,默认值为1
  • flatMap()方法将返回结果降维度

Symbol的属性拓展

对象.description获取Symbol对象的描述

私有属性

  1. 私有属性前面加个#符号
  2. 私有属性不能直接访问,需要定义在类中定义函数访问

allSettled()

  • Promise.allSettled(Promise对象)始终都能返回Promise对象

all()

  • Promise.all(Promise对象)只有成功才能返回Promise对象

matchAll()方法

可选链操作符 ?

  • ?可以判断是否有该值,可以免去层级判断

ES11

动态import

import返回的是一个promise对象

BigInt数据类型

  • let n = 123n是一个大整型
  • 不能对浮点数进行大整型转化

globalThis

版权声明:本文为feiru-cnblogs原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/feiru-cnblogs/p/17127831.html