不容错过的js文章,看完学会ES6
ES6中新增声明变量的方法let和const
在ES3时,我们声明变量一般用var来声明,在ES6中新增了let和const,下面我来说一下let、const和var的区别:
- var在代码执行时有变量提升,而let和const没有
console.log(a); //=> undefined
var a = 10;
console.log(a); //=> 10
console.log(b); //=>报错,Cannot access 'b' before initialization
let b = 10;
- var在创建变量的时候,会在上下文中创建变量,且在全局对象(GO)下建立一个属性,let和const创建变量时,只会在上下文中创建
var a = 0;
let b = 0;
console.log(window.a); //输出全局下的a => 0
console.log(window.b); //输出全局下的b => undefined
- var可以重复声明变量,但是浏览器只会识别一次,不会报错;let和const不可以重复声明变量,且在词法解析(发生在代码执行之前,就像var的变量提升一样)阶段就判断是否声明过,声明过的话直接报错,代码不会执行
//直接报错代码都不执行:Identifier 'a' has already been declared
let a = 10;
console.log(a);
let a = 20;
- let可以解决typeof的一个浏览器BUG,typeof在检测一个没有声明过的变量时,不会报错而是输出undefined,按理说应该报错的,这里可以用let在typeof下面声明这个变量,就可以达到报错的效果
typeof a; //报错而不是输出undefined
let a = 10;
- let和const的区别,let声明过的变量可以指向别的值,const声明过的变量不可以指向别的值,但是当const声明的是一个对象的时候,可以改变堆内存里面的属性值,不能改变堆内存的地址
let a = 10;
a = 20;
console.log(a); //=> 20
const b = 10; // 报错 Assignment to constant variable.
b = 20;
console.log(b);
const obj = {name:'珠峰培训'}
obj.name = '珠峰教育';
console.log(obj.name); //=> '珠峰教育'
箭头函数
箭头函数是ES6中新增加,可以简化函数编写的方式
- 语法:
let func = (形参) => {函数体}
- 跟普通函数的区别:
function func(){}; //创建普通函数
let func = () => {} //创建箭头函数
- 箭头函数在一些情况下可以简化函数编写的方式
- 当形参只有一个时,小括号可以省略
let func = (x) => {} => let func = x => {}
- 当函数体中只有一句return时,可以把大括号和return省略
let func = (x) => { return x++ } => let func = x => x++
- 当形参只有一个时,小括号可以省略
- 箭头函数中没有this和arguments,它会把this和arguments当成一个变量来判断,沿着作用域链去上级作用域中查找,call、apply和bind对箭头函数是没作用的
var arguments = 20;
var f2 = (a,b)=>{
console.log(this); // => window
console.log(arguments); // => 20
return 123;
}
剩余、展开运算符(…)
“…”很神奇的三个点,不同地方的使用代表不同的意思
剩余运算符:顾名思义就是把剩余下来的都拿到,且放到一个数组中
- 一般用在函数的形参传值中,例如任意数求和的时候,不知道传递几个参数就可以利用剩余运算符(args只是一个变量可以是任何值)
function func(x,y,...args) { console.log(args); // => [13,14] } func(11,12,13,14)
- 也会在箭头函数中用到,因为箭头函数中没有arguments,就可以用剩余运算符来创建一个形参集合的数组
let func = (...args) => { console.log(args); // => [12,13,14,15] } func(12,13,14,15)
展开运算符:就是把一个数组或者对象中的值展开成一项一项的
- 可以用于把数组或者对象展开成一项一项的
- 也可以用来数组或者对象的拼接
var a = [1,2,3], b = [3,4,5,6]; var c = [...a,...b]; console.log(c); //=> [1,2,3,3,4,5,6]
var o1 = {a:1,b:2,c:3}, o2 = {q:100,w:200,c:300}; var o3 = {...o1,...o2}; var o4 = {...o2,...o1}; console.log(o3,o4); //=> {a:1,b:2,c:3,q:100,w:200,c:300}
ES6模板字符串和结构赋值
ES6模板字符串,最大的特点是可以编写换行,若需要变量则编写${变量名};
- 语法:两个反引号包起来的字符串( ` )
- 和以前得区别:
var myname = "珠峰"; var str = '<div>'+ '<h1>hello '+myname+'</h1>'+ '</div>'; //字符串拼接 var str2 = `<div> <h1>hello ${myname}</h1> </div>` ; //ES6模板字符串
结构赋值
- 数组的结构赋值:根据索引位置赋值得
let ary = [1,2,3,4,5]; let [a,b,c,d] = ary;// 数组的结构赋值,他是根据位置(索引进行对应的) console.log(a,b,c,d); //=> a=1 b=2 c=3 d=4 //如果只想赋值a和d let [a,,,d] = ary; //=> a=1 d=4
- 对象的结构赋值:是把属性值根据属性名赋值给变量
var obj = {name:"珠峰",age:10,sex:0} var {name,age,age2=100} = obj; // 给属性名ag2添加的默认属性 console.log(name,age,age2); //=> name="珠峰" age=10 ag2=100 var {name:n} = obj;// 等价于把name的属性值赋值给n,var n = obj.name;
对象-数组原型上新增的方法
首先理解回调函数的意思,回调函数通俗的讲就是一个方法把这个函数调用了,这个函数就叫做回调函数。
数组
- forEach : 遍历数组,没有返回值
let ary = [100,200,300,400]; let res1 = ary.forEach((item=>{ console.log(item); //数组中每一项的值 });
- map : 遍历数组,有返回值,返回值是一个新数组,新数组是由每一个回调函数执行的返回值决定的
let ary = [100,200,300,400]; let res2 = ary.map((item=>{ return item+100 }); console.log(res2); //=> [200,300,400,500]
- some : 只要有一个回调函数的返回值是true ,则some的运行结果就是true, 一旦有一个回调函数的结果是true, 则后边的回调就不再执行了
let ary = [100,200,300,400]; let bol1 = ary.some(item=>{ console.log(item); //=> 100 200 300,到300时条件成立了后面的回调不在执行了 return item > 200 }) console.log(bol1); //=> true
- every : 只要有一个回调函数的返回值是false 则every的运行结果就是false,一旦有一个回调的结果是false ,则后边的回调就不再执行了;
let ary = [100,200,300,400]; let bol2 = ary.every(item=>{ console.log(item); //=> 100 200,到200时条件不成立了后面的回调不在执行了 return item < 200 }) console.log(bol2); //=> false
- filter : 过滤 把回调函数return值是true的复制一份放到新数组中;
let ary = [1,2,2,4,1,3]; let res1 = ary.filter(item=>{ return item <= 2 }) console.log(res1); //=> [1,2,2,1]
- reduce : prev,next 形参; prev上一个回调函数的返回值 next代表数组的下一项
- 若reduce存在第二个参数,那么第一次回调函数执行的时候,prev就是这个参数,next就是数组中的第一项;
let ary2 = [100,200,300,400]; let res2 = ary2.reduce((prev,next)=>{ console.log(prev,next); //=> 1000 100; undefined 200; undefined 300; undefined 400; },1000)
- 若不存在:
prev在第一个回调函数执行的时候 是数组中的第一项,在这之后的回调函数执行时,prev是上一个回调函数的返回值,next在第一个回调函数执行的时候 是数组中的第二项,在这之后都是数组的下一项let ary2 = [100,200,300,400]; let res2 = ary2.reduce((prev,next)=>{ console.log(prev,next); //=> 100 200; 200 300; 300 400; return next })
- 若reduce存在第二个参数,那么第一次回调函数执行的时候,prev就是这个参数,next就是数组中的第一项;
对象
- Object.is(value1,value2) 类似于“===” 特点:可以用来比较NaN;具体区分了+0和-0;
Object.is(NaN,NaN); //=> true Object.is(+0,-0); //=> false
- Object.assign() 用来合并对象
let obj1 = {name:'珠峰培训', age:10}, obj2 = {sex:100, age:100}; // 后面赋值的会把前面的顶掉 Object.assign(obj1,obj2) //=> {name:'珠峰培训',sex:100, age:100}返回值是合并后的obj1;obj2不变
- Object.keys(obj) : 把obj中的所有的属性名组成一个新数组
let obj = {name:'珠峰培训',sex:100, age:100}; Object.keys(obj); //=> ["name","sex","age"]
- Object.values(obj) : 把obj中的所有的属性值组成一个新数组
let obj = {name:'珠峰培训',sex:100, age:100}; Object.values(obj); //=> ['珠峰培训',100,100]
- obj2 = Object.freeze(obj) : obj和obj2是同一个地址; 被冻住的对象不能进行任何操作;等同于把地址冻住了
let obj = {name:'珠峰培训',sex:100, age:100}; let obj2 = Object.freeze(obj); obj2.name = '珠峰教育'; obj.sex = 200; console.log(obj); //=> {name: "珠峰培训", sex: 100, age: 100} console.log(obj2); //=> {name: "珠峰培训", sex: 100, age: 100}
ES6创建类的方法Class
class声明的类 只能通过 new 执行; 不能当作普通函数;
class People{
constructor(){
// constructor 就是当前类的函数体;
this.name = "zhufeng";
this.age = 10;
}
eat(){
// 在这些位置编写的属性 都是属于当前类的共有属性;
console.log(this.name)
}
static qwer = 6666; //给People增加属性
}
new People(); //=> 返回所属类的实例 {name:"zhufeng",age:10}
之前创建类的方式,和上面对应
function Person(){
this.name = "珠峰";
this.age = 10;
return 10
}
Person.prototype.eat = function(){
//属于当前类的共有属性
console.log(this.name)
}
Person.qwer = 666; //给Person增加属性
new Person(); //=> 返回所属类的实例 {name:"zhufeng",age:10}
Person(); //=> 10
尾记
以上都是ES6中新增加的比较重要的知识,特别感谢珠峰培训,希望对大家有所帮助,谢谢阅读!