文章目录
一,箭头函数
1,箭头函数的用法
- 箭头函数没有function的关键字
- 小括号和大括号之间有个箭头
- 如果参数是一个,可以省略小括号
- 如果没有return,可以不写大括号(return和大括号可以一起省略)
//普通函数
function fn(a){
return a;
}
//普通函数转化为箭头函数h
//1,不希望有函数声明的预编译环节,用let
let fn = (a)=>{
return a;
}
//2. 如果参数是一个,可以省略小括号
let fn = a =>{
return a;
}
//3. 省略return和大括号
let fn = a => a;
console.log(fn(1));//1
function a(c){
return function(d){
return c+d;
}
}
let a = c => d => c + d;
-----------------------------------------------------------------------------
function a(c){
return function(d){
return c+d;
}
}
console.log(a(1)(2));
let a = c => d => c + d;
console.log(a(1)(2));
-----------------------------------------------------------------------------
function a(c){
return function(d){
return {sum:c+d};
}
}
let a = c => d => ({sum:c+d});//如果直接返回的是对象,那么用()包裹
console.log(a(1)(2));
2,箭头函数解决this的问题
1,普通函数中setInterval函数里面的this是指向window的,因为setInterval本身就是winow上的一个函数
let obj = {
b:1,
a:function(){
setInterval(function(){
console.log(this);
}, 1000);
}
}
console.log(obj.a());//Window
2,我要让setInterval里面的this不指向window有三种方法:
1. var that = this;
2. 通过 bind方式绑定(this) call apply
3. 通过箭头函数,箭头函数中没有this指向
//第一种方法:
let obj = {
b:1,
a:function(){
let that = this;
setInterval(function(){
console.log(that);
}, 1000);
}
}
-----------------------------------------------------------------------------
//第二种方法:
let obj = {
b:1,
a:function(){
setInterval(function(){
console.log(this);
}.bind(this), 1000);
}
}
-----------------------------------------------------------------------------
//第三种方法:箭头函数:
//箭头函数中没有this指向,那么它自己没有就会向上找,a函数里面存在有隐式的this
let obj = {
b:1,
a:function(){//this
setInterval(()=>{
console.log(this);
}, 1000);
}
}
obj.a();
3,对象不是作用域
//{}不会产生作用域,对象不是作用域
let obj = {
b:1,
a:() => {
setInterval(() => {
console.log(this);//Window
}, 1000);
}
}
obj.a();
// 对象不是作用域 let声明的不会被提升到全局作用域上
let a = 1;
let obj={
a:2,
b:() => {
console.log(this.a);//undefined
}
}
obj.b();
二,剩余运算符
- 箭头函数中没有arguments
- …叫剩余运算符,就是把多余的都放在数组中(放到最后一个)
let fn = (x,...args) =>{
// console.log(arguments);//报错,因为箭头函数中没有arguments
console.log(args);//[1,2,3,4,5];
}
fn('x',1,2,3,4,5);
let fn = (...arguments) =>{//闲得慌的非要把arguments找回来
console.log(arguments.slice(1));//[1,2,3,4,5];
}
fn('x',1,2,3,4,5);
//函数可以赋予默认参数(没有传参数的时候)
let fn = (a=1,b=2) =>{
console.log(a,b);//1 2
}
fn();
三,展开运算符
function spread(x,...args){
// sum.apply(null,args);//老方法,改变this,然后把剩余运算符里面的数组传给sum函数作为参数u
sum(...args);//展开运算符
}
function sum(a,b,c,d){
console.log(a,b,c,d);
}
spread('X',1,2,3,4);
// let arr = [1,2,3,4].concat([5,6,7]);
let arr = [...[1,2,3,4], ...[5,6,7]];
console.log(arr);//[1,2,3,4,5,6,7]
Math.min(...[1,2,3,4]);
console.log(Math.min(...[1,2,3,4]));
四,展开运算符是浅拷贝
1,slice是浅拷贝
//slice是浅拷贝
let b=[1,2,3];
let a=[b];
let c = a.slice(0);
b[0]=100;
console.log(c);//100
2,…是浅拷贝(对象的展开)
//对象的展开 ...是浅拷贝
let name={name:'wdwd'};
let age = {age :8};
let school={...name, ...age};//{name:'wdwd',age:8}
let name={name:{name:'wdwd'}};
let age = {age :8};
let school={...name, ...age};
name.name.name = 'qs';
console.log(school);{name:{name:'qs'},age:8}
-----------------------------
//对象的还有一个es6新增的方法Object.assign来合并对象,和...是一样的功能,浅拷贝
let name={name:'wdwd'};
let age = {age :8};
obj={};
Object.assign(obj,name,age);
console.log(obj);//{ name: 'wdwd', age: 8 }
let name={name:'wdwd'};
let age = {age :8};
let obj = Object.assign(name,age);
console.log(obj);//{ name: 'wdwd', age: 8 }
3,深拷贝的实现
let obj = {a:1};
let obj = {a:1, fn:function(parms){}, t:/a/, d:new Date(), b:null};
console.log(JSON.parse(JSON.stringify(obj)));
//这种方式可以试想深拷贝,但是有缺陷,它只针对json,它不识别函数,正则,日期,
//它通通把它们转变为对象,还不保留继承关系
//实现深拷贝,保留继承关系,可以实现各种类型的拷贝 实现递归拷贝
function deepClone(obj) {
if(typeof obj !== 'object') return obj;
if(obj === null) return null;
if(obj instanceof Date) return new Date(obj);
if(obj instanceof RegExp) return new RegExp(obj);
// Object.prototype.toString.call(obj) ==='[object Array]'//这种方式也不太好
let o = new obj.constructor();//保留类的继承关系
// console.log(o);
for(let key in obj){
o[key] = typeof obj[key] === 'object' ?deepClone(obj[key]):obj[key];
}
return o;
}
let o = {a:{a:1}}
let newObj = deepClone(o);
o.a.a=2;
console.log(newObj);