es6复习 ------ (1)

let & const

let的特点是,没有变量生命提升,而且会统治作用域(也就是不可以重复声明),在块级作用域内部声明的变量同样外部不能访问

const在满足以上所有的特点的同时,const声明的是常量(改变会报错),但这个常量指的是指向的内存地址不可以改变

{            
    var a = 1;            
    let b = 1;/        
}        
console.log(a);        
console.log(b);复制代码

访问不到b

依靠let这个特性我们可以解决闭包问题,那什么是闭包?闭包就是有权访问另一个函数作用域中变量的函数,我自己对闭包的理解其实就是“额外”保存了完整的作用域链内变量(记住是变量不是this)的一个函数,就常见来说函数内再套用一层函数并返回就可能会产生闭包

比如closure就是一个闭包。通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。但是,在创建了一个闭包以后,这个函数的作用域就会一直保存到闭包不存在为止。

function func(){
  var a = 1,b = 2;
  
  function closure(){
    return a+b;
  }
  return closure;
}复制代码

那举个万年例子

var arr = Array(10);        
for(var  i = 0; i < 10; i++) {
//let i = i;          
    arr[i] = function () {                
        return i;            
    }                    
}        
for(var  a = 0; a < 10; a++) {            
    console.log(arr[a]());        
}复制代码

打印10个10对吧,最常见的闭包问题,这里第一个for循环产生了闭包,这个闭包保留了目前自己所在的作用域链内完整的变量,在for里面的var i = 0这个变量声明是在全局里声明的(因为var不做用于块级作用域),我们执行每一个arr内部的函数的时候,这个函数会沿着自己的作用域链寻找i,就视图上看,从子域一步一步向外寻找i,直到var i = 0这里(即在全局声明的变量i),找到了i,可是这个i是在全局里声明的,那么在第十次循环的时候,我们已经令i = 10了,所以打印出来10个10;

那我们用let解决的话,其实可以理解成我们在块级作用域的每一次循环里添加了这一步

let i = i;//看上面位置复制代码

由于是let,所以我们在每一个块里都声明了i,在访问的时候,每一个arr内的元素沿着自己的作用域链访问到自己的块作用域是就会拿到i,而不像var在最后全局才能拿到。

此外啊,为什么说闭包保存的是整条作用域链里的变量,而不是this呢,再举个栗子

var name = 'window';        
var obj = {            
    name: 123,            
    getName: function () {                
        //var that = this                
        return function () {                    
            //return that.name;
            return this.name;                
        }            
    }        
}        
console.log(obj.getName()())复制代码

这里打印的是window,因为虽然产生闭包,但是this不会沿着所谓的作用域链老老实实的找,而是由于这个匿名函数是在全局被调用的,所以this指向的就是window对象,解决方法就是用一个that代替this,如上注释

解构赋值

两边模式一样的话,就会相应的进行匹配,比如我们在获取后台的json数据的时候,我们一点一点的获取,赋值等等操作是一件很麻烦的事,所以解构赋值为我们提供了方便,我们直接拿到后台传过来的json数据的格式,然后解构赋值就可以了

let [a, b, c, [d, f]] = [1, 2, 3, [1, 2]];复制代码

几种结构失败或者报错方式有以下几种

 let [a, b, c, d] = [1, 2, 3]//d是undefined
复制代码

let [a, b, c, d] = [1, 2, 3, 4, 5]//5赋值不进去复制代码

let [a, b, c, d] = 1;//或者undefined,null,{}等,会报错,这是迭代器iterator的问题
                     //Uncaught TypeError: {} is not iterable
复制代码

对象不行是因为解构赋值这里其实是一个for of循环,对象不支持,以后会详细说明iterator

默认赋值

let [a = 1, b = 2, c = 3] = [];复制代码

如果严格a b c 严格等于("===")undefined,那么就会触发默认赋值

惰性求值

let fn = function () {
    return 10
};

let [a = fn(), b = 2, c = 3] = [];复制代码

赋值顺序

解构赋值从右向左,如

var [a = 1, b = a] = [];console.log(a,b) // 1 1

var [a = b, b = 1] = [];console.log(a,b) // undefined  1复制代码

第二种情况,如果是let声明,记得let没有变量提升的作用,会报错a is not defined

对象的解构赋值

var {name, age, sex} = {        
    name: 'name',            
    age: '18',        
    sex: 'male'    
}复制代码

与数组情况类似

给属性值模式匹配

var {name: aName} = {        
    name: "name"    
}    
console.log(name)//undefined    
console.log(aName)//name复制代码

字符串的结构赋值

var {length} = "hello" console.log(length)// 5
把hello转化成类数组,然后进行匹配复制代码

var {toString} = "hello" //先变成类数组,再转化成对象
console.log(toString)//ƒ toString() { [native code] }复制代码

数值和布尔值得解构赋值 如果等号左边是数值或是布尔值,则会先转为对象

 let {toString: a} = 123;
 let {toString: b} = true; 
 console.log( a === Number.prototype.toString);// true
 console.log( b === Boolean.prototype.toString);// true
// undefined 和 null 不能转成对象所以会出错 
//let {toString: x } = undefined;
//let {toString: y } = null 
复制代码

几个小题

function move({x = 0,y = 0} = {}) {
            console.log([x,y]);
        }
        move({x:3,y:8}); // 3 8
        move({x:3});// 3 0
        move({});// 0 0
        move();// 0 0复制代码

 

 function deal({x,y} = {x: 0 , y: 0}) {
            console.log([x,y]);
        }     
        deal({x: 3,y: 8}); // 3 8
        deal({x: 3}); // 3 undefined
        deal({}); // undefined undefined
        deal(); // 0 0复制代码

变量交换

var x = 1;
var y = 2;
var  [x, y] = [y, x];复制代码

从函数返回多个值 

 function example () {
            return [1,2,3];
        }        
 var [a, b, c] = example(); 复制代码

函数参数的定义

 function f2({x,y,z}) {
            console.log(x,y,z);
        }        
f2({z:3,x:2,y:1});复制代码

 4.提交json数据 

var jsonData= {
            id: 42,
            status: 'ok',
            data:[888,999]            
        }
let {id,status,data:number} = jsonData;
console.log(id, status,number);复制代码

数组的扩展

Array.from()

把arguments,DOM等类数组转换成数组,并返还一个新数组,但这是一个浅拷贝,比如

var arr = [1, 2, [1, 2]];        
var arr1 = Array.from(arr); 
//let arr1 = Array.prototype.slice.call(arrayLike); 也是转化类数组为数组      
arr[2].push(3);        
console.log(arr1)复制代码

var arr1 = Array.from(arr, function (item) {
    return item + "a";
})
//类似于map方法复制代码

Array.of()

把一组数转化成数组,用于处理new Array(10)的问题


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值