函数自动执行
自动执行函数加括号
//js函数自动执行1:
(function aaa() {
console.log('aaa')
})()
//js函数自动执行2:
var Funb = function() {
console.log('bbb')
}();
//js函数自动执行3:
var Func = function() {
console.log('ccc')
};
window.onload = function() {
Func()
}
函数防抖和函数节流
函数防抖应用场景:1搜索框搜索输入。用户最后一次输入完,再发送请求 2手机号、邮箱验证输入检测
1简单防抖
var timer; // 维护同一个timer
function debounce(fn, delay) {
clearTimeout(timer);
timer = setTimeout(function(){
fn();
}, delay);
}
2在上面代码中,会出现一个问题,var timer只能在setTimeout的父级作用域中,这样才是同一个timer,为了方便防抖函数的调用和回调函数fn的传参问题,我们应该用闭包来解决这些问题。
//函数防抖
//应用场景:1搜索框搜索输入。用户最后一次输入完,再发送请求 2手机号、邮箱验证输入检测
var timer; // 维护一个 timer
function debounce(fn, delay) {
return function () {
var self = this; // 取debounce执行作用域的this
var args = arguments;
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(function () {
fn.apply(self, args); // 用apply指向调用debounce的对象,相当于self.fn(args);
timer = null;
}, delay);
};
}
测试:
debounce(()=>console.log('debounce'),1800)()
debounce(()=>console.log('debounce'),1800)() //debounce
var aaa=function(){console.log('aaa')}
debounce(aaa,800)()
debounce(aaa,800)() //aaa
函数节流应用场景:1滚动加载,加载更多或滚到底部监听.2高频点击提交,表单重复提交
节流1
var timer;
function throttle(fn, delay) {
return function () {
var self = this;
var args = arguments;
if (timer) {
return;
}
timer = setTimeout(function () {
fn.apply(self, args);
timer = null; // 在delay后执行完fn之后清空timer,此时timer为假,throttle触发可以进入计时器
}, delay)
}
}
函数节流-立刻执行版
var previous = 0;
function throttle(fn, delay) {
return function() {
var self = this;
var args = arguments;
var now = new Date();
if(now - previous > delay) {
fn.apply(self, args);
previous = now;
}
}
}
throttle(()=>console.log('debounce'),1800)(); //debounce
throttle(()=>console.log('debounce'),1800)();
for循环中let和var区别详解
for(var i=0;i<5;i++){
setTimeout(()=>{
console.log(i);//5个5
},100)
}
console.log(i);//5
console.log('=============')
for(let j=0;j<5;j++){
setTimeout(()=>{
console.log(j);//0,1,2,3,4
},100)
}
console.log(j);//报错 j is not defined
分析:
1 setTimeout()是以异步的方式执行的。在执行for循环的时候,并不是执行一次for循环就立刻执行一次setTimeout()
2 因为var是没有块级作用域的,所以在for循环中声明的i会存在于test()函数作用域中。每一次for循环就会声明一次i,但后面声明的变量会覆盖前面声明的变量。所以当for循环执行完后(此时setTimeout()还未被执行),函数作用域中的i的值就变成5了
{
let a=123;
}
{
let a=246;
}
console.log(a);//a is not defined;
{
var b=1;
}
{
var b=2;
}
console.log(b);// 2;
call和apply--改变函数中this的指向
apply() {
// call和apply--改变函数中this的指向
// 什么是道岔?
// 火车在行进途中遇到路口后,决定火车应该向那个方向执行的装置被称为【道岔】
// 我们可以将函数类比为火车,
// 而今天介绍的call和apply就好比为控制火车this行进方向的【道岔】
var agen = {
name: 'agen'
};
function show() {
console.log(this.name);
};
show.call(this); //undefined
//此时,调用者是agen对象,this指向agen对象,this.name='agen'.
show.call(agen); //agen
//应用求数组最大值
var arr = [1, 3, 5, 2, 8];
var max = Math.max.apply(null, arr);
console.warn(max);//8
},
for...of遍历数组对象
// for...of循环可以使用的范围包括数组、Set 和 Map 结构、某些类似数组的对象、Generator 对象以及字符串。
//遍历字符串
var str1 = "agen666";
for (let s1 of str1) {
console.warn(s1);
}
//遍历数组
var arr1 = ['3个月'];
for (let value of arr1) {
console.log(value);//3个月
}
//遍历数组对比for...in
var arr1 = ['3个月', '6个月', '9个月', '12个月'];
for (let index in arr1) {
console.log(index, arr1[index]);//0 3个月
}
//for...of循环支持 ES6 迭代(通过 iterables 和 iterators)和解构。。通过数组的ES6新方法enteries()结合解构,可以代替数组实例的forEach方法。
for (var [index, elem] of arr1.entries()) {
console.log('index=' , index, 'elem=',elem);
};
//遍历数组对象
var arr2 = [{ id: 3, name: '3个月' }, { id: 6, name: '6个月' }, { id: 9, name: '9个月' }, { id: 12, name: '12个月' },];
for (var [index, elem] of arr2.entries()) {
console.log('index=' , index, 'elem=',elem);
};
for...of 实现遍历对象,优点:支持跳出循环
forOfIteratorForOf() {
console.log("for...of实现遍历对象", "=".repeat(16))
var es6 = {
edition: 6,
committee: "TC39",
standard: "ECMA-262"
};
for (let e in es6) {
console.log(e);
}
// edition
// committee
// standard
// for (let e of es6) {
// console.log(e);
// }
// TypeError: es6[Symbol.iterator] is not a function
// 上面代码表示,对于普通的对象, for...in 循环可以遍历键名, for...of 循环会报错。
// 1一种解决方法是,使用 Object.keys 方法将对象的键名生成一个数组,然后遍历这个数组。
for (var key of Object.keys(es6)) {
console.log(key + ':' + es6[key]);
}
// for...of 循环相比上面几种做法,有一些显著的优点
// 有着同 for...in 一样的简洁语法,但是没有 for...in 那些缺点。
// 不同于 forEach 方法,它可以与 break 、 continue 和 return 配合使用。
// 提供了遍历所有数据结构的统一操作接口。
},
Promise
testPromise() {
// 回一个 Promise 对象,如果该对象状态变为 resolved ,则会调用 then 方法指定的回调函数;
// 如果异步操作抛出错误,状态就会变为 rejected ,就会调用 catch 方法指定的回调函数,处理这个错误。另外, then 方法指定的回调函数,如果运行中抛出错误,也会被 catch 方法捕获。
var promise = new Promise(function(resolve, reject) {
throw new Error('test');
});
promise.catch(function(error) {
console.log(error);
});
//,可以发现 reject 方法的作用,等同于抛出错误
var promise = new Promise(function(resolve, reject) {
try {
throw new Error('test two');
} catch (e) {
reject(e);
}
});
promise.catch(function(error) {
console.log(error);
})
//一般总是建议,Promise 对象后面要跟 catch 方法,这样可以处理 Promise 内部发生的错误。 catch 方法返回的还是一个 Promise 对象,因此后面还可以接着调用 then 方法。
var someAsyncThing = function() {
return new Promise(function(resolve, reject) {
// 下面一行会报错,因为x没有声明
resolve(x + 2);
})
};
someAsyncThing()
.catch(function(error) {
console.log('oh no', error);
})
.then(function() {
console.log('carry on');
})
// oh no [ReferenceError: x is not defined]
// carry on
// 上面代码运行完 catch 方法指定的回调函数,会接着运行后面那个 then 方法指定的回调函数。如果没有报错,则会跳过 catch 方法
var someAsyncThing = function() {
return new Promise(function(resolve, reject) {
// 下面一行会报错,因为x没有声明
resolve(x);
})
};
// catch 方法之中,还能再抛出错误。
someAsyncThing()
.catch(function(error) {
console.log('oh no', error);
})
.then(function() {
console.log('carry on');
y + 2;
}).catch(function(error) {
console.log('carry on', error);
});
// carry on
// 上面代码中,第二个 catch 方法用来捕获,前一个 catch 方法抛出的错误。
},
promise捕获异常
//promise带捕获异常
newPromise() {
new Promise((resolve, reject) => {
// var x=6;
// 下面一行会报错,因为x没有声明
resolve(x + 2);
}).catch((error) => {
// 捕获处理 Promise 内部发生的错误
console.warn(error);
}).then((res) => {
console.warn("res");
console.warn(res);
y + 2;
}).catch((error) => {
// 第二个 catch 方法用来捕获,前一个 then 方法抛出的错误
console.warn(error);
});
},
async对比promise
promise异步执行有延迟
normalPromise() {
// 写法有一个缺点,就是如果 f 是同步函数,那么它会在本轮事件循环的末尾执行
var f = () => console.log('now');
Promise.resolve().then(f);
console.log('next');
// next
// now
},
async-同步函数同步执行,异步函数异步执行
//有一种方法,让同步函数同步执行,异步函数异步执行。第一种写法是用async 函数来写。
asyncPromise() {
var f = () => console.log('now');
//自动执行f函数,并返回Promise对象
(async () => f())()
.then();
console.log('next');
// now
// next
},
async-await-没有resolve结果的情况
// pomise对象
async f1() {
let self = this;
await new Promise(resolve => {
console.log(1);
});
console.log(2);
}
testAwaitNotReturn() {
let self = this;
self.f1();
console.log(3);
}
//结果
//2
//3
async-await-有resolve结果的情况
async f2() {
let self = this;
await new Promise(resolve => {
console.log(1);
resolve();
});
console.log(2);
}
testAwaitReturn() {
let self = this;
self.f2();
console.log(3);
}
//结果
//2
//3
//1
set
setTest() {
// 去除数组重复成员
var arr = [1, 1, 2, 3];
var arr1 = Array.from(new Set(arr));
console.warn(arr1); // [1, 2, 3]
//扩展运算符和 Set 结构相结合,就可以去除数组的重复成员
var arr2 = [...new Set(arr)];
console.warn(arr2); // [1, 2, 3]
// 在遍历操作中,同步改变原来的 Set 结构
// 一种是利用原 Set 结构映射出一个新的结构,然后赋值给原来的 Set 结构
var set = new Set([1, 2, 3]);
set=new Set([...set].map(val=>val*2));
// 另一种是利用 Array.from
var set = new Set([1, 2, 3]);
set=new Set(Array.from(set,val=>val*2));
//数组的 map 和 filter 方法也可以用于 Set 了
var set=new Set([1,2,3]);
set = new Set([...set].map(x => x * 2));
console.warn(set);//{2, 4, 6}
var set = new Set([1, 2, 3,4,5]);
set=new Set([...set].filter(x=>(x%2==0)));
console.warn(set);//{2, 4}
// 因此使用 Set 可以很容易地实现并集(Union)、交集(Intersect)和差集(Difference)。
var a = new Set([1, 2, 3]);
var b = new Set([4, 3, 2]);
// 并集
var union = new Set([...a, ...b]);// {1, 2, 3, 4}
// 交集
var intersect =new Set([...a].filter(x=>b.has(x)))
console.warn(intersect);// {2, 3}
var difference=new Set([...a].filter(x=>!b.has(x)))
console.warn(difference);// {1}
},
set.forEach的值和索引是同一个值
// 由于Set集合对象中没有索引,所以它的值和索引都是同一个值
set.forEach((value, index) => console.warn(index + ':' + value))
// 1 : 1
// 4 : 4
// 9 : 9
set实现交集,并集
setTestTwo(){
var arr1 = [1, 2, 3];
var arr2 = [4, 3, 2];
var set1=new Set(arr1);
var set2=new Set(arr2);
// 并集
var union = new Set([...set1,...set2]);
console.warn(union);// {1, 2, 3, 4}
// 交集
var common = new Set([...set1].filter(value => set2.has(value)));
console.warn(common);// {2, 3}
//set1特有的元素,不同的元素
var difference = new Set([...set1].filter(value => !set2.has(value)));
console.warn(difference);// {1}
},
Symbol作为键名具有唯一性
symbolTest() {
//作为键名的 Symbol -唯一性
var mySymbol = Symbol();
var a = {
[mySymbol]: 'Hello!'
};
console.warn(a[mySymbol]); // "Hello!"
//作为属性名的 Symbol
var mySymbolValue = Symbol();
a.mySymbolValue = 'es6';
console.warn(a.mySymbolValue); //es6
},
Object.entries-实现对象转换Map
entries() {
var {
keys,
values,
entries
} = Object;
var obj = {
a: 1,
b: 2,
c: 3
};
for (let [key, value] of entries(obj)) {
console.warn([key, value]);
}
// ['a', 1], ['b', 2], ['c', 3]
// 如果 Object.values 方法的参数是一个字符串,会返回各个字符组成的一个数组
console.warn(Object.values('foo')); // ['f', 'o', 'o']
//Object.entries 的基本用途是遍历对象的属性
var obj = {
one: 1,
two: 2
};
for (let [k, v] of Object.entries(obj)) {
console.warn(
`${JSON.stringify(k)}: ${JSON.stringify(v)}`
);
}
// "one": 1
// "two": 2
// Object.entries 方法的另一个用处是,将对象转为真正的 Map 结构。
var obj = { foo: 'bar', baz: 42 };
var map=new Map(Object.entries(obj));
console.warn(map) // Map { foo: "bar", baz: 42 }
},
Object.assign
//对象浅拷贝,原对象改变不会影响新的对象的值
objectCopy() {
let obj = {
name: 'age',
age: 23,
};
let obj2 = { ...obj };
console.warn(obj2);//{name: "age", age: 23}
obj.age=26;
console.warn(obj);//{name: "age", age: 26}
console.warn(obj2);//{name: "age", age: 23}
console.warn('>>>>>>>>>>>>>>>>>>>>>>>>>>');
//Object.assign 方法实行的是浅拷贝,而不是深拷贝
let obj6 = {
name: 'age',
age: 23,
};
let obj7 = Object.assign({}, obj6);
obj6.age = 26;
console.warn(obj6);//{name: "age", age: 26}
console.warn(obj7);//{name: "age", age: 23}
console.warn('>>>>>>>>>>>>>>>>>>>>>>>>>>');
//也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
//assign
let obj5 = { a: { b: 1 } };
let obj3 = Object.assign({}, obj5);
obj5.a.b = 28;
console.warn(obj5);//{ a: { b: 28 } }
console.warn(obj3);//{ a: { b: 28 } }
},
属性名表达式与简洁表示法
let foo='bar';
let baz={
[foo]:'abc'
}
console.warn(baz);//{bar: "abc"}
Object.is
//”(同值相等)算法。Object.is用来比较两个值是否严格相等,严格比较运算符(===)的行为基本一致。
console.warn(Object.is('foo', 'foo'));
Array.from
arrayFrom(){
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
var arr2=Array.from(arrayLike);
console.warn(arr2);//[a,b,c]
arr2=Array.from('hello')
console.warn(arr2);//["h", "e", "l", "l", "o"]
let namesSet=new Set(['a','b'])
arr2=Array.from(namesSet);
console.warn(arr2);//["a", "b"]
//下面的例子将数组中布尔值为 false 的成员转为 0
arr2=Array.from([1,,2,,3],(n)=>n||0);
console.warn(arr2);//[1, 0, 2, 0, 3]
},
函数
通过提供函数参数的默认值,避免报错
// 如果没有提供参数,函数 foo 的参数默认为一个空对象。
// 通过提供函数参数的默认值,避免报错
foo({
x,
y = 5
} = {}) {
console.log(x, y);
},
this.foo(); // undefined 5
应用:利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误
// 应用:利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误。
function throwIfMissing() {
throw new Error('Missing parameter')
}
function params(mustBeProvided = throwIfMissing()) {
return mustBeProvided;
}
console.warn(params({
a: 1
}));
params();//执行提示报错
rest参数
// arguments变量的写法
function funsortNumbers() {
return Array.prototype.slice.call(arguments).sort();
}
// rest参数的写法
function sortNumbersRest(...numbers) {
return numbers.sort();
}
// 下面是一个利用 rest 参数改写数组 push 方法的例子
function pushRest(array, ...items) {
items.forEach((item) => {
array.push(item);
});
}
// arguments参数
var arr = funsortNumbers(8, 3, 1, 6);
console.warn(arr) //[1, 3, 6, 8]
// rest参数
var arr = sortNumbersRest(8, 3, 1, 6);
console.warn(arr) //[1, 3, 6, 8]
// 下面是一个利用 rest 参数改写数组 push 方法的例子
var a = [];
pushRest(a, 1, 2, 3);
console.warn(a); //[1, 2, 3]
// 下面是 rest 参数与箭头函数结合的例子
var numbers = (...nums) => nums.sort();
console.warn(numbers(1, 3, 2, 4)); //[1, 2, 3, 4]
rest参数简化数组排序
testRest() {
var arr = [8, 3, 1, 6];
// arguments变量的写法
var arr2 = Array.prototype.slice.call(arr).sort();
console.warn(arr); //[8, 3, 1, 6]
console.warn(arr2); //[1, 3, 6, 8]
// rest参数的写法
var arr3 = [...arr.sort()]
console.warn(arr3); //[1, 3, 6, 8]
},
Number Math方法
number() {
console.warn(Number('0o10'));//8
console.warn(Number.parseFloat('123.45#')); //123.45
// Math.trunc 方法用于去除一个数的小数部分
console.warn(Math.trunc('123.45')); //123
// Number.isInteger() 用来判断一个值是否为整数。需要注意的是,在 JavaScript 内部,整数和浮点数是同样的储存方法,所以 3 和 3.0 被视为同一个值
console.warn(Number.isInteger(25)); //true
console.warn(Number.isInteger(25.0)); //true
console.warn(2 ** 3); //8
console.warn(typeof 123); //number
},
正则表达式:
u修饰符匹配unicode
// u 修饰符 unicode
// \u0000 ~ \uffff 加u匹配超出这个范围的修饰符
var str = '\uD842\uDFB7' // 表示一个字符
console.log('\uD842\uDFB7', "\uD842\uDFB7" == "\u{20BB7}") //𠮷 true
console.log(/^\uD842/.test(str)) //true 把一个字符当做2个字符处理
console.log(/^\uD842/u.test(str)) //false
console.log(/^\u{20BB7}/u.test(str)) //true es6写法用大括号包裹
console.warn(/\u003F/.test('?')); // true
console.warn(/\u003F/u.test('?')); // true
console.warn(/\u{003F}/u.test('?')); // true
匹配除换行符以外的任意字符
// .匹配除换行符以外的任意字符
var str = '\uD842\uDFB7' // 表示一个字符
console.log(/^.$/.test(str)) // false
console.log(/^.$/u.test(str)) // true
y修饰符-匹配开头
// y 修饰符
var s = 'aaaa_aaa';
var r1 = /a+/g;
var r2 = /a+/y;
console.warn(r1.exec(s)) // ["aaa"]
console.warn(r1.exec(s)) // ["aa"]
console.warn(r2.exec(s)) // ["aaa"]
console.warn(r2.exec(s)) // null
console.warn(/b/y.exec('bia')) // ["b"]
//y 修饰符要求匹配必须从头部开始,所以返回 null
console.warn(/b/y.exec('aba')) // null
console.warn('a1a2a3'.match(/a\d/gy));//["a1", "a2", "a3"]
先行断言和后行断言
// ”先行断言“指的是, x 只有在 y 前面才匹配,必须写成 / x(?=y) / 。比如,只匹配百分号之前的数字,要写成 /\d + (?=%) / 。
// ”先行否定断言“指的是, x 只有不在 y 前面才匹配,必须写成 / x(?!y) / 。比如,只匹配不在百分号之前的数字,要写成 /\d + (? !%) / 。
var value = /\d+(?=%)/.exec('100% of US presidents have been male');
console.warn(value);// ["100"]
var value = /\d+(?!%)/.exec('that’s all 33 and 44% of them') ;
console.warn(value);// ["33"]
//“后行断言”正好与“先行断言”相反, x 只有在 y 后面才匹配,必须写成 /(?<=y)x/ 。
//比如,只匹配美元符号之后的数字
var value = /(?<=$)\d+/.exec('that’s all $33 of them');
console.warn(value);// ["33"]
// ”后行否定断言“则与”先行否定断言“相反, x 只有不在 y 后面才匹配,必须写成 / (?< !y)x /
//。比如,只匹配不在美元符号后面的数字,要写成 /(?<!\$)\d+/
var value = /(?<!\$)\d+/.exec('that’s all ¥33 of them');
console.warn(value);// ["33"]
简单匹配数字金额
/\d+(\.\d+)?/.exec('is ¥33.12345 all'); //33.12345
正则匹配括号 () []
//匹配()
testKuoHao() {
var aa = "ldfjsldfj(123))AAA";
//1 查找(开始
//2 ([^)]*)中是匹配内容,不包含)的任意字符,零个或多个的字符
var result = aa.match(/\(([^)]*)\)/);
//下面这种方式更加好理解:
// var result = aa.match(/\((.*)\)/);
// 此时result=["(123)", "123"];
console.log(result);
if (result) {
console.log(result[1]); // "123"
}
},
//匹配[]
testZhongkuo() {
var aa = "ldfjsldfj[123]AAA";
//1 查找[开始
//2 匹配多个字符
//3 查找]结束
var result = aa.match(/\[(.*)\]/);
console.log(result);
if (result) {
console.log(result[1]); // "123"
}
},
正则-手机号校验
方法1:test
var regExp = new RegExp('^[1][0-9]{10}$');
var telReg = regExp.test(mobile);
方法2:match
//tel.match匹配成功有值,例如:!!1=true
//tel.match匹配失败为null,例如:!!null=false
var telReg = !!tel.match(/^[1][0-9]{10}$/);
正则-大小写字母校验
test() {
var message ="12 aa ab 1";
var telReg = !!message.match(/.*[A-Za-z]+.*/);
console.warn(telReg);//true
},
正则-匹配以小数点开头
//匹配以小数点开头,.是特殊字符需要用到转义字符
var telReg = !!value.match(/^\./);
//匹配不以小数点开头,一次非逻辑判断即可
var telReg = !value.match(/^\./);
for ... of
//字符串的遍历器接口for ... of,这个遍历器最大的优点是可以识别大于 OxFFFF 的码点,
codePointAt() {
var s = "?a";
console.log(s.codePointAt(0));//134071
for (let ch of s) {
console.log(ch.codePointAt(0).toString(16));
}
//20bb7
//61
// let num = 134071;
// console.log(num.toString(16));
console.log(this.is32Bit("?")); //true
console.log(this.is32Bit("吉")); //false
//fromCodePoint用于从码点返回对应字符
console.log(String.fromCodePoint(0x20BB7));//吉
console.log('abc'.charAt(0));//a
},
codePointAt
//codePointAt方法是测试一个字符是由 2 个字节还是 4 个字节组成的最简单方法。
is32Bit(char) {
return char.codePointAt(0) > 0xFFFF;
},
字符的 Unicode 码
stringTest() {
//JavaScript 允许采用\uxxxx 形式表示一个字符,其中 xxxx 表示字符的 Unicode 码点。
//这种表示法只限于码点在\uOOOO~\uFFFF 之间的字符。超出这个范围的字符,必 须用 2 个双字节的形式表达
let j = "\uD842\uDFB7";
console.log('j=' + j); //j=?
let a = "\u20BB7";
console.log('a=' + a); //a=₻7
let a1 = "\u{20BB7}";
console.log('a1=' + a1); //a1=?
let b = "\u0041\u0042\u0043";
console.log('b=' + b); //b=ABC
let b1 = "\u{0041}\u{0042}\u{0043}";
console.log('b1=' + b1); //b1=ABC
console.log('z' === '\z' && '\x7A' === '\u007A' && 'z' === '\u{7A}'); //true
},
padStart
// padStart 的常见用途是为数值补全指定位数。下面代码生成 10 位的数值字符串。
console.log('1'.padStart(10, '0'));// "0000000001"
raw-用来获取一个模板字符串的原始字符串
String.raw 方法也可以作为正常的函数使用。这时,它的第一个参数,应该是一个具有 raw 属性的对象,且 raw 属性的值应该是一个数组。
String.raw({ raw: 'test' }, 0, 1, 2); // 't0e1s2t'
// 等同于
String.raw({ raw: ['t','e','s','t'] }, 0, 1, 2);
// 比如说,占位符(例如 ${foo})会被处理为它所代表的其他字符串,而转义字符(例如 \n)不会。
testRaw() {
console.warn(String.raw `Hi\n${2 + 3}!`);
// 'Hi\n5!',Hi 后面的字符不是换行符,\ 和 n 是两个不同的字符
// 但是为了模拟 `t${0}e${1}s${2}t` 你可以这样做:
console.warn(String.raw({
raw: 'test'
}, 0, 1, 2)); // 't0e1s2t'
},
扩展运算符(spread)是三个点(...
)
它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列
(1)复制数组
数组是复合的数据类型,直接复制的话,只是复制了指向底层数据结构的指针,而不是克隆一个全新的数组
const a1 = [1, 2];
// 写法一
const a2 = [...a1];
// 写法二
const [...a2] = a1;
对象浅拷贝
//对象浅拷贝
objectCopy(){
let obj = {
name: 'age',
age: 23,
};
let obj2={...obj};
console.log(obj2);
},
主要用于函数调用,
function add(x, y) {
return x + y;
}
const numbers = [4, 38];
add(...numbers) // 42
数组合并拼接
//展开运算符
spread() {
let arr = [1, 3, 5, 7, 9];
let max = this.max(arr);
console.log('max=' + max); //max=9
//等同于下面的效果
max = Math.max(1, 2, 3);
console.log('max=' + max); //max=3
//数组合并拼接
var a = [1, 2, 3];
var b = [...a, 4, 5, 6];
var c = b.concat(7, 8, 9);
console.log(c); //[1, 2, 3, 4, 5, 6, 7, 8, 9]
},
max(arr) {
return Math.max(...arr)
},
下面是扩展运算符取代 apply 方法的一个实际的例子,应用 Math.max 方法,简化求出一个数组最大元素的写法。
// ES6 的写法 Math.max(...[14, 3, 77])
spreadMax(){
//找到数据中最大值
console.warn(Math.max(...[9, 1, 3, 7, 5]));
// 另一个例子是通过 push 函数,将一个数组添加到另一个数组的尾部
// ES6 的写法
let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];
arr1.push(...arr2);
console.warn(arr1);//[0, 1, 2, 3, 4, 5]
console.warn(new Date(...[2015, 1, 1]));//Sun Feb 01 2015
let map = new Map([
[1, 'one'],
[2, 'two'],
[3, 'three'],
]);
let arr=[...map.keys()];
console.warn(arr);//[1, 2, 3]
},
属性名支持表达式
//属性名支持表达式
property() {
var name = 'a';
var obj = {};
obj[name] = 123;
console.log(obj);
var sex = 'man';
var params = {
[sex]: 123
};
console.log(params);
},
数组对象遍历map方法:
map()遍历、filter()筛选
ES6 map()遍历、filter()筛选--随记_leo-CSDN博客_es6 map遍历
查找数组对象的age属性,然后进行拼接,
testMapJoin() {
var chinaWords = [{
name: "君住长江头",
msg: "诗词",
age: 15
}, {
name: "我住长江尾",
msg: "歌赋",
age: 15
}, {
name: "日日思君不见君,同饮一江水",
msg: "古风",
age: 14
}];
var ages = chinaWords.map((obj, index) => {
console.log(index);
return obj.age;
}).join("");
console.log(ages); //151514
},
set用于数组去重
正则表达式
参考规则表:JavaScript RegExp 对象 | 菜鸟教程
1.获取10100668,从这个链接http://mmy.hbinfo.cn/wechat/index?deviceCode=10100668
// \d代表数字 $代表结尾部分
let flag = new RegExp(/\d+$/).exec(massageUrl)[0];
console.log(flag)
JS 判断字符串是否全部为数字
// \d代表数字 ^代表以数字开头 $代表以数字结尾部分
let reg7 = new RegExp(/^\d+$/).test('123')
console.log(reg7)//true
获取数字
let reg6 = new RegExp(/\d+/).exec('aa123bb')[0]
console.log(reg6)//123
JS 判断字符串是否全部为字母
let reg8 = new RegExp(/^[a-zA-Z]+$/).test('aabb')
console.log(reg8)
JS 判断输入是否为数字、字母、下划线组成
let reg9 = new RegExp(/^\w+$/).test('123_abc')
console.log(reg9)
es6是高级JavaScript
全称 ECMAScript 6.0 ,是 JaveScript 的下一个版本标准,2015.06 发版。就是JavaScript的高级版本
let和const
JavaScript中咱们以前主要用关键var来定义变量,
let 声明的变量只在 let 命令所在的代码块内有效。
const 声明一个只读的常量,一旦声明,常量的值就不能改变。