- let
- const 定义常量
- 解构赋值
- 数组
- 对象
- 对象的简化写法
- ``反单引号模板字符串
- => 箭头函数
- 形参赋初始值
- ...X rest参数
- ...扩展运算符
- 描述
- 一些应用
- 数组的合并
- 数组的克隆
- 将伪数组转为真正的数组
- Symbol()数据类型
- Symbol 特点
- Symbol内置属性
- 迭代器
- 介绍
- for of 与 for in
- 自定义迭代器接口
- 生成器函数 yield
- 介绍
- 实例
- Set集合
- 声明
- 部分集合的方法
- promise
- Map地图对象
- 介绍
- 部分函数
- class类
- 介绍
- 静态成员
- 构造函数的继承
- 类的继承
- get set
- get
- set
- 数值扩展
- Number.EPSILON 最小精度
- 变量的进制表达方式
- Number.isNaN()判断是否为一个数字
- Number.parseInt()将字符转为整形的数字
- Number.isInteger() 是否为整形
- 对象方法扩展
- Object.is() 判断两个值是否相等
let更像是c语言里面的声明
- 不能重复声明一个变量,而var可以。
- 拥有块级作用域。
- 不存在变量提升
- 有一个常见的var的bug,就是for(var i = 0; i< 3;i++){s[i].click} 这个时候只会执行s[3],因为i变成了全局的,i就是3。这就是块级作用域的问题
const PS = “15”
- 必须初始化
- 常量无法修改
- 一般要大写
- 块级作用域
- 数组和对象可以修改,比如SS[5] = "541" obj.name = "44";
这个有点像c语言里的#define
解构赋值 数组const score = [90, 100, 95]; let [math, English, Chinese] = score;
这个不是很常用
对象const student{
name: "",
score: 100;
gotoschool: function(){}
}
let {gotoschool} = student;
//或者let {name, score, gotoschool} = student;
gotoschool();
let arr = ["s", "a", "b"];let {x1, x2, x3} = arr;x123分别为s、a、b可以进行这样的赋值操作,包括对象(相当于结构体)
对象的简化写法能够使用外部已经赋值的变量
能够简化对象里的函数定义,不需要再写function
let name = "xiaoming";
let score = 100;
let gotochool = function(){};
const student{
name,
score,
gotoschool,
eat(){}
}
``反单引号模板字符串
和双引号一样是一种定义字符串的方式
- 直接可以换行
- 可以直接字符串拼接 例如:${X}是我喜欢的东西就是将x与汉字连接
- this是静态的,始终指向声明时的作用域,无法改变。
- 不能用argument变量。
- 形参只有一个的时候可以省略括号
- 只有一条语句时可以省略花括号
- 这条语句是return时,可以省略return;如let a = n => n*n;
let getname = () => {}
当我们在使用setTimeout这种直接调用的函数的时候,函数没有和其他的东西绑定,所以里面的this就是默认的windows,这就是箭头函数的好处setTimeout(() => {}, 2000);
形参赋初始值function ss(df,dfd = 5){}
ss(5);
//55
赋初始值的要靠后,假如没有传参就会使用初始值
…X rest参数可以用来替代argument,不同的是需要在函数声明的时候形参写成…X的形式,如
function fn(a, b, ...args){} fn(1,2,3,4,5);
//args[0] = 3,args就是一个数组
rest参数要放在最后
…扩展运算符 描述需要将一个数组的所有元素单独作为参数传进去的时候使用
例如
const tfboys = ['yyqx', 'wy', 'wjk'];
function chunwan(){
console.log(argument);//获取实参信息
}
chunwan(...tfboys)//这里是三个实参传进去了,而不只是一个数组
一些应用
数组的合并
const arr1 = ["A", "B", "C"]; const arr2 = ["D", "E"]; const zuhe = [...arr1, ...arr2];数组的克隆
const arr3 = [...arr1];
可以直接将数组克隆而不用使用函数,相对来说更为简洁
将伪数组转为真正的数组const divs = document.querrySelectorAll("div");
const divarr = [...divs];
//这里就是将divs这个对象转为数组,可以使用数组的方法
Symbol()数据类型
Symbol 特点
- symbol本质是一个唯一随机的字符串,而且我们是无法打印出来的
- 括号里是相当于注释的描述性文字,如Symbol(“注释”);
- 无法运算和比较
- Symbol.for(“key”),这种方法的symbol可以相等
这一部分暂时不学了,有点难理解,又感觉用到的场景不是很多
对象调用属性有两种方法,而symbol内置属性定义的函数只能用[]的方式来调用这个属性,用点.不行
symbol的内置属性是Symbol的一些方法,然后用在一些对象或者构造函数或者类里面,充当一些函数名,在特定的场景下面这个自己定义的,函数名为symbol内置属性的函数会被调用
自带iterator接口的数据
Array StringSset Map Argument TypedArray Nodelist
iterator就是一个array自带的Symbol内置属性,当使用for in或者for of的时候就会调用。
const xiyou = ["孙悟空", "唐僧", "猪八戒", "沙和尚"];
for(let i of xiyou){//键值
console.log(i);//孙悟空 唐僧 猪八戒 沙和尚
}
for(let i in xiyou){//键名
console.log(i);//1234
}
自定义迭代器接口
const banji = {
name:"终极一班",
stus:[
"xiaoming",
"xiaotian"
]
}
for(let i of banji){
console.log(i);//报错,会显示banji不是一个能够迭代的对象
}
for(let i in banji){
console.log(i);//输出的时name stus
}
for(let i of banji.stus){
console.log(i);//xiaoming xiaotian
}
此时需要的是实现第三个的功能,但是不采用这种方式,而是使用自定义迭代器的方式
name:"终极一班",
stus:[
"xiaoming",
"xiaotian"
],
[Symbol.iterator](){//返回的是一个next函数,
let index = 0;
let _this = this;
return{
next: ()=>{
if(index < _this.stus.length){
const result = {
value: _this.stus[index],
done: false
}
index++;
return result;
}
else{
return {
value: undefined,
done: true
}
}
}
}
}
}
for(let i of banji ){
console.log(i);
}
上面代码最主要的部分就是那个Symbol.iterator{}这就是当使用for in和for of的时候会触发的函数,我们需要返回一个对象,这个对象需要包含next函数,next函数需要返回一个对象,这个对象需要包含value,done。
next一开始会指向第一个元素,返回value的值在i里面,当done变成true的时候会停止,这个的value值不会被返回,所以就是这样实现了一个自定义的迭代器。
生成器函数就是用来解决回调地狱问题,就比如用户数据到订单数据到商品数据,这时候就需要等上一个函数执行成功,才能执行下一个,而多了就会不断嵌套,形成回调地狱。
例子
function fun1(){}
function fun2(){}
function * getdata(){//声明方式不同
console.log("start");
yield fun1;//多了一个关键字yield
yield fun2;
}
let iterator = getdata();//也可以直接调用getdata();
itetator.next();//这个next就是调用第一个yield和fun1, 再使用iterator.next()就会调用第二个
传参问题:
使用next()传参,第二个参数会变成第一个yield的返回结果,而第三个会变成第二个yield的返回结果,以此类推
function getUsers(){
setTimeout(() =>{
let data = "用户数据";
iterator.next(data);
}, 1000)
}
function getOrders(){
setTimeout(() =>{
let data = "订单数据";
iterator.next(data);
}, 1000)
}
function getGoods(){
setTimeout(() =>{
let data = "商品数据";
iterator.next(data);
}, 1000)
}
function * gen(){
let users = yield getUsers();
console.log(users);
let orders = yield getOrders();
console.log(orders);
let goods = yield getGoods();
console.log(goods);
}
let iterator = gen();//这里将gen实例化,好像是必须实例化,才能在第一个函数中使用next
iterator.next();
Set集合
这是一个新的数据结构,内有iterator接口,所以能够使用for in和for of,当然for in是不会和数组一样有123的,声明都没有,而for of能够输出集合里的所有的元素。
会自动将重复的元素去除,就算是在声明的时候添加了多个相同的元素,它就只会保存一个
let set1 = new Set();//与数组不同,必须使用new let set2 = new Set(["1", "2"]);部分集合的方法
- set.size();//返回集合大小
- set.add(“fsf”);//增加一个集合元素,返回集合
- set.delete(“sffs”);//返回boolean值,是否删除成功,有的时候可能都没有这个元素
- set.has(“sf”);//判断是否有这个元素,返回boolean值
这个暂时不学
Map地图对象 介绍map其实就是一个升级了的对象, 能够通过键名访问键值,与对象的区别就在于这个键名可以是对象,不只是局限于字符串
部分函数声明
就是普通的对象声明方式
let m = new Map();
添加元素
m.set("name", "iceylia");
m.set("change", function(){});
得到大小
console.log(m.size);
清空地图
m.clear();
访问元素
m.get("name");
遍历
for(let v of m){
console.log(v);//iceylia function
}
class类
介绍
类的定义在很多的语言里面都有,其实类的许多功能也能够用之前的语法实现,只是为了让js更加像是面向对象的编程。
class phone{
constructor(brand, price){//这个函数就是在类被声明的时候会自动执行这个函数。
this.brand = brand;
this.price = price;
}
call(){
console.log("我可以打电话");
}
}
let oneplus = new phone("1+", 3000);
oneplus.call();//我可以打电话
console.log(oneplus.brand);//1+
静态成员
在原本的构造函数里面也有静态对象
function phone(){
this.brand = brand;
this.price = price;
}
phone.call = function(){
console.log("wfw");
}//这个时候这个call是构造函数的对象
phone.prototype.call2 = funciton(){}//这个函数实例化对象就能使用,prototype就是原型的意思,可以理解成构造对象。
let oneplus = new phone("1+", 3000);
oneplus.call();//undefined;
而我们在类里面也可以定义静态成员,就是在成员名前面加上static
class phone{
constructor(brand, price){
this.brand = brand;
this.price = price;
}
static call(){
console.log("我可以打电话");
}
}
构造函数的继承
function phone(brand, price){
this.brand = brand;
this.price = price;
}
function smartphone(brand, price, color, size){
phone.call(this, brand, price);//这个是不能更改名字的
//大概意思就是将这个构造函数的对象和与父类相同的属性传过去
this.color = color;
this.size = size;
}
smartphone.prototype = new phone;//这里也就是将smartphone的父类原型指定为phone
const chuizi = new smartphone("锤子", 2999, "黑色", "5inch");
console.log(chuizi.brand);//锤子
console.log(chuizi.call);//undefined;
类的继承
class phone{
constructot(brand, price){
this.brand = brand;
this.price = price;
}
call(){
console.log("我可以打电话");
}
}
class smartphone extends phone{
constructor(brand, price, color, size){
super(brand, price);//将父类需要的参数传过去
this.color = color;
this.size = size;//定义子类的成员属性
}
}
const xiaomi = new smartphone("小米", 2999, "black", "5.5inch");
xiaomi.call();//我可以打电话;
如上例子,我们可以调用父类的方法,但是当我们子类也有一个同名的方法的时候,就无法通过子类调用这个父类的同名方法,只能使用子类里面的方法.
get set getget其实就是一个特殊的class的函数的修饰词,看起来是函数,实际上是一个class里的变量或者说是属性
class phone{
get call(){
console.log("call1");
return 5;
}
}
const oneplus = new phone();
console.log(oneplus.call);//call1 5;
作用就是能够动态地改变这个变量的值,每使用一次set参数,就会调用一次set函数,将函数返回值编程set参数的值
setset形式上与get相似,一般就是利用里面的函数判断是否能够实现这个赋值,如果你给变量赋值不合法,或者不符合规则,那么就可通过函数直接赋值失败
class phone{
set call(newvalue){//必须有一个参数
console.log("call1");
}
}
const oneplus = new phone();
oneplus.call = "454";
数值扩展
Number.EPSILON 最小精度
epsilon英文中是希腊中第五个字母,小的正数的意思,再js里面就是js的最小精度。
用途,在我们进行浮点数的运算的时候,我们都知道,浮点数其实是有许多没有显示出来的位数的,一直到最小的精度,所以会出现下面的问题
console.log(2.1 - 1.1 === 1.0);//false;
//用EPLISON解决
if(Math.abs(2.1-1.1) < Number.EPLISON){
console.log(1);
}
else{
console.log(0);
}
变量的进制表达方式
形式都是0+字母加 数字
//二进制 let b = 0d101;//5; //八进制 let o = 0o777; //十六进制 let x = 0xfff;Number.isNaN()判断是否为一个数字
在es6之前这个isNaN()就是一个单独的方法,所以我们现在也可以直接使用之前的那种形式
console.log(isNaN(13));Number.parseInt()将字符转为整形的数字
同上,之前就是一个单独的函数
console.log(Number.parseInt("123"));//ture;
let a = Number.parseInt("123");//true;
Number.isInteger() 是否为整形
略
对象方法扩展 Object.is() 判断两个值是否相等与===相似
有一点不同,就是全等的时候NaN ==NaN是false,而is是true



