Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Destructuring results in invalid write reference #68

Open
jbrumwell opened this issue Jun 4, 2015 · 4 comments
Open

Destructuring results in invalid write reference #68

jbrumwell opened this issue Jun 4, 2015 · 4 comments

Comments

@jbrumwell
Copy link

Given the following code;

const { x = 10 } = {};

The result is two write declarations on variable x the first to 10 and the second to the empty object {}

eslint-const-destruct

@mysticatea
Copy link
Contributor

Yeah, it is by design.

escope makes writable-references for variable-initializers.
When it's used together with destructuring and default values, the variable has multiple writable-references for its initializer.

So the Reference object has init property in order to check whether or not the reference is the initializer. And the Reference object has partial property in order to check whether or not the reference writes a part of writeExpr to the variable.

Please see also #65.
And eslint/eslint#2639 may help you.

@jbrumwell
Copy link
Author

@mysticatea Thank you for responding, given your description of init and partial I would be able to implement the changes in behaviour.

Partial doesn't seem to be operating in the fashion you mention, here are the results for partial and init in two different circumstances;

const { x = 10 } = { y: 15 };

  1. partial=false init=true // given your definition I'd expect this to be true
  2. partial=true init=true // given your definition I'd expect this to be false

const { x = 10 } = { x: 15 };

  1. partial=false init=true // given your definition I'd expect this to be true
  2. partial=true init=true

@mysticatea
Copy link
Contributor

On const { x = 10 } = { y: 15 };, x has two initializers.

  1. x = 10 is not partial.
  2. {x} = {y: 15} is partial. This means x = ({y: 15}).x. A runtime optimizer may remove it. But we can assignment to Object.prototype.x anywhere, so escope cannot decide whether it is undefined.

On const { x = 10 } = { x: 15 };, x has two initializers as almost same as the above. x = 10 exists but it is unreachable. escope does not analyze execution paths.

@jbrumwell
Copy link
Author

I may be wrong but I don't think this is incorrect according to the draft. My interpretation of the draft is that it creates a reference from the assignment expression, then declares the value with rhs destructuring if available and if not uses the default value on the assignment expression.

This makes sense because if it didn't you are declaring const twice when destructuring their assignments. This is also the way that babel transforms the code.

// const { x = 10 } = { y: 15 };
"use strict";

var _x = { y: 15 };
var _x$x = _x.x;
var x = _x$x === undefined ? 10 : _x$x;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants