【学习笔记】ES6中变量和函数的新增内容

【学习笔记】ES6中变量和函数的新增内容

目录

  • 【学习笔记】ES6中变量和函数的新增内容
    • 一、原有变量存在的问题以及ES6给的新方案
      • 1.重复声明变量的问题
      • 2.常量的问题
      • 3.块级作用域
        • 3.1 ES6以下没有块级作用域的概念
        • 3.2 ES6的块级作用域
      • 4.解构赋值
    • 二、函数
      • 1.箭头函数
        • 1.1使用方法
        • 1.2简写
        • 1.3修正this
      • 2.参数扩展和数组对象的展开
      • 3.Array的扩展
        • 1.map
        • 2.reduce
        • 3.filter 过滤
        • 4.forEach 遍历
        • 5.补充字符串模板

一、原有变量存在的问题以及ES6给的新方案

1.重复声明变量的问题

非严格模式下,重复声明变量不会出错

var a = 5;
var a = 10;

在ES6中新提供了两种方案,let和const来定义变量。

这两个方法声明的变量都不允许重复

let a = 10;
let a = 5;
//报错 Uncaught SyntaxError: Identifier 'a' has already been declared

2.常量的问题

ES6之前,定义的变量都是可以更改的,想要声明一个常量,不允许修改,只能通过全部大写来人为的表示一下

var GIT_HOST = "这是一个常量";

但这样的定义,还是不安全。

ES6新添加的const就是声明常量用的

const MIX = 10;
MIX = 5;
//TypeError: Assignment to constant variable. 

修改const声明的常量时会报错

3.块级作用域

3.1 ES6以下没有块级作用域的概念

一个变量在被定义时,产生执行期上下文(注意是定义时产生)

使用ES5中的var定义的变量,如果是在函数中,它在函数以外的地方是不可见的

但是,如果该变量是定义在{}、if或者for这样的代码块中,它在代码块之外是可见的,相当于全局的变量

var arr = [];

for(var i = 0;i < 3; i++){  //for是一个块级
    function b(){    //b方法的定义本质属于全局的,作用域链上只含有全局作用域
        console.log(i);
    }
    arr[i] = b;
}
arr[0](); //3 
console.log(i); //3  这里的i是属于全局的
b(); //3

块级定义的内容都属于全局,所以外部访问相当于全局访问

而arr[0]() 调用的是b方法,此时b的作用域链如下 [[scope]] --> scope chain --> { 0 : AO(b自己的) , 1 : GO(全局的) }

b在全局中找到的i是循环结束后的,所以打印的i为3。

3.2 ES6的块级作用域

在ES6中给出了块级作用域的概念

使用 letconst 的定义的变量,多了一个块级的作用域,从外部是无法访问该变量的 。

但是要注意块级中定义的其他内容,本质上只是多了一层块级作用域

var arr = [];

for(let i = 0;i < 3; i++){  //for是块级作用域
    function b(){ 
        console.log(i);
    }
    arr[i] = b;
}
arr[0](); //0
//如果执行 console.log(i); //i is not defined 在全局中已经找不到i了
b(); //返回2

使用let后有两个变化:

​ 1.通过let定义的i值,是专属于for这个块级的,外界无法访问。

​ 2.块级中定义的其他函数,在作用域链上都添加了块级的作用域。

这里的arr[0]() 存的是第一次循环的b方法,其作用域链包括for第一次循环的块级作用域和全局作用域,不再只有全局作用域了

而b方法,在定义时本质上还是属于全局的,只是多了一个块级作用域。

每次循环定义出来的方法b,都会覆盖上一个b,同理作用域链也跟着改变了。

所以循环了三次之后,第三次的b方法,覆盖了前两次,此时b的作用域链包括了最后一次块级作用域和全局作用域

笔记补充:{ }就是一个代码块

 {  //块级中定义变量,var可以被外界访问,而let不可以
     var a = 10;
     let b = 10;
 }

console.log(a);
console.log(b);  //报错

4.解构赋值

解构赋值主要用在请求接口时使用

var json = {
    "a" : 12,
    "b" : 34
};
let {a,b} = json; 

用如上方法可以得到a = 12,b=34

相当于一次定义了两个值a,b,并给a,b赋值了

var arr = [12,5,8];
let [a,b,c] = arr;

同理,一次定义三个值a,b,c,并进行赋值

写解构赋值的时候要注意的要求:

1.两边的结构得一样,对象对应对象 – 数组对应数组

2.右边的内容,得有实际的东西,不能啥也不是

3.赋值和解构同时完成

针对第三点看以下代码,不可分开进行

let {a,b}; 报错
{a,b} = {a:12,b:13} //两步应该同时完成

4.在结构赋值时,针对对象进行结构,对象的属性可以有双引号,也可以没有

var json = {
    "a" : 12,
    "b" : 34
};
let {a,b} = json; 

var obj = {
    a : 12,
    b : 34
}
let {a,b} = obj;

这两个定义出来的a,b没有差别

二、函数

1.箭头函数

1.1使用方法

正常函数:function (){

}

箭头函数:()=>{}

1.2简写

1.如果有且仅有一个参数,这个**()可以不写
2.有且仅有一句语句是return,这个
{}return**可以不写

例子1:

//function add(n){
//    return n+5;
//}

function show(n,fn){
    console.log(fn(n));
}

//可以把add函数省略

show(12,n=>n+5);   //n => n+5就是一个函数,参数是n,返回值n+5

例子2:

let arr = [3,10,56,9];
arr.sort();
console.log(arr);  //按照数字第一位的编码进行排序

// arr.sort(function(a,b){
//     return a-b;
// })

//上述函数可以写成下面这个形式

arr.sort((a,b)=> a-b);//就只留下参量,用箭头指向函数块 

console.log(arr);   //得到正常排序结果
1.3修正this

箭头函数会固定this指向,固定的this是当前的环境,就是你定义this的时候,所处环境中this的指向,注意这里定义时,就是一开始这个this就是指向window的,通过箭头函数固定了下来,后面不管什么对象调用,这个this指向都不变。参考以下代码

 let json = {
            a : 12,
            fn : function(){ 
                console.log(this);
                console.log(this.a);
            }
        }

        let date = new Date();
        date.fn = json.fn;  //函数this指向到了date上,date并没有this.a
        //谁调用的,this指向谁
        date.fn();  //结果 时间,undefined

        

        // 字面量定义对象

        let json2 = {
            a : "字面量定义的",
            fn : () => {  //箭头函数会固定this指向,固定的this是当前的环境
                //就是你定义this的时候,所处环境中this的指向,注意这里定义时,就是一开始这个this就是指向window的
                //通过箭头函数固定了下来,后面不管什么对象调用,这个this指向都不变
                console.log(this);
                console.log(this.a);  //window上没有a
            }
        }

        json2.fn(); //结果 window undefined


        //使用class来定义对象

        class Json {   //这里的this的指向,是指向Json的。使用构造函数也是同理
            constructor(){   
                this.a = "类定义";
                this.fn = () => {
                    console.log(this.a);
                }
            }
        }

        let json3 = new Json();
        json3.fn(); //结果 类定义


        //使用构造函数

        function Json4() {
            this.a = "构造函数";
            this.fn = () => {
                console.log(this.a);
            }
        }
        let json4 = new Json4();
        json4.fn();  //结果 构造函数

2.参数扩展和数组对象的展开

1.收集剩余参数

在参数中使用,要求剩余参数只能在最后,后面不可以再放了

function show(a,b,...c){  //收集剩余参数到c,要求剩余参数只能在最后,后面不可以再放了
            console.log(a,b,c);
        }
show(1,2,3,4,5,6);  //返回结果 1 2 Array[4]-->[3,4,5,6]

2.数组的展开

数组中有什么内容,展开后返回的就是什么内容arr[1,2,3] ----> …arr == 1,2,3

let arr = [1,2,3];
function add(a,b,c){
    console.log(a + b + c); //打印结果6
}

add(...arr); //通过展开来写,...arr 相当于  1,2,3

//所以有了数组链接的新方法
let arr2 = [4,5,6];
let arr3 = [...arr,...arr2];
console.log(arr3);

3.对象的展开

//对象展开也是一样
let person = {
    name : "张三",
    age : 18,
    say : () => {
        console.log("Hello!");
    }
}

let student = {
    ...person,
    class : "一班",
    score : 100
}

console.log(student);

3.Array的扩展

1.map

​ 映射: 一一对应

​ [60 , 50 , 90] => [及格,不及格,及格]

let arr = [67, 78, 58, 89, 90];
let arr2 = arr.map(function (item){
    if(item >= 60){
        return '及格';
    }
    else{
        return '不及格'
    }
})  //映射完成后,才返回结果,所以有多少个返回多少个结果
//简化后的写法
arr2 = arr.map(item => item>=60?'及格':'不及格');
console.log(arr,arr2);  
2.reduce

​ 缩减: 多对一

​ n => 1 比如求和、求平局数

let score = [67, 78, 58, 89, 90];

let avg = score.reduce(function (tmp, item, index){
    console.log(index+':'+tmp+ ', '+ item);  //tmp一开始会把第一个值取出来,后面就是undefined,除非有返回值
    //注意index的值是对应item的,item是从score[1]开始的
    if(index == score.length - 1){
        return (tmp + item)/ (score.length)
    }else{
        return tmp + item;
    }
});
//优点,可以同时将前面遍历产生的结果和当前遍历项进行计算
console.log(avg);
3.filter 过滤
//过滤,取出全部偶数
let arr = [66,59,78,45,23];
let arr2 = arr.filter(item => item%2==0) //返回true是,把item添加到arr2中,false则不操作
console.log(arr);
console.log(arr2); //取出所有偶数
4.forEach 遍历
let arr = [66,59,78,45,23];
arr.forEach((item,index) => {
    console.log(`第${index}个元素是${item}`); //字符串模板,使用反引号,可以折行
})
5.补充字符串模板

​ 1.用反引号表示字符串模板
​ 2.字符串模板中,可以时用${}来获取变量,方便输出
​ 3.字符串模板的所有的空格、缩进和换行都会被保留在输出中

let a = "方便"

var str = `字符串模板注意使用反引号
换行是实际存在的,并非形式上的
引用变量也很${a}`

console.log(str);  

你可能感兴趣的:(javascript,javascript,ES6,闭包,属性,函数依赖)