关于js中对象的嵌套的解构并重组

关于js中对象的嵌套的解构并重组

在看《你不知道的JavaScript》下卷的时候遇到了一个问题,在第二部分2.5.3中的解构并重组遇到了一段代码

var defaults = {
    options: {
        remove: true,
        enable: false,
        instance: {}
    },
    log: {
        warn: true,
        error: true
    }
}

var config = {
    options: {
        remove: false,
        instance: null
    }
}

我们的本意是想要把config和defaults中的数据合并,并保留config自带的参数,虽然可以通过Object.assign来实现,但是因为是浅操作的原因,会导致内部对象比如options等只会复制对象引用,所以作者提供了一个结构的函数

config.options = config.options || {};
config.log = config.log || {};

{
    options: {
        remove: config.options.remove = defaults.options.remove,
            enable: config.options.enable = defaults.options.enable,
                instance: config.options.instance = defaults.options.instance
    } = {},
        log: {
            warn: config.log.warn = defaults.log.warn,
                error: config.log.error = defaults.log.error
        } = {}
} = config

但是这样就出现了一个问题,就是这么写的话会报错

Uncaught SyntaxError: Unexpected token ‘:’

记得前面有讲过说在解构赋值的时候{ }不可以直接出现在等号的左侧,不然会被当做语句块处理而不是对象处理

于是我加上了一个var变成了这样

var {
    options: {
        remove: config.options.remove = defaults.options.remove,
        enable: config.options.enable = defaults.options.enable,
        instance: config.options.instance = defaults.options.instance
    } = {},
    log: {
        warn: config.log.warn = defaults.log.warn,
        error: config.log.error = defaults.log.error
    } = {}
} = config

这样总没问题了吧?

Uncaught SyntaxError: Illegal property in declaration context

oh no ! 还是报错了,大概意思是使用了非法属性(我也没能理解为什么会报这个错,看看有没有大佬解答一下)

在vscode中报错(期望的符号应该是 , 而不是 . )

‘,’ expected

然后我想了想这个语法,按照正常来说,应该是声明变量的时候使用解构赋值,从config之中解构出options和log,然后再从这里面解构出几个属性,并且赋值给了config.options和config.log

啊?这是可以用var声明的吗,比如这么写

var a = {}
var a.haha = 123

Uncaught SyntaxError: Unexpected token ‘.’

哎!报了一样的错误,说明是不可以这样赋值的

不知道是不是这个书出的年代太久远了,版本更新已经不允许这么写了,于是我就试了另一个写法

var a = {
    options: {
        remove: config.options.remove = defaults.options.remove,
        enable: config.options.enable = defaults.options.enable,
        instance: config.options.instance = defaults.options.instance
    } = {},
    log: {
        warn: config.log.warn = defaults.log.warn,
        error: config.log.error = defaults.log.error
    } = {}
} = config

在控制台中输入a和config的数据,发现都变化了(并且符合我们的预期),并且最最最重要的一点!!!就是 a === config 的返回值是true。

那么这样就符合预期了,我就开始分析为什么会这样,以下都是个人推测和理解,有错误希望大佬指出:

首先我们通过“var a =”这些附加品解决了前面遇到的两个报错的问题,回到了正常的结构赋值的问题

  • 首先我们从config中解构出了options和log

  • 然后我们再从opitons和log中解构出了remove,enable等属性

  • 解构赋值中的结构是source -> target的哦不要搞错了

  • 然后我们将remove等属性都一一赋值到了config.options和config.log上

  • 而config原本没有的属性例如log中的warn和error,我们就会使用defaults.log的对应属性(解构赋值的默认值)

  • 然后又有重点来啦!!!

    • 在解构赋值采用了默认值之后,其实进行了两步:这里我们拿warn: config.log.warn = defaults.log.warn来举例子

      • 首先我们发现从config.log中解构出来的结果中是没有warn的,那么就会取得默认值也就是defaults.log.warn
      • 然后warn就有值了,并且把这个值传给了config.log.warn。
  • 那么我们就实现了结构赋值的同时,把config重组了

在控制台输出config我们就会发现他是已经达到了我们的预期,也就是作者想要表达的意思!

那为什么a === config呢?

我猜应该是赋值链最右端的值会一直往左边传吧,所以相当于进行了一步a = config,而config是对象,也就会进行一个浅拷贝咯

以上都是个人测试和理解,有错误希望大佬指出!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值