资讯专栏INFORMATION COLUMN

ES的解构赋值-数组&对象

imccl / 2416人阅读

摘要:不执行对象的解构赋值对象的解构赋值和数组有一个不同,数组的元素是按次序排列的,变量的取值由它的位置决定而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。实际上,对象的解构赋值是以下形式的简写。

什么是解构?

按照一定的模式从数组或者对象中取值,对变量进行赋值的过程称为「解构」

在 ES5 中,为变量赋值只能直接指定值:

var a=1,b=2,c=3
a; // 1
b; // 2
c; // 3

但是在 ES6 中,我们可以被允许写成:

var [a,b,c]=[1,2,3];
a; // 1
b; // 2
c; // 3

ES6 中可以很明显看出来,我们可以在数组中取数据,按照位置的对应关系对变量赋值。

[默认值]
解构赋值允许使用默认值
var [foo = true] = [];
foo; // true
[x,y = "b"] = ["a"]
x; // "a"
y; // "b"
[x,y = "b"] = ["a","c"]
x; // "a"
y; // "c"

ES6 内部使用的是严格相等运算符(===)判断一个位置是否有值。所以,如果一个数组成员不严格等于 undefind,默认值是不会生效的。

var [x = 1] = [undefined];
x; // 1
null == undefined // true
var [x = 1] = [null];
x; // null

上述代码中,一个数组成员是 null,因此默认值不生效。因为 null 不严格等于 undefined。

function f(){
    console,log("aaa");
}
let [x = f()] = [1]; // undefined ,不执行 f()
x; // 1
对象的解构赋值
var {foo,bar}={foo:"aaa",bar:"bbb"};
foo; // "aaa"
bar; // "bbb"

对象的解构赋值和数组有一个不同,数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值。

var {laf} = {foo:"aaa",bar:"bbb"};
laf; // undefined;

在上面代码中,变量没有对应的同名属性,导致取不到值,最后等于 undefind。
实际上,对象的解构赋值是以下形式的简写。

var { foo: foo, bar: bar } = { foo:"aaa", bar:"bbb" }

实际上,在对象的解构赋值的内部机制,是先找到同名属性,然后在赋值给对应的变量。真正被赋值的是后者,而不是前者。

var { foo : bar } = {foo : "aaaa"};
foo; // foo is not defined
bar; // "aaaa"

采用这种写法是,变量的声明和赋值都是一体的。对于 let 和 const 而言,变量不能重新声明,所以一旦赋值的变量以前声明过,就会报错。

let foo;
let {foo}={foo:"1"}
// Uncaught SyntaxError: Identifier "foo" has already been declared

所以不能重复 let 声明:

let foo;
({foo} = {foo:1})

对象的解构也可以制定默认值。

var {x,y = 5} = {x:1};
x; // 1
y; // 5

默认值生效条件是,对象属性严格不等于 undefined

var {x = 3} = {x: undefined};
x; // 3
var {x = 3} = {x:null};
x; // null

和数组一样,解构也可以用于嵌套解构的对象。

var obj={
    p:[
        "hello",
        {y:"world"}
    ]
}

这时的 p 是模式,不是变量,因此不会被赋值。如果 p 也要作为变量赋值,应该写成这样:

var obj = {
    p:{
        "Hello",
        {
            y:"World"
        }
    }
}
let {p, p : { x , [ { y } ] = obj;

x // "Hello"
y // "World"
p // ["Hello", {y: "World"}]

下面一个例子:

var {loc,loc:{start},loc:{ start: { { line,column } } }={
    loc:{
        start:{
            line:1,
            column:5
        }
    }
}
上面代码有三次解构赋值,分别是对loc、start、line三个属性的解构赋值。注意,最后一次对line属性的解构赋值之中,只有line是变量,loc和start都是模式,不是变量。

var obj = [];
var arr = [];

({foo:obj.prop,bar: arr[0]} = {foo:123,bar:true});

obj; // {prop:123}
arr; // [true]

如果解构模式是嵌套的对象,而且子对象所在的父属性不存在,则会报错

var {foo : {bar}} = {baz:"baz"};

正确的写法:

var {foo,foo:{bar}}={foo:{bar:"bar"}};

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/104438.html

相关文章

  • 解析ES6变量赋值和基本数据类型

      let和const  let和const两者并不存在变量提升  这里要说明的是变量一定要在声明后使用,否则报错。  vara=[];   for(vari=0;i<10;i++){   a[i]=function(){   console.log(i);   };   }   a[6]();//10  变量i是var声明的,我们要知道这里在全局范围内都有效。我们要知道在每一次循环中,新的...

    3403771864 评论0 收藏0
  • JavaScript &amp; 6小时了解ES6基本语法

    摘要:返回布尔值,表示参数字符串是否在源字符串的头部。参考语法返回一个布尔值与的全等操作符比较兼容环境把对象的值复制到另一个对象里浅拷贝定义方法用于将所有可枚举的属性的值从一个或多个源对象复制到目标对象。语法要设置其原型的对象。 一步一步似爪牙。 前言 学习es6之前我们可能并不知道es6相比es5差距在哪, 但是这并不妨碍我们站在巨人的肩膀上; 程序员就是要乐于尝鲜; 学习es6最终目的是...

    Amos 评论0 收藏0
  • React&amp;ES6

    摘要:在中必须调用方法,因为子类没有自己的对象,而是继承父类的对象,然后对其进行加工而就代表了父类的构造函数。虽然代表了父类的构造函数,但是返回的是子类的实例,即内部的指的是,因此在这里相当于。要求,子类的构造函数必须执行一次函数,否则会报错。 1.class ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES...

    jeffrey_up 评论0 收藏0
  • React&amp;ES6

    摘要:在中必须调用方法,因为子类没有自己的对象,而是继承父类的对象,然后对其进行加工而就代表了父类的构造函数。虽然代表了父类的构造函数,但是返回的是子类的实例,即内部的指的是,因此在这里相当于。要求,子类的构造函数必须执行一次函数,否则会报错。 1.class ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。基本上,ES...

    mist14 评论0 收藏0

发表评论

0条评论

imccl

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<