feat(es/minifier): Turn Array/Object calls into literals (#4947)

This commit is contained in:
Austaras 2022-06-12 10:36:49 +08:00 committed by GitHub
parent 461b9902b3
commit 47bdc6a6b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 313 additions and 164 deletions

View File

@ -1,5 +1,5 @@
var A; var A;
!function(A1) { !function(A1) {
var beez; var beez;
A1.beez2 = Array(), A1.beez = beez; A1.beez2 = [], A1.beez = beez;
}(A || (A = {})); }(A || (A = {}));

View File

@ -5,5 +5,5 @@ import _class_call_check from "@swc/helpers/lib/_class_call_check.js";
"use strict"; "use strict";
_class_call_check(this, B); _class_call_check(this, B);
}; };
A1.beez2 = Array(), A1.beez = beez; A1.beez2 = [], A1.beez = beez;
}(A || (A = {})); }(A || (A = {}));

View File

@ -20,11 +20,13 @@ var a1 = [
var a2 = [ var a2 = [
, ,
, ,
,
].concat(_to_consumable_array(a0), [ ].concat(_to_consumable_array(a0), [
"hello" "hello"
]); ]);
var a3 = [ var a3 = [
, ,
,
].concat(_to_consumable_array(a0)); ].concat(_to_consumable_array(a0));
var a4 = [ var a4 = [
function() { function() {

View File

@ -9,10 +9,12 @@ var a0 = [
[ [
, ,
, ,
,
].concat(_to_consumable_array(a0), [ ].concat(_to_consumable_array(a0), [
"hello" "hello"
]), [ ]), [
, ,
,
].concat(_to_consumable_array(a0)), _to_consumable_array(a0).concat([ ].concat(_to_consumable_array(a0)), _to_consumable_array(a0).concat([
, ,
]); ]);

View File

@ -21,11 +21,13 @@ var a1 = [
var a2 = [ var a2 = [
, ,
, ,
,
].concat(_to_consumable_array(a0), [ ].concat(_to_consumable_array(a0), [
"hello" "hello"
]); ]);
var a3 = [ var a3 = [
, ,
,
].concat(_to_consumable_array(a0)); ].concat(_to_consumable_array(a0));
var a4 = [ var a4 = [
function() { function() {

View File

@ -8,10 +8,12 @@ var a0 = [
], a2 = [ ], a2 = [
, ,
, ,
,
].concat(_to_consumable_array(a0), [ ].concat(_to_consumable_array(a0), [
"hello" "hello"
]), a3 = [ ]), a3 = [
, ,
,
].concat(_to_consumable_array(a0)); ].concat(_to_consumable_array(a0));
_to_consumable_array(a0).concat([ _to_consumable_array(a0).concat([
, ,

View File

@ -1,2 +1,2 @@
function foo(t) {} function foo(t) {}
foo(1), foo(null), foo(new Object()), foo(1), foo(new Date()); foo(1), foo(null), foo({}), foo(1), foo(new Date());

View File

@ -1,2 +1,2 @@
function foo(t) {} function foo(t) {}
foo(1), foo(null), foo(new Object()), foo(1), foo(new Date()); foo(1), foo(null), foo({}), foo(1), foo(new Date());

View File

@ -1,7 +1,7 @@
var E, F, x; var E, F, x;
function foo(x, a, b) {} function foo(x, a, b) {}
function foo2(x, a, b) {} function foo2(x, a, b) {}
foo('', (x)=>'', (x)=>null), foo('', (x)=>'', (x)=>null), foo('', (x)=>'', (x)=>''), foo(null, (x)=>'', (x)=>''), foo(null, (x)=>'', (x)=>''), foo(new Object(), (x)=>'', (x)=>''), function(E) { foo('', (x)=>'', (x)=>null), foo('', (x)=>'', (x)=>null), foo('', (x)=>'', (x)=>''), foo(null, (x)=>'', (x)=>''), foo(null, (x)=>'', (x)=>''), foo({}, (x)=>'', (x)=>''), function(E) {
E[E.A = 0] = "A"; E[E.A = 0] = "A";
}(E || (E = {})), function(F) { }(E || (E = {})), function(F) {
F[F.A = 0] = "A"; F[F.A = 0] = "A";

View File

@ -21,7 +21,7 @@ foo("", function(x) {
return ""; return "";
}, function(x) { }, function(x) {
return ""; return "";
}), foo(new Object(), function(x) { }), foo({}, function(x) {
return ""; return "";
}, function(x) { }, function(x) {
return ""; return "";

View File

@ -1,8 +1,25 @@
runTestCase(function() { runTestCase(function() {
var a = Array(!1, void 0, null, "0", { var a = [
toString: function() { !1,
return 0; void 0,
} null,
}, -1.3333333333333, "str", -0, !0, 0, 1, 1, 0, !1, -4 / 3, -4 / 3); "0",
{
toString: function() {
return 0;
}
},
-1.3333333333333,
"str",
-0,
!0,
0,
1,
1,
0,
!1,
-4 / 3,
-4 / 3
];
if (14 === a.indexOf(-4 / 3) && 7 === a.indexOf(0) && 7 === a.indexOf(-0) && 10 === a.indexOf(1)) return !0; if (14 === a.indexOf(-4 / 3) && 7 === a.indexOf(0) && 7 === a.indexOf(-0) && 10 === a.indexOf(1)) return !0;
}); });

View File

@ -1,8 +1,25 @@
runTestCase(function() { runTestCase(function() {
var a = Array(!1, void 0, null, "0", { var a = [
toString: function() { !1,
return 0; void 0,
} null,
}, -1.3333333333333, "str", -0, !0, 0, 1, 1, 0, !1, -4 / 3, -4 / 3); "0",
{
toString: function() {
return 0;
}
},
-1.3333333333333,
"str",
-0,
!0,
0,
1,
1,
0,
!1,
-4 / 3,
-4 / 3
];
if (14 === a.indexOf(-4 / 3) && 7 === a.indexOf(0) && 7 === a.indexOf(-0) && 10 === a.indexOf(1)) return !0; if (14 === a.indexOf(-4 / 3) && 7 === a.indexOf(0) && 7 === a.indexOf(-0) && 10 === a.indexOf(1)) return !0;
}); });

View File

@ -1,4 +1,4 @@
var r = { var r = {
s: new Object() s: {}
}; };
r.s && r.s.toFixed(); r.s && r.s.toFixed();

View File

@ -1,4 +1,4 @@
var r = { var r = {
s: new Object() s: {}
}; };
r.s && r.s.toFixed(); r.s && r.s.toFixed();

View File

@ -79,10 +79,11 @@ add_bitflags!(
/// If the literal is empty, do not add spaces between braces. /// If the literal is empty, do not add spaces between braces.
NoSpaceIfEmpty: 1 << 18, NoSpaceIfEmpty: 1 << 18,
SingleElement: 1 << 19, SingleElement: 1 << 19,
ForceTrailingComma: 1 << 20,
}, },
// Optimization. // Optimization.
Values { Values {
CanSkipTrailingComma: 1 << 20 CanSkipTrailingComma: 1 << 21
}, },
/// Precomputed Formats /// Precomputed Formats
Values { Values {

View File

@ -1835,11 +1835,12 @@ where
srcmap!(node, true); srcmap!(node, true);
punct!("["); punct!("[");
self.emit_list( let mut format = ListFormat::ArrayLiteralExpressionElements;
node.span(), if let Some(None) = node.elems.last() {
Some(&node.elems), format |= ListFormat::ForceTrailingComma;
ListFormat::ArrayLiteralExpressionElements, }
)?;
self.emit_list(node.span(), Some(&node.elems), format)?;
punct!("]"); punct!("]");
srcmap!(node, false); srcmap!(node, false);
@ -2224,25 +2225,26 @@ where
} }
// Write a trailing comma, if requested. // Write a trailing comma, if requested.
let has_trailing_comma = format.contains(ListFormat::AllowTrailingComma) && { let has_trailing_comma = format.contains(ListFormat::ForceTrailingComma)
if parent_node.is_dummy() { || format.contains(ListFormat::AllowTrailingComma) && {
false if parent_node.is_dummy() {
} else { false
match self.cm.span_to_snippet(parent_node) { } else {
Ok(snippet) => { match self.cm.span_to_snippet(parent_node) {
if snippet.len() < 3 { Ok(snippet) => {
false if snippet.len() < 3 {
} else { false
let last_char = snippet.chars().last().unwrap(); } else {
snippet[..snippet.len() - last_char.len_utf8()] let last_char = snippet.chars().last().unwrap();
.trim() snippet[..snippet.len() - last_char.len_utf8()]
.ends_with(',') .trim()
.ends_with(',')
}
} }
_ => false,
} }
_ => false,
} }
} };
};
if has_trailing_comma if has_trailing_comma
&& format.contains(ListFormat::CommaDelimited) && format.contains(ListFormat::CommaDelimited)

View File

@ -1101,104 +1101,6 @@ where
Some(e.take()) Some(e.take())
} }
/// `new RegExp("([Sap]+)", "ig")` => `/([Sap]+)/gi`
fn compress_regexp(&mut self, e: &mut Expr) {
let (span, args) = match e {
Expr::New(NewExpr {
span,
callee,
args: Some(args),
..
})
| Expr::Call(CallExpr {
span,
callee: Callee::Expr(callee),
args,
..
}) => match &**callee {
Expr::Ident(Ident {
sym: js_word!("RegExp"),
..
}) => (*span, args),
_ => return,
},
_ => return,
};
if args.is_empty() || args.len() > 2 {
return;
}
// We aborts the method if arguments are not literals.
if args.iter().any(|v| {
v.spread.is_some()
|| match &*v.expr {
Expr::Lit(Lit::Str(s)) => {
if s.value.contains(|c: char| {
// whitelist
!c.is_ascii_alphanumeric()
&& !matches!(c, '%' | '[' | ']' | '(' | ')' | '{' | '}' | '-' | '+')
}) {
return true;
}
if s.value.contains("\\\0") || s.value.contains('/') {
return true;
}
false
}
_ => true,
}
}) {
return;
}
//
let pattern = args[0].expr.take();
let pattern = match *pattern {
Expr::Lit(Lit::Str(s)) => s.value,
_ => {
unreachable!()
}
};
if pattern.is_empty() {
// For some expressions `RegExp()` and `RegExp("")`
// Theoretically we can use `/(?:)/` to achieve shorter code
// But some browsers released in 2015 don't support them yet.
args[0].expr = pattern.into();
return;
}
let flags = args
.get_mut(1)
.map(|v| v.expr.take())
.map(|v| match *v {
Expr::Lit(Lit::Str(s)) => {
assert!(s.value.is_ascii());
let s = s.value.to_string();
let mut bytes = s.into_bytes();
bytes.sort_unstable();
String::from_utf8(bytes).unwrap().into()
}
_ => {
unreachable!()
}
})
.unwrap_or(js_word!(""));
report_change!("Converting call to RegExp into a regexp literal");
self.changed = true;
*e = Expr::Lit(Lit::Regex(Regex {
span,
exp: pattern,
flags,
}))
}
fn merge_var_decls(&mut self, stmts: &mut Vec<Stmt>) { fn merge_var_decls(&mut self, stmts: &mut Vec<Stmt>) {
if !self.options.join_vars && !self.options.hoist_vars { if !self.options.join_vars && !self.options.hoist_vars {
return; return;
@ -1739,8 +1641,6 @@ where
self.drop_unused_assignments(e); self.drop_unused_assignments(e);
self.compress_regexp(e);
self.compress_lits(e); self.compress_lits(e);
self.compress_typeofs(e); self.compress_typeofs(e);

View File

@ -230,12 +230,172 @@ impl Pure<'_> {
} }
} }
/// `new RegExp("([Sap]+)", "ig")` => `/([Sap]+)/gi`
fn optimize_regex(&mut self, args: &mut Vec<ExprOrSpread>, span: &mut Span) -> Option<Expr> {
if args.is_empty() || args.len() > 2 {
return None;
}
// We aborts the method if arguments are not literals.
if args.iter().any(|v| {
v.spread.is_some()
|| match &*v.expr {
Expr::Lit(Lit::Str(s)) => {
if s.value.contains(|c: char| {
// whitelist
!c.is_ascii_alphanumeric()
&& !matches!(c, '%' | '[' | ']' | '(' | ')' | '{' | '}' | '-' | '+')
}) {
return true;
}
if s.value.contains("\\\0") || s.value.contains('/') {
return true;
}
false
}
_ => true,
}
}) {
return None;
}
let pattern = args[0].expr.take();
let pattern = match *pattern {
Expr::Lit(Lit::Str(s)) => s.value,
_ => {
unreachable!()
}
};
if pattern.is_empty() {
// For some expressions `RegExp()` and `RegExp("")`
// Theoretically we can use `/(?:)/` to achieve shorter code
// But some browsers released in 2015 don't support them yet.
args[0].expr = pattern.into();
return None;
}
let flags = args
.get_mut(1)
.map(|v| v.expr.take())
.map(|v| match *v {
Expr::Lit(Lit::Str(s)) => {
assert!(s.value.is_ascii());
let s = s.value.to_string();
let mut bytes = s.into_bytes();
bytes.sort_unstable();
String::from_utf8(bytes).unwrap().into()
}
_ => {
unreachable!()
}
})
.unwrap_or(js_word!(""));
Some(Expr::Lit(Lit::Regex(Regex {
span: *span,
exp: pattern,
flags,
})))
}
/// Array() -> []
fn optimize_array(&mut self, args: &mut Vec<ExprOrSpread>, span: &mut Span) -> Option<Expr> {
if args.len() == 1 {
if let ExprOrSpread { spread: None, expr } = &args[0] {
match &**expr {
Expr::Lit(Lit::Num(num)) => {
if num.value <= 5_f64 && num.value >= 0_f64 {
Some(Expr::Array(ArrayLit {
span: *span,
elems: vec![None; num.value as usize],
}))
} else {
None
}
}
Expr::Lit(_) => Some(Expr::Array(ArrayLit {
span: *span,
elems: vec![args.take().into_iter().next()],
})),
_ => None,
}
} else {
None
}
} else {
Some(Expr::Array(ArrayLit {
span: *span,
elems: args.take().into_iter().map(Some).collect(),
}))
}
}
/// Object -> {}
fn optimize_object(&mut self, args: &mut Vec<ExprOrSpread>, span: &mut Span) -> Option<Expr> {
if args.is_empty() {
Some(Expr::Object(ObjectLit {
span: *span,
props: Vec::new(),
}))
} else {
None
}
}
/// new Array(...) -> Array(...) /// new Array(...) -> Array(...)
pub(super) fn remove_new(&mut self, e: &mut Expr) { pub(super) fn optimize_builtin_object(&mut self, e: &mut Expr) {
if !self.options.pristine_globals { if !self.options.pristine_globals {
return; return;
} }
match e {
Expr::New(NewExpr {
span,
callee,
args: Some(args),
..
})
| Expr::Call(CallExpr {
span,
callee: Callee::Expr(callee),
args,
..
}) if callee
.is_one_of_global_ref_to(&self.expr_ctx, &["Array", "Object", "RegExp"]) =>
{
let new_expr = match &**callee {
Expr::Ident(Ident {
sym: js_word!("RegExp"),
..
}) => self.optimize_regex(args, span),
Expr::Ident(Ident {
sym: js_word!("Array"),
..
}) => self.optimize_array(args, span),
Expr::Ident(Ident {
sym: js_word!("Object"),
..
}) => self.optimize_object(args, span),
_ => unreachable!(),
};
if let Some(new_expr) = new_expr {
report_change!(
"Converting Regexp/Array/Object call to native constructor into literal"
);
self.changed = true;
*e = new_expr;
return;
}
}
_ => {}
};
match e { match e {
Expr::New(NewExpr { Expr::New(NewExpr {
span, span,
@ -245,6 +405,7 @@ impl Pure<'_> {
}) if callee.is_one_of_global_ref_to( }) if callee.is_one_of_global_ref_to(
&self.expr_ctx, &self.expr_ctx,
&[ &[
"Object",
// https://262.ecma-international.org/12.0/#sec-array-constructor // https://262.ecma-international.org/12.0/#sec-array-constructor
"Array", "Array",
// https://262.ecma-international.org/12.0/#sec-function-constructor // https://262.ecma-international.org/12.0/#sec-function-constructor

View File

@ -371,7 +371,7 @@ impl VisitMut for Pure<'_> {
self.compress_useless_cond_expr(e); self.compress_useless_cond_expr(e);
self.remove_new(e); self.optimize_builtin_object(e);
} }
fn visit_mut_expr_stmt(&mut self, s: &mut ExprStmt) { fn visit_mut_expr_stmt(&mut self, s: &mut ExprStmt) {

View File

@ -5177,7 +5177,9 @@
75202: function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 75202: function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
"use strict"; "use strict";
var $ = __webpack_require__(35437), $findIndex = __webpack_require__(48499).findIndex, addToUnscopables = __webpack_require__(23140), FIND_INDEX = "findIndex", SKIPS_HOLES = !0; var $ = __webpack_require__(35437), $findIndex = __webpack_require__(48499).findIndex, addToUnscopables = __webpack_require__(23140), FIND_INDEX = "findIndex", SKIPS_HOLES = !0;
FIND_INDEX in [] && Array(1)[FIND_INDEX](function() { FIND_INDEX in [] && [
,
][FIND_INDEX](function() {
SKIPS_HOLES = !1; SKIPS_HOLES = !1;
}), $({ }), $({
target: "Array", target: "Array",
@ -5192,7 +5194,9 @@
37742: function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) { 37742: function(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
"use strict"; "use strict";
var $ = __webpack_require__(35437), $find = __webpack_require__(48499).find, addToUnscopables = __webpack_require__(23140), FIND = "find", SKIPS_HOLES = !0; var $ = __webpack_require__(35437), $find = __webpack_require__(48499).find, addToUnscopables = __webpack_require__(23140), FIND = "find", SKIPS_HOLES = !0;
FIND in [] && Array(1)[FIND](function() { FIND in [] && [
,
][FIND](function() {
SKIPS_HOLES = !1; SKIPS_HOLES = !1;
}), $({ }), $({
target: "Array", target: "Array",
@ -8390,7 +8394,12 @@
79085: function(module, __unused_webpack_exports, __webpack_require__) { 79085: function(module, __unused_webpack_exports, __webpack_require__) {
"use strict"; "use strict";
__webpack_require__(17384); __webpack_require__(17384);
var $ = __webpack_require__(35437), getBuiltIn = __webpack_require__(44990), USE_NATIVE_URL = __webpack_require__(62902), redefine = __webpack_require__(78109), redefineAll = __webpack_require__(59855), setToStringTag = __webpack_require__(77875), createIteratorConstructor = __webpack_require__(10536), InternalStateModule = __webpack_require__(44670), anInstance = __webpack_require__(51819), isCallable = __webpack_require__(67106), hasOwn = __webpack_require__(1521), bind = __webpack_require__(59561), classof = __webpack_require__(85983), anObject = __webpack_require__(83941), isObject = __webpack_require__(39817), $toString = __webpack_require__(72729), create = __webpack_require__(18255), createPropertyDescriptor = __webpack_require__(93608), getIterator = __webpack_require__(11661), getIteratorMethod = __webpack_require__(99422), wellKnownSymbol = __webpack_require__(81019), nativeFetch = getBuiltIn("fetch"), NativeRequest = getBuiltIn("Request"), RequestPrototype = NativeRequest && NativeRequest.prototype, Headers = getBuiltIn("Headers"), ITERATOR = wellKnownSymbol("iterator"), URL_SEARCH_PARAMS = "URLSearchParams", URL_SEARCH_PARAMS_ITERATOR = URL_SEARCH_PARAMS + "Iterator", setInternalState = InternalStateModule.set, getInternalParamsState = InternalStateModule.getterFor(URL_SEARCH_PARAMS), getInternalIteratorState = InternalStateModule.getterFor(URL_SEARCH_PARAMS_ITERATOR), plus = /\+/g, sequences = Array(4), percentDecode = function(sequence) { var $ = __webpack_require__(35437), getBuiltIn = __webpack_require__(44990), USE_NATIVE_URL = __webpack_require__(62902), redefine = __webpack_require__(78109), redefineAll = __webpack_require__(59855), setToStringTag = __webpack_require__(77875), createIteratorConstructor = __webpack_require__(10536), InternalStateModule = __webpack_require__(44670), anInstance = __webpack_require__(51819), isCallable = __webpack_require__(67106), hasOwn = __webpack_require__(1521), bind = __webpack_require__(59561), classof = __webpack_require__(85983), anObject = __webpack_require__(83941), isObject = __webpack_require__(39817), $toString = __webpack_require__(72729), create = __webpack_require__(18255), createPropertyDescriptor = __webpack_require__(93608), getIterator = __webpack_require__(11661), getIteratorMethod = __webpack_require__(99422), wellKnownSymbol = __webpack_require__(81019), nativeFetch = getBuiltIn("fetch"), NativeRequest = getBuiltIn("Request"), RequestPrototype = NativeRequest && NativeRequest.prototype, Headers = getBuiltIn("Headers"), ITERATOR = wellKnownSymbol("iterator"), URL_SEARCH_PARAMS = "URLSearchParams", URL_SEARCH_PARAMS_ITERATOR = URL_SEARCH_PARAMS + "Iterator", setInternalState = InternalStateModule.set, getInternalParamsState = InternalStateModule.getterFor(URL_SEARCH_PARAMS), getInternalIteratorState = InternalStateModule.getterFor(URL_SEARCH_PARAMS_ITERATOR), plus = /\+/g, sequences = [
,
,
,
,
], percentDecode = function(sequence) {
try { try {
return decodeURIComponent(sequence); return decodeURIComponent(sequence);
} catch (error) { } catch (error) {

View File

@ -4778,7 +4778,7 @@
{ {
key: "decode", key: "decode",
value: function(row, start) { value: function(row, start) {
var result = Array(), decodedCodes = Array(), resultInfo = {}, startInfo = this._findStart(); var result = [], decodedCodes = [], resultInfo = {}, startInfo = this._findStart();
if (!startInfo) return null; if (!startInfo) return null;
var code = { var code = {
start: startInfo.start, start: startInfo.start,
@ -5854,7 +5854,7 @@
{ {
key: "decode", key: "decode",
value: function(row, start) { value: function(row, start) {
var result = Array(), decodedCodes = Array(), startInfo = this._findStart(); var result = [], decodedCodes = [], startInfo = this._findStart();
if (!startInfo) return null; if (!startInfo) return null;
decodedCodes.push(startInfo); decodedCodes.push(startInfo);
var endInfo = this._findEnd(); var endInfo = this._findEnd();

View File

@ -19888,7 +19888,7 @@
for(; a <= 279;)d[2 * a + 1] = 7, a++, l[7]++; for(; a <= 279;)d[2 * a + 1] = 7, a++, l[7]++;
for(; a <= 287;)d[2 * a + 1] = 8, a++, l[8]++; for(; a <= 287;)d[2 * a + 1] = 8, a++, l[8]++;
for(D(d, 287, l), a = 0; a < 30; a++)f[2 * a + 1] = 5, f[2 * a] = C(a, 5); for(D(d, 287, l), a = 0; a < 30; a++)f[2 * a + 1] = 5, f[2 * a] = C(a, 5);
n = new w(d, r, 257, 286, 15), o = new w(f, s, 0, 30, 15), p = new w(Array(0), u, 0, 19, 7); n = new w(d, r, 257, 286, 15), o = new w(f, s, 0, 30, 15), p = new w([], u, 0, 19, 7);
}(), M = !0), a.l_desc = new x(a.dyn_ltree, n), a.d_desc = new x(a.dyn_dtree, o), a.bl_desc = new x(a.bl_tree, p), a.bi_buf = 0, a.bi_valid = 0, E(a); }(), M = !0), a.l_desc = new x(a.dyn_ltree, n), a.d_desc = new x(a.dyn_dtree, o), a.bl_desc = new x(a.bl_tree, p), a.bi_buf = 0, a.bi_valid = 0, E(a);
}, b._tr_stored_block = l, b._tr_flush_block = function(a, j, h, g) { }, b._tr_stored_block = l, b._tr_flush_block = function(a, j, h, g) {
var b, c, k = 0; var b, c, k = 0;

View File

@ -1,5 +1,7 @@
console.log(Array()); console.log([]);
console.log(Array(0)); console.log([]);
console.log(Array(1)); console.log([
,
]);
console.log(Array(11)); console.log(Array(11));
console.log(Array(12)); console.log(Array(12));

View File

@ -1,5 +1,5 @@
function foo(x) { function foo(x) {
return x; return x;
} }
var o = new Object(); var o = {};
o.p = 1; o.p = 1;

View File

@ -1,4 +1,12 @@
const { a: a, b: c, d: d = new Object(1) } = { b: 7 }; const { a: a , b: c , d: d = Object(1) } = {
let { e: e, f: g, h: h = new Object(2) } = { e: 8 }; b: 7
var { w: w, x: y, z: z = new Object(3) } = { w: 4, x: 5, y: 6 }; };
let { e: e , f: g , h: h = Object(2) } = {
e: 8
};
var { w: w , x: y , z: z = Object(3) } = {
w: 4,
x: 5,
y: 6
};
console.log(c, e, z + 0); console.log(c, e, z + 0);

View File

@ -1,4 +1,12 @@
const { a: a, b: c, d: d = new Object(1) } = { b: 7 }; const { a: a , b: c , d: d = Object(1) } = {
let { e: e, f: g, h: h = new Object(2) } = { e: 8 }; b: 7
var { w: w, x: y, z: z = new Object(3) } = { w: 4, x: 5, y: 6 }; };
let { e: e , f: g , h: h = Object(2) } = {
e: 8
};
var { w: w , x: y , z: z = Object(3) } = {
w: 4,
x: 5,
y: 6
};
console.log(c, e, z + 0); console.log(c, e, z + 0);

View File

@ -1,4 +1,12 @@
const { a: a, b: c, d: d = new Object(1) } = { b: 7 }; const { a: a , b: c , d: d = Object(1) } = {
let { e: e, f: g, h: h = new Object(2) } = { e: 8 }; b: 7
var { w: w, x: y, z: z = new Object(3) } = { w: 4, x: 5, y: 6 }; };
let { e: e , f: g , h: h = Object(2) } = {
e: 8
};
var { w: w , x: y , z: z = Object(3) } = {
w: 4,
x: 5,
y: 6
};
console.log(c, e, z + 0); console.log(c, e, z + 0);

View File

@ -1,4 +1,12 @@
const { a: a, b: c, d: d = new Object(1) } = { b: 7 }; const { a: a , b: c , d: d = Object(1) } = {
let { e: e, h: h = new Object(2) } = { e: 8 }; b: 7
var { w: w, z: z = new Object(3) } = { w: 4, x: 5, y: 6 }; };
let { e: e , h: h = Object(2) } = {
e: 8
};
var { w: w , z: z = Object(3) } = {
w: 4,
x: 5,
y: 6
};
console.log(c, e, z + 0); console.log(c, e, z + 0);