js方法文档
mdn
1.类和对象
类中属性和方法
// 1.创建类class 创建一个明星类习惯定义首字母大写class Star {// 类的共有属性放到constructor里面constructor(uname, age) {this.uname = uname;this.age = age;}sing(song) {console.log(this.uname + '唱' + song);}}// 2.利用类创建对象newvar ldh = new Star('刘德华', 21);ldh.sing('冰雨');console.log(ldh);// 类里面有个constructor函数,可以结束参数,同时返回实例对象// constructor函数只要new生成实例时,就会自动调用这个函数,如果我们不写,类也会自动生成这个函数// 类名后面不加小括号</script>
类的继承
可以继承类里面的属性和方法,就近原则
类里面的共有的属性和方法一定要加this使用
- super继承属性
class Father {constructor(x, y) {this.x = x;this.y = y;}sum() {console.log(this.x + this.y);}}// 属性和方法都可以继承class Son extends Father {constructor(x, y) {//调用了父类中的构造函数,否则就传给子类会报错,因为用的是父类的thissuper(x, y);}}var son = new Son(2, 5);var son1 = new Son(11, 23);son.sum()son1.sum()</script>
-
super继承方法
1.继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,有就执行子类
2.如果子类没有,就去找父类,如果父类有,就执行父类的这个方法
class Father {say() {return '天龙'}}class Son extends Father {say() {// console.log('八部');console.log(super.say() + '八部');//天龙八部}}var son = new Son();
-
子类继承同时扩展自己
class Father {constructor(x, y) {this.x = x;this.y = y;}sum() {console.log(this.x + this.y);}}// 属性和方法都可以继承class Son extends Father {constructor(x, y) {// 子类在构造函数中使用super必须放到this前面super(x, y);this.x = x;this.y = y;}subtract() {console.log(this.x - this.y);}}var son = new Son(9, 5);son.subtract();son.sum();
类的注意事项
<button>点击</button><script>var that;class Star {constructor(uname, age) {// constructor里面的this指向的是创建的实例对象// 类里面的共有属性和方法一定要加this使用that = this;this.uname = uname;this.age = age;// this.sing()this.btn = document.querySelector('button');// 不要加(),否则就直接调用了,this.btn.onclick = this.sing;}sing() {// 这里是btn调用,所以函数this是btn// console.log(this.uname);//undefinedconsole.log(that.uname);}}var ldh = new Star('刘德华');// es6中类没有变量提升,所以必须先定义类,才能通过类实例化对象</script></body>
2.构造函数和原型
原型对象prototype
//每个构造函数都有一个prototype属性对象,这个对象的所有属性和方法都会被构造函数所有function Star(uname, age) {this.uname = uname;this.age = age;// this.sing=function(){// console.log('我会唱歌');// }/* 原型是对象,prototype为原型对象方法为复杂数据类型会开辟新的内存空间原型的作用是共享方法,减少资源消耗*/Star.prototype.sing = function () {console.log('我会唱歌');}}var ldh = new Star('刘德华', 15);var zxy = new Star('张学友', 19);// 一般情况下,我们公共属性定义到构造函数里面,公共方法则定义到原型对象上console.log(ldh.sing === zxy.sing);//true
对象原型__proto__
<script>function Star(uname, age) {this.uname = uname;this.age = age;}Star.prototype.sing = function () {console.log('我会唱歌');}var ldh = new Star('刘德华', 18);var zxy = new Star('张学友', 19);ldh.sing();console.log(ldh);//对象身上系统自己添加一个__proto__指向我们构造函数的原型对象prototypeconsole.log(ldh.__proto__ === Star.prototype);//true// 方法的查找规则:首先看ldh 对象身上是否有sing方法,如果有就执行这个对象上的sing//如果没有sing这个方法,因为有__proto__的存在,就去构造函数原型对象prototype身上去查找sing这个方法</script>
原型constructor
原型对象和对象原型都带ru有一个指向原来构造函数的constructor
function Star(uname, age) {this.uname = uname;this.age = age;// Star.prototype.sing = function () {// console.log('我会唱歌');// },// Star.prototype.movie = function () {// console.log('我会演电影');// }};// 很多情况下,我们需要手动的利用constructor这个属性指回原来的构造函数Star.prototype = {// 如果不加就指向一个对象了constructor: Star,sing: function () {console.log('我会唱歌');},movie: function () {console.log('我会演电影');}}var ldh = new Star('刘德华', 18);var zxy = new Star('张学友', 19);console.log(Star.prototype);console.log(ldh.__proto__);// 原型对象和对象原型都带有一个指向原来构造函数的constructor// console.log(Star.prototype.constructor);// console.log(ldh.__proto__.constructor);
原型链(就近原则)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D6YXW5LC-1668090175085)(C:\Users\林威\Desktop\原型链简易版.jpg)]
原型链对象查找机制及this指向
function Star(uname, age) {this.uname = uname;this.age = age;// 在构造函数中,里面this指向的是对象实例ldhconsole.log(this);}Star.prototype.sing = function () {console.log('我会唱歌');// 原型对象函数里面的this指向的也是实例对象ldhconsole.log(this);}var ldh = new Star('刘德华', 18);// 按原型链就近原则查找ldh.sex = '女';// Star.prototype.sex = '男';Object.prototype.sex = '男'console.log(ldh.sex);//女
call方法
call(),也可以调用函数,调用这个函数,并且修改函数运行时的this指向
-
fun.call(thisArg,a1,a2)
-
thisArg:当前调用函数this的指向对象
-
a1,a2:传递的其他参数
-
借用父构造函数继承属性
// 借用父构造函数继承属性function Father(uname, age) {this.uname = uname;this.age = age;}function Son(uname, age, score) {// this 指向子构造函数的对象实例Father.call(this, uname, age);this.score = score}var son = new Son('刘德华', 13, 99);console.log(son);
3.原型对象继承方法
<script>function Father(uname, age) {this.uname = uname;this.age = age;};Father.prototype.money = function () {console.log('我要赚钱');}function Son(uname, age) {Father.call(this, uname, age)}// Son.prototype=Father.prototype这样有问题,如果修改了子原型对象,父原型对象会跟着要求变化Son.prototype = new Father();Son.prototype.constructor = Son;Son.prototype.exam = function () {console.log('孩子要考试');}var son = new Son('dad', 45);console.log(son);console.log(Father.prototype);</script>
4.ES5新增数组方法
文档
3个参数(当前项的值,当前的索引,数组对象本身)
forEach遍历
<script>var arr = [1, 2, 3];var sum = 0;arr.forEach(function (a, b, c) {console.log('数组元素' + a);console.log('数组索引号' + b);console.log('数组本身' + c);sum += a;})console.log(sum);//6
filter筛选
// ilter筛选数组,返回一个新的数组1var arr = [12, 33, 44, 66, 3, 7]var newArr = arr.filter(function (value, index, total) {// return value % 2 === 0;return value >= 20})console.log(newArr);</script>
some✴️
检测数组中的元素是否满足指定条件,返回的是布尔值,如果查到就返回true,否则false
如果找到第一个满足条件的元素,则终止循环,不在继续查找;
要终止循环return后面一定要加turn
var arr = [10, 24, 4];var flag = arr.some(function (value) {return value > 20})console.log(flag);//truevar arr1 = ['red', 'pink', 'green'];var flag1 = arr1.some(function (value) {return value === 'pink';})console.log(flag1);//true
find
方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
var ary = [{id: 1,name: '张三'}, {id: 2,name: '李四'}];// 如果查找不到就返回undefindlet target = ary.find(item => item.id===2);console.log(target)
findIndex
let ary = [10, 20, 50];// 用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1let index = ary.findIndex(item => item > 15);console.log(index);//1
includes
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回
true
,否则返回false
。
const array1 = [1, 2, 3];console.log(array1.includes(2));
// expected output: trueconst pets = ['cat', 'dog', 'bat'];console.log(pets.includes('cat'));
// expected output: trueconsole.log(pets.includes('at'));
// expected output: false
flat
看上面文档
flatmap
reduce
计算数组所有元素的总和
// 注意:如果设置初始值,那么在第一次调用回调函数时,prev的值为这个初始值,如果不设置初始值,那么默认情况下,prev的值为数组的第一个元素var a = [1, 2, 3]var b = a.reduce(function (h, f) {return h + f}, 5)//5+1+2+3console.log(b);//11
------------------------------------------------
//返回未被选中的 undoneLength() {return state.list.reduce((pre, item) => {return pre + (item.done === true ? 0 : 1)}, 0)},
join
数组转为字符串
5.字符串方法
trim
trim(),去除字符串两侧空格,返回一个新的字符串
var str = ' an dy ';console.log(str);var str1 = str.trim();console.log(str1);
startsWith()和endsWith()
-
startsWith():表示参数字符串是否在字符串的头部,返回布尔值
-
endsWith():表示参数字符串是否在字符串的尾部,返回布尔值
let str = 'Hellow word';str = str.startsWith('He');console.log(str);
repeat
// repeat方法表示将原字符串重复n次,返回一个新字符串console.log("y".repeat(5))
split
字符串转为数组
6.Object.defineProperty()
object.defineProperty(obj,prop,descriptor)
只有用这个方法加进去的才受控制
-
obj:必需。目标对象
-
prop:必需。需定义或修改的属性的名字
-
descriptor:必需。目标属性所拥有的特性
- value:设置属性的值
- writable:值是否可以重写修改。true/false,默认为false
- enumerable:目标属性是否可以被枚举。true/false,默认为false
- configurable:目标属性是否可以被删除或是否可以再次修改特性true/false,默认为false
- 这里id是本身有的,所以不受控制
var obj = {id: 1,pname: '小米',price: 1999};// 有则修改,无则添加Object.defineProperty(obj, 'num', {value: 1000,// 因为writable默认为false});obj.num = 3;obj.id = 3;console.log(obj);//id:3,num:1000
7.函数
函数定义方式
// 函数的定义方式// 1.自定义函数(命名函数)function fn() { }// 2.函数表达式(匿名函数)var fun = function () { };// 3.利用 new Function('参数1','参数2','函数3');// 了解就好,效率较低var f = new Function('a', 'b', 'console.log(a+b)');f(1, 2);// 4.所有函数都是 Function 的实例(对象)console.dir(f);// 5.函数也属于对象console.log(f instanceof Object);
this指向
调用方式 | this指向 |
---|---|
普通函数调用 | window |
构造函数调用 | 实例对象,原型对象里面的方法也指向实例对象 |
对象方法调用 | 该方法所属对象 |
事件绑定方法 | 绑定事件对象 |
定时器函数 | window |
立即执行函数 | window |
apply方法
// 改变函数内this指向 js 提供了3种方法 call() apply() bind()// 2.apply() 应用 运用的意思var o = {name: 'andy'};function fn(arr) {console.log(this);console.log(arr);//'red'};fn.apply(o, ['red']);// 1.也是调用函数 第2跟可以改变函数内部的this指向// 2.但是他的参数必须是数组,也可以是伪数组// 3.apply 的主要应用 比如说我们可以利用 apply 借助于数学内置对象求最大值// Math.max()var arr = [1, 66, 3, 99, 4];var max = Math.max.apply(Math, arr);var min = Math.min.apply(Math, arr);console.log(max,min);
bind方法⭐️
var o = {name: 'andy',}function fn(a, b) {console.log(a + b);console.log(this);}// 改变this的同时不会直接调用,而是返回一个新的函数var f = fn.bind(o, 2, 4);f();
应用场景函数内部的this指向
都可以改变
-
call经常做继承·
-
apply经常和数组有关系,比如借助数组对象实现最大值最小值
-
bind不调用函数,但是还想改变this指向,比如改变定时器内部的this指向
var btns = document.querySelectorAll('button');for (var i = 0; i < btns.length; i++) {btns[i].onclick = function () {this.disabled = true;setTimeout(function () {this.disabled = false;}.bind(this), 2000)//bind写在定时器函数的外面,this指向btn这个对象}}
高阶函数
是对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出
function fn(a, b, callback) {console.log(a + b);callback && callback();}fn(1, 2, function() {console.log('我是最后调用的');});
8.闭包
一个作用域可以访问另外一个函数内部的局部变量,是延申了变量的作用范围
// 闭包(closure) 指有权访问另一个函数作用域中变量的函数// 简单理解:一个作用域可以访问另外一个函数内部的局部变量// 闭包:我们fun 这个函数作用域 访问了另外一个函数 fn 里面的局部变量num/*function fn() {var num = 5;function fun() {console.log(num);}fun()}fn()*/// 利用闭包,我们外面的作用域可以访问fn内部的局部变量//就是延申了变量的作用范围function fn() {var num = 10;// function fun() {// console.log(num);// };// return fun;return function () {console.log(num);}}var f = fn();f();
9.递归
函数内部自己调用自己
/*var num = 1;function fn() {console.log('打印6句话');if (num == 6) {return;//}num++;fn();}fn();*/// 利用递归求1~n的阶乘function fn(n) {if (n == 1) {return 1}return n * fn(n - 1)}console.log(fn(3));</script>
利用递归遍历数据
// 输入id,就可以返回对应的数据对象var data = [{id: 1,name: '家电',goods: [{id: 11,gname: '冰箱',goods: [{id: 111,gname: '海尔'}, {id: 112,gname: '美的'},]}, {id: 12,gname: '洗衣机'}]}, {id: 2,name: '服饰'}];function select(json, id) {var o = {};json.forEach(function (value) {if (value.id == id) {o = value;} else if (value.goods && value.goods.length > 0) {o = select(value.goods, id)}})return o;}console.log(select(data, 111));
10.拷贝
浅拷贝
浅拷贝对于更深层次对象级别只拷贝引用,所以改值对两个对象都有影响
var obj = {id: 1,name: 'andy',msg: {age: 17,}};var o = {};for (var i in obj) {// k是属性名,obj[k]属性值o[i] = obj[i];}// o.msg.age = 12;// 浅拷贝对于更深层次对象级别只拷贝引用,所以改值对两个对象都有影响console.log(obj);console.log(o);
------------------------------------------ES6浅拷贝语法糖Object.assign()
Object.assign(o,obj);//把obj拷贝给oconsole.log(o);
深拷贝
修改源对象更深层次对象不会影响拷贝的对象的值,互不影响
var obj = {id: 1,name: 'andy',msg: {age: 18},color: ['pink', 'red']};var o = {};function deepCopy(newObj, oldObj) {for (var i in oldObj) {var item = oldObj[i];if (item instanceof Array) {newObj[i] = [];deepCopy(newObj[i], item)} else if (item instanceof Object) {newObj[i] = {};deepCopy(newObj[i], item)} else {newObj[i] = item;}}}deepCopy(o, obj);console.log(o);console.log(obj);obj.msg.age = 1;console.log(o);
11.正则表达式
菜鸟正则
正则在js中的创建使用
// 方法1.利用RegExp对象来创建正则表达式var regexp = new RegExp(/123/);console.log(typeof regexp);console.log(regexp);//2.利用字面量创建正则表达式var rg = /123/;// 3.test方法用来检测字符串是否符号正则表达式要求的规范console.log(rg.test(123));//trueconsole.log(rg.test('abc'));//falseconsole.log(regexp.test(1234));//true
边界符的使用
//正则表达式里面不需要加引号 不管是数字还是字符型
// 边界符^ $var rg = /abc/;//正则表达式里面不需要加引号 不管是数字还是字符型// /abc/ 只要包含有abc这个字符串返回的都是trueconsole.log(rg.test('abc'));console.log(rg.test('abcd'));console.log(rg.test('aabcd'));console.log('--------------');var reg = /^abc/; //必须以abc开头console.log(reg.test('abc'));console.log(reg.test('abcd'));console.log(reg.test('aabcd'));//falseconsole.log('--------------');var reg = /abc$/; //必须以abc结尾console.log(reg.test('abc'));console.log(reg.test('abcd'));//falseconsole.log(reg.test('dabc'));console.log('--------------');var reg = /^abc$/; //精确匹配,要求必须是abc 字符串才符合规范console.log(reg.test('abc'));console.log(reg.test('abcd'));//falseconsole.log(reg.test('aabcd'));//falseconsole.log(reg.test('abcabc'));//false
字符类
// 字符类: [] 表示有一系列字符可供选择,只要1匹配其中一个就可以了
// var rg=/abc/; 只要包含abc就可以// 字符类: [] 表示有一系列字符可供选择,只要1匹配其中一个就可以了var rg = /[abc]/; //只要包含有a 或者包含有b 或者包含有C 都返回为trueconsole.log(rg.test('andy'));console.log(rg.test('baby'));console.log(rg.test('color'));console.log(rg.test('red'));//falseconsole.log('------------------');var rg1 = /^[abc]/; //只要其中任何一个开头都可以console.log(rg1.test('aa'));console.log(rg1.test('a'));console.log(rg1.test('b'));console.log(rg1.test('c'));console.log(rg1.test('dabc'));//falseconsole.log('------------------');var rg1 = /^[abc]$/; //3选1 只有是a 或者是b 或者是c 这3个字母才返回trueconsole.log(rg1.test('aa'));//falseconsole.log(rg1.test('a'));console.log(rg1.test('b'));console.log(rg1.test('c'));console.log(rg1.test('abc'));//falseconsole.log('------------------');var rg1 = /^[a-z]$/; //26个英文字母任何一个字母返回的都是true -表示a到z的范围console.log(rg1.test('g'));console.log(rg1.test('A'));//falseconsole.log(rg1.test('z'));console.log(rg1.test(1));//falseconsole.log('------------------');// 字符组合var rg1 = /^[a-zA-Z0-9_-]$/; //26个英文字母(大小写)任何一个字母返回的都是true -表示范围console.log(rg1.test('a'));console.log(rg1.test('B'));console.log(rg1.test('8'));console.log(rg1.test('_'));console.log(rg1.test('-'));console.log(rg1.test('!'));//falseconsole.log('------------------');// 如果中括号里面有^ 表示取反的意思 千万和我们边界符^ 别混淆var rg1 = /^[^a-zA-Z0-9_-]$/; //26个英文字母(大小写)任何一个字母返回的都是true -表示范围console.log(rg1.test('a'));console.log(rg1.test('B'));console.log(rg1.test('8'));console.log(rg1.test('_'));console.log(rg1.test('-'));console.log(rg1.test('!'));//true
量词
// 量词符: 用来设定某个模式出现的次数// 简单理解: 就是让下面的a这个字符重复多少次// var reg = /^a$/;// * 相当于 >= 0 可以出现0次或者很多次 var reg = /^a*$/;console.log(reg.test(''));console.log(reg.test('a'));console.log(reg.test('aaa'));// + 相当于 >= 1 可以出现1次或者很多次// var reg = /^a+$/;// console.log(reg.test('')); // false// console.log(reg.test('a')); // true// console.log(reg.test('aaaa')); // true// ? 相当于 1 || 0// var reg = /^a?$/;// console.log(reg.test('')); // true// console.log(reg.test('a')); // true// console.log(reg.test('aaaa')); // false// {3 } 就是重复3次// var reg = /^a{3}$/;// console.log(reg.test('')); // false// console.log(reg.test('a')); // false// console.log(reg.test('aaaa')); // false// console.log(reg.test('aaa')); // true// {3, } 大于等于3var reg = /^a{3,}$/;console.log(reg.test('')); // falseconsole.log(reg.test('a')); // falseconsole.log(reg.test('aaaa')); // trueconsole.log(reg.test('aaa')); // true// {3,16} 大于等于3 并且 小于等于16var reg = /^a{3,6}$/;console.log(reg.test('')); // falseconsole.log(reg.test('a')); // falseconsole.log(reg.test('aaaa')); // trueconsole.log(reg.test('aaa')); // trueconsole.log(reg.test('aaaaaaa')); // false</script>
括号
// 中括号 字符集合 匹配方括号中的任意字符var reg = /^[abc]$/;// a 也可以 b也可以 c 可以 a||b||c// 大括号 量词符 里面表示重复次数var reg=/^abc{3}$/; //它只是让c重复3次 abcccconsole.log(reg.test('abc'));console.log(reg.test('abcabcabc'));console.log(reg.test('abaccc'));console.log(reg.test('abccc'));//true// 小括号 表示优先级var reg=/^(abc){3}$/; //它只是让abc重复3次 abcabcabcconsole.log(reg.test('abc'));console.log(reg.test('abcabcabc'));//trueconsole.log(reg.test('abaccc'));console.log(reg.test('abccc'));
替换
// 替换 replace// var str = 'andy和red';// // var str1=str.replace('andy','baby');// var str1=str.replace(/andy/,'baby');// console.log(str1);var text=document.querySelector('textarea');var btn=document.querySelector('button');var div=document.querySelector('div');btn.onclick=function(){// g:全局匹配 i:忽略大小写 gi:全局匹配+忽略大小写div.innerHTML=text.value.replace(/激情|gay/g,'**');}
12.阮一峰ES6
Es6文档
12.let和const关键字
let关键字声明变量
-
let声明的变量只在所处于的块级作用域有效
-
块级作用域: 全局,函数
if(true){let a=10 } console.log(a);// a is not defined
-
不存在变量提升
console.log(a);let a = 100;
-
存在暂时性死区
var tmp = 123; if (true) {tmp = 'abc'; // ReferenceErrorlet tmp; }
let经典面试题
var arr = [];for (var i = 0; i < 2; i++) {arr[i] = function () {// 函数内部没有定义i的代码,所以会按原型链往上查找console.log(i);}}arr[0]();//2arr[1]();//2// 因为i是全局变量,函数调用的时候for早就执行完了var arr1 = [];//let有块级作用域for (let i = 0; i < 2; i++) {arr1[i] = function () {console.log(i);}}arr1[0]();//0arr1[1]();//1
const声明常量⭐️
-
const声明的常量只在所处于的块级作用域有效
-
使用const关键字声明的常量必须赋初始值
-
常量赋值后不能更改两种情况
// 常量赋值后,值不能修改// const a = 3;// a = 4;// 但是复杂数据类型可以这样const arr = [1, 2];arr[0] = '上';arr[1] = '下';console.log(arr);//['上','下']arr = ['a', 'n']//报错,不能这样改值,这样更改了内存地址
-
var let const 函数级作用域 块级作用域 块级作用域 变量提升 不存在变量提升 不存在变量提升 值可更改 值可更改 值不可更改
作用域
<button>1</button><button>2</button><button>3</button><script>var btns = document.querySelectorAll('button');// for (var i = 0; i < btns.length; i++) {// btns[i].addEventListener('click', function () {// console.log(i);//3// })// }// 解决方法1// for (let i = 0; i < btns.length; i++) {// btns[i].addEventListener('click', function () {// console.log(i);//3// })// }// 解决方法2for (let i = 0; i < btns.length; i++) {(function (i) {btns[i].addEventListener('click', function () {console.log(i);})})(i)}</script>
对象字面量增强写法
<script>// 属性的增强写法const name = 'why';const age = 16;const height = 188;/*Es5写法const obj = {name: name,age: age,height: height}*/const obj = {name,age,height}console.log(obj);// 函数方法的简写//Es5的写法let obj1 = {test: function () {console.log(777);},test() {console.log('我是简写');}}</script>
13.解构赋值
从数组和对象中提取值,对变量进行赋值,这被称为解构,j建议直接看文档
数组解构
let ary = [1, 2, 3];// 多出来的解构失败,显示undefinedlet [a, b, c, d] = ary;console.log(a);console.log(b);console.log(c);console.log(d);//undefined
对象解构
使用变量的名字匹配对象的属性,匹配成功将对象属性的值赋值给变量
-
正常情况下,对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { bar, foo } = { foo: 'c', bar: 'a' }console.log(bar);//aconsole.log(foo);//c
//对象的属性没有次序,变量必须与属性同名,才能取到正确的值。let { bar, foo } = { foo: 'c', bar: 'a' }console.log(bar);//aconsole.log(foo);//clet { baz } = { hd: 'aaa', gr: 'bbb' };console.log(baz);//undefineds
-
如果变量与属性名不一样,还想要匹配成功则需要设置别名,利用别名解构
let { n: bm } = { a: 'c', g: 'k', n: 5 };console.log(bm);//5
14.箭头函数
菜鸟箭头文档
箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法
-
语法表达
const fn = () => {console.log(123);}fn();//123
-
// 如果函数体只有一句代码,且代码的执行结果就是返回值,可以省略大括号
const sum = (n1, n2) => n1 + n2;var result = sum(3, 5);console.log(result);//8
-
如果形参只有一个,可以省略小括号
const single = v => {alert(v);}single(20)
// 箭头函数不绑定this 箭头函数没有自己的this关键字 如果在箭头函数中使用this关键字将指向箭头函数定义位置中的this
// 局部作用域(函数作用域)
function fn() {console.log(this);return () => {console.log(this)}}const obj = { name: 'zhangsan' };const resFn = fn.call(obj);resFn();
-
对象是不能产生作用域的
var age = 100;var obj = {age: 20,say: () => {console.log(this.age);//100},s: function () {console.log(this.age);//20}}// 对象是不能产生作用域的obj.say();obj.s()
15.剩余参数
剩余参数是将剩余的元素放在一个数组中
// 剩余参数是将剩余的元素放在一个数组中const sum = (...args) => {var total = 0;args.forEach(item => {total += item;})return total;}console.log(sum(12, 34));// 剩余参数+数组解构let ary1 = ['张三', '李四', '王五'];let [s1, ...s2] = ary1;//s2变成了一个数组console.log(s1)console.log(s2)
16.扩展运算符
扩展运算符可以将数组或者对象转为用逗号分隔的参数序列
// 扩展运算符可以将数组或者对象转为用逗号分隔的参数序列let arr = ['a', 'b', 'c'];// 这里没逗号是因为被当成了log方法的分隔符console.log(...arr);//1 2 3// 扩展运算符应用于数组合并let arr1 = [1, 2, 3];let arr2 = [4, 5, 6];let arr3 = [...arr1, ...arr2];console.log(arr3);//方法2arr3.push(...arr1);console.log(arr3);
利用扩展运算符将伪数组转换为真正的数组
var oDivs = document.getElementsByTagName('div');console.log(oDivs);//实际上就是伪数组var ary = [...oDivs];//数组// 变成数组后就可以运用数组方法了ary.push('a');console.log(ary);
17.Array.form
1.将伪数组或可遍历对象转换为真正的数组
2.第2个参数为回调函数,
var arrayLike = {'0': 1,'1': 2,'2': 3,length: '3'}console.log(arrayLike);// var newArr = Array.from(arrayLike);//console.log(newArr);//[1,2,3];// 第2个参数为回调函数var newArr = Array.from(arrayLike, item => item * 2);console.log(newArr);//[2,4,6]
18.模板字符串
// es6新增的创建字符串的方式,使用反引号定义// let name=`这是一个模板字符串`;// let a=`张飞`;// console.log(`我的兄弟是${a}`);// console.log(name);// let result={// name:'张三',// age:20// };// let html=`// <div>// <span>${result.name}</span>// <span>${result.age}</span>// </div>// `;// console.log(html);const fn = function () {return '关羽';}let b = `你是${fn()}`;console.log(b);console.log(`付电费,放到`);
19.Set,Map方法⭐️
类似于数组,但成员的值都是唯一的,没有重复的值
// es6提供了新的数据结构Set,它类似于数组,但是成员的值都是唯一的,没有重复的值// Set本身是一个构造函数,用来生成Set数据结构// const s1 = new Set();// // size 表示此数据结构中包含多少值// console.log(s1.size)// // Set函数可以接收一个数组作为参数,用来初始化// const s2 = new Set(["a", "b"]);// console.log(s2.size)// // 可以做到数组去重// const s3 = new Set(["a", "a", "b", "b"]);// console.log(s3.size);//2 具有去重功能// console.log(s3)// const ary = [...s3];// console.log(ary)const s4 = new Set();// 向set结构中添加值 使用add方法 返回结构本身s4.add('a').add('b');console.log(s4.size);//2// 从set结构中删除值 用到的方法是delete 返回布尔值const r1 = s4.delete('c');console.log(s4.size)console.log(r1);// 判断某一个值是否是set数据结构中的成员 使用has 返回布尔值const r2 = s4.has('d');console.log(r2)// // 清空set数据结构中的值 使用clear方法// s4.clear();// console.log(s4.size);// 遍历set数据结构 从中取值const s5 = new Set(['a', 'b', 'c']);s5.forEach(value => {console.log(value)})
20.Es6模块化
Es6文档
1.想要在nodejs中体验es6模块化
在package.json里面加入“type":‘module’
{"type": "module","name": "code","version": "1.0.0","description": "","main": "index.js","scripts": {"test": "echo \"Error: no test specified\" && exit 1"},"keywords": [],"author": "","license": "ISC","dependencies": {"then-fs": "^2.0.0"}
}
2.默认导入和导出
默认导出
let n1 = 10
let n2 = 20
function show() {}export default {n1,show
}
默认导入不要加{}
import m1 from './01.默认导出.js'console.log(m1)
每个模块中,只允许使用唯一的一次export default
3.按需导入和导出
按需导出
export let s1 = 'aaa'
export let s2 = 'ccc'
export function say() {}
按需导入要加{}
取别名,这里给s2取了别名
import { s1, s2 as str2, say } from './03.按需导出.js'console.log(s1)
console.log(str2)
console.log(say)
4.默认与按需导入导出写一块
export let s1 = 'aaa'
export let s2 = 'ccc'
export function say() {}export default {a: 20
}
导入
import info, { s1, s2 as str2, say } from './03.按需导出.js'console.log(s1)
console.log(str2)
console.log(say)console.log(info)运行结果
aaa
ccc
[Function: say]
{ a: 20 }
5.直接运行模块中的代码
导出
for (let i = 0; i < 3; i++) {console.log(i)
}导入
import './05.直接运行模块中的代码.js'运行结果
0
1
2
21.Promise
Es6文档
- 基本语法
const p = new Promise(function (resolve, reject) {let date = '你是奔达嘛';// resolve(date);reject(date);//对应第then的第2个状态}).then(function (value) {console.log(value);}, function (reason) {console.error(reason);})
-
catch
const p = new Promise((resolve, reject) => {setTimeout(() => {//设置 p 对象的状态为失败, 并设置失败的值reject("出错啦!");}, 1000)});// p.then(function(value){}, function(reason){// console.error(reason);// });p.catch(function (reason) {console.warn(reason);});
-
读取文件
// 1.引入fs模块 const fs = require('fs') // 2.调用方法读取文件 //3. 使用 Promise 封装 const p = new Promise(function (resolve, reject) {fs.readFile('./resources/为学.md', (err, data) => {if (err) reject(err);resolve(data)}); }).then(value => {return new Promise(function (resolve, reject) {fs.readFile('./resources/插秧诗.md', (err, data) => {if (err) reject(err);resolve([value, data])});}) }).then(value => {return new Promise(function (resolve, reject) {fs.readFile('./resources/观书有感.md', (err, data) => {if (err) {reject(err)} else {value.push(data);resolve(value)}})}) }).then(value => {console.log(value.toString()); }) // p.then(function (value) { // console.log(value.toString()); // }, function (item) { // console.log('读取失败'); // })
promise.all
Promise.all([// new Promise((resolve, reject) => {// $.ajax({// url: 'url1',// success: function (data) {// resolve(data)// }// })// }),// new Promise((resolve, reject) => {// $.ajax({// url: 'url2',// success: function (data) {// resolve(data)// }// })// })new Promise((resolve, reject) => {setTimeout(() => {resolve({name: 'why', age: 18})}, 2000)}),new Promise((resolve, reject) => {setTimeout(() => {resolve({name: 'kobe', age: 19})}, 1000)})]).then(results => {console.log(results);
22.async和await
async
// 只要返回的结果表示promise对象,返回的结果就是成功的Promise对象async function fn() {// async函数的返回值是 Promise 对象// return '绝世武神'//return; //undefined//返回的结果是一个失败的promise//throw new Error('出错啦!')//返回的结果是一个Promise对象return new Promise((resolve, reject) => {// resolve('成功的数据')对应then的第1个参数reject('失败的数据');//对应then的第2个参数})}const hs = fn();console.log(hs);hs.then(success => {console.log(success);}, error => {console.log(error);})
await
const p = new Promise(function (resolve, reject) {//resolve('成功的值');reject('失败的值')})// await要放在async函数中/* async function main() {// await返回的结果就是promise对象成功的那个值let result = await p;console.log(result);}*//*任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。我们希望即使前一个异步操作失败,也不要中断后面的异步操作。这时可以将第一个await放在try...catch结构里面,这样不管这个异步操作是否成功,第二个await都会执行。*/async function main() {try {let result = await p;console.log(result);} catch (e) {console.log(e);//失败的值}}main()
在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行
const fs = require('fs');
function readWx() {return new Promise(function (resolve, reject) {fs.readFile('./resources/为学.md', (err, data) => {if (err) reject(err);resolve(data)});})
};
function readCys() {return new Promise(function (resolve, reject) {fs.readFile('./resources/插秧诗.md', (err, data) => {if (err) reject(err);resolve(data)});})
};
function readGsyg() {return new Promise(function (resolve, reject) {fs.readFile('./resources/观书有感.md', (err, data) => {if (err) reject(err);resolve(data)});})
}
console.log('A');async function main() {console.log('B');let Wx = await readWx();let Cys = await readCys();let Gsyg = await readGsyg();console.log(Wx.toString());console.log(Cys.toString());console.log(Gsyg.toString());console.log('C');
}
main();
console.log('D');
// 在async方法中,第一个await之前的代码会同步执行,await之后的代码会异步执行
//ABD....C