赞
踩
// 1.创建类class 创建一个明星类习惯定义首字母大写 class Star { // 类的共有属性放到constructor里面 constructor(uname, age) { this.uname = uname; this.age = age; } sing(song) { console.log(this.uname + '唱' + song); } } // 2.利用类创建对象new var ldh = new Star('刘德华', 21); ldh.sing('冰雨'); console.log(ldh); // 类里面有个constructor函数,可以结束参数,同时返回实例对象 // constructor函数只要new生成实例时,就会自动调用这个函数,如果我们不写,类也会自动生成这个函数 // 类名后面不加小括号 </script>
可以继承类里面的属性和方法,就近原则
类里面的共有的属性和方法一定要加this使用
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) { //调用了父类中的构造函数,否则就传给子类会报错,因为用的是父类的this super(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);//undefined console.log(that.uname); } } var ldh = new Star('刘德华'); // es6中类没有变量提升,所以必须先定义类,才能通过类实例化对象 </script> </body>
//每个构造函数都有一个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
<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__指向我们构造函数的原型对象prototype console.log(ldh.__proto__ === Star.prototype);//true // 方法的查找规则:首先看ldh 对象身上是否有sing方法,如果有就执行这个对象上的sing //如果没有sing这个方法,因为有__proto__的存在,就去构造函数原型对象prototype身上去查找sing这个方法 </script>
原型对象和对象原型都带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指向的是对象实例ldh console.log(this); } Star.prototype.sing = function () { console.log('我会唱歌'); // 原型对象函数里面的this指向的也是实例对象ldh console.log(this); } var ldh = new Star('刘德华', 18); // 按原型链就近原则查找 ldh.sex = '女'; // Star.prototype.sex = '男'; Object.prototype.sex = '男' console.log(ldh.sex);//女
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);
<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>
3个参数(当前项的值,当前的索引,数组对象本身)
<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
// ilter筛选数组,返回一个新的数组1
var 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>
检测数组中的元素是否满足指定条件,返回的是布尔值,如果查到就返回true,否则false
如果找到第一个满足条件的元素,则终止循环,不在继续查找;
要终止循环return后面一定要加turn
var arr = [10, 24, 4];
var flag = arr.some(function (value) {
return value > 20
})
console.log(flag);//true
var arr1 = ['red', 'pink', 'green'];
var flag1 = arr1.some(function (value) {
return value === 'pink';
})
console.log(flag1);//true
方法返回数组中满足提供的测试函数的第一个元素的值。否则返回 undefined。
var ary = [{
id: 1,
name: '张三'
}, {
id: 2,
name: '李四'
}];
// 如果查找不到就返回undefind
let target = ary.find(item => item.id===2);
console.log(target)
let ary = [10, 20, 50];
// 用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1
let index = ary.findIndex(item => item > 15);
console.log(index);//1
includes() 方法用来判断一个数组是否包含一个指定的值,根据情况,如果包含则返回
true
,否则返回false
。
const array1 = [1, 2, 3];
console.log(array1.includes(2));
// expected output: true
const pets = ['cat', 'dog', 'bat'];
console.log(pets.includes('cat'));
// expected output: true
console.log(pets.includes('at'));
// expected output: false
看上面文档
计算数组所有元素的总和
// 注意:如果设置初始值,那么在第一次调用回调函数时,prev的值为这个初始值,如果不设置初始值,那么默认情况下,prev的值为数组的第一个元素
var a = [1, 2, 3]
var b = a.reduce(function (h, f) {
return h + f
}, 5)//5+1+2+3
console.log(b);//11
------------------------------------------------
//返回未被选中的
undoneLength() {
return state.list.reduce((pre, item) => {
return pre + (item.done === true ? 0 : 1)
}, 0)
},
数组转为字符串
trim(),去除字符串两侧空格,返回一个新的字符串
var str = ' an dy ';
console.log(str);
var str1 = str.trim();
console.log(str1);
startsWith():表示参数字符串是否在字符串的头部,返回布尔值
endsWith():表示参数字符串是否在字符串的尾部,返回布尔值
let str = 'Hellow word';
str = str.startsWith('He');
console.log(str);
// repeat方法表示将原字符串重复n次,返回一个新字符串
console.log("y".repeat(5))
字符串转为数组
object.defineProperty(obj,prop,descriptor)
只有用这个方法加进去的才受控制
obj:必需。目标对象
prop:必需。需定义或修改的属性的名字
descriptor:必需。目标属性所拥有的特性
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
// 函数的定义方式
// 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指向 |
---|---|
普通函数调用 | window |
构造函数调用 | 实例对象,原型对象里面的方法也指向实例对象 |
对象方法调用 | 该方法所属对象 |
事件绑定方法 | 绑定事件对象 |
定时器函数 | window |
立即执行函数 | window |
// 改变函数内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);
var o = {
name: 'andy',
}
function fn(a, b) {
console.log(a + b);
console.log(this);
}
// 改变this的同时不会直接调用,而是返回一个新的函数
var f = fn.bind(o, 2, 4);
f();
都可以改变
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('我是最后调用的');
});
一个作用域可以访问另外一个函数内部的局部变量,是延申了变量的作用范围
// 闭包(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();
函数内部自己调用自己
/* 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));
浅拷贝对于更深层次对象级别只拷贝引用,所以改值对两个对象都有影响
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拷贝给o console.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);
// 方法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));//true
console.log(rg.test('abc'));//false
console.log(regexp.test(1234));//true
//正则表达式里面不需要加引号 不管是数字还是字符型
// 边界符^ $ var rg = /abc/;//正则表达式里面不需要加引号 不管是数字还是字符型 // /abc/ 只要包含有abc这个字符串返回的都是true console.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'));//false console.log('--------------'); var reg = /abc$/; //必须以abc结尾 console.log(reg.test('abc')); console.log(reg.test('abcd'));//false console.log(reg.test('dabc')); console.log('--------------'); var reg = /^abc$/; //精确匹配,要求必须是abc 字符串才符合规范 console.log(reg.test('abc')); console.log(reg.test('abcd'));//false console.log(reg.test('aabcd'));//false console.log(reg.test('abcabc'));//false
// 字符类: [] 表示有一系列字符可供选择,只要1匹配其中一个就可以了
// var rg=/abc/; 只要包含abc就可以 // 字符类: [] 表示有一系列字符可供选择,只要1匹配其中一个就可以了 var rg = /[abc]/; //只要包含有a 或者包含有b 或者包含有C 都返回为true console.log(rg.test('andy')); console.log(rg.test('baby')); console.log(rg.test('color')); console.log(rg.test('red'));//false console.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'));//false console.log('------------------'); var rg1 = /^[abc]$/; //3选1 只有是a 或者是b 或者是c 这3个字母才返回true console.log(rg1.test('aa'));//false console.log(rg1.test('a')); console.log(rg1.test('b')); console.log(rg1.test('c')); console.log(rg1.test('abc'));//false console.log('------------------'); var rg1 = /^[a-z]$/; //26个英文字母任何一个字母返回的都是true -表示a到z的范围 console.log(rg1.test('g')); console.log(rg1.test('A'));//false console.log(rg1.test('z')); console.log(rg1.test(1));//false console.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('!'));//false console.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, } 大于等于3 var reg = /^a{3,}$/; console.log(reg.test('')); // false console.log(reg.test('a')); // false console.log(reg.test('aaaa')); // true console.log(reg.test('aaa')); // true // {3,16} 大于等于3 并且 小于等于16 var reg = /^a{3,6}$/; console.log(reg.test('')); // false console.log(reg.test('a')); // false console.log(reg.test('aaaa')); // true console.log(reg.test('aaa')); // true console.log(reg.test('aaaaaaa')); // false </script>
// 中括号 字符集合 匹配方括号中的任意字符
var reg = /^[abc]$/;
// a 也可以 b也可以 c 可以 a||b||c
// 大括号 量词符 里面表示重复次数
var reg=/^abc{3}$/; //它只是让c重复3次 abccc
console.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次 abcabcabc
console.log(reg.test('abc'));
console.log(reg.test('abcabcabc'));//true
console.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,'**');
}
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'; // ReferenceError
let tmp;
}
var arr = []; for (var i = 0; i < 2; i++) { arr[i] = function () { // 函数内部没有定义i的代码,所以会按原型链往上查找 console.log(i); } } arr[0]();//2 arr[1]();//2 // 因为i是全局变量,函数调用的时候for早就执行完了 var arr1 = []; //let有块级作用域 for (let i = 0; i < 2; i++) { arr1[i] = function () { console.log(i); } } arr1[0]();//0 arr1[1]();//1
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 // }) // } // 解决方法2 for (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>
从数组和对象中提取值,对变量进行赋值,这被称为解构,j建议直接看文档
let ary = [1, 2, 3];
// 多出来的解构失败,显示undefined
let [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);//a
console.log(foo);//c
//对象的属性没有次序,变量必须与属性同名,才能取到正确的值。
let { bar, foo } = { foo: 'c', bar: 'a' }
console.log(bar);//a
console.log(foo);//c
let { baz } = { hd: 'aaa', gr: 'bbb' };
console.log(baz);//undefineds
如果变量与属性名不一样,还想要匹配成功则需要设置别名,利用别名解构
let { n: bm } = { a: 'c', g: 'k', n: 5 };
console.log(bm);//5
箭头函数适合与 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()
剩余参数是将剩余的元素放在一个数组中
// 剩余参数是将剩余的元素放在一个数组中
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)
扩展运算符可以将数组或者对象转为用逗号分隔的参数序列
// 扩展运算符可以将数组或者对象转为用逗号分隔的参数序列
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);
//方法2
arr3.push(...arr1);
console.log(arr3);
利用扩展运算符将伪数组转换为真正的数组
var oDivs = document.getElementsByTagName('div');
console.log(oDivs);//实际上就是伪数组
var ary = [...oDivs];//数组
// 变成数组后就可以运用数组方法了
ary.push('a');
console.log(ary);
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]
// 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(`付电费, 放到`);
类似于数组,但成员的值都是唯一的,没有重复的值
// 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) })
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
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([ // 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);
// 只要返回的结果表示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); })
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
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。