ES6 new features: Destructuring and its application in actual projects
Introduction
Destructuring assignment syntax is a Javascript expression. Through destructuring assignment, attributes/values can be taken out of the object/array and assigned to other variables.
1. Deconstruction of objects
1. Basic assignment
var o = {
p: 42, q: true};
var {
p, q} = o;
console.log(p); // 42
console.log(q); // true
2. Assignment without declaration
A variable can be destructured and assigned independently of its declaration.
var a, b;
({
a, b} = {
a: 1, b: 2});
console.log(a); // 1
console.log(b); // 2
Notice:
- Parentheses (…) around assignment statements are required when using object literals for undeclared destructuring assignments.
{a, b} = {a: 1, b: 2} is not valid stand-alone syntax because {a, b} on the left is considered a block rather than an object literal. - Your (…) expression needs to be preceded by a semicolon, otherwise it may be executed as the function in the previous line.
- The variable names on the left and right sides of the statements need to correspond one to one.
3. Assign a value to the new variable name
You can extract variables from an object and assign them to new variable names that are different from the object's property names.
var o = {
p: 42, q: true};
var {
p: foo, q: bar} = o;
console.log(foo); // 42
console.log(bar); // true
Notice:
- There is no need to define foo and bar variables
4.Default value
Variables can be assigned default values first. When the object to be extracted does not have a corresponding attribute, the variable is assigned a default value.
var {
a = 10, b = 5} = {
a: 3};
console.log(a); // 3
console.log(b); // 5
5. Name the new variable and provide a default value
A property can be simultaneously 1) destructured from an object and assigned to a variable with a different name and 2) assigned a default value in case the undestructured value is undefined.
var {
a:aa = 10, b:bb = 5} = {
a: 3};
console.log(aa); // 3
console.log(bb); // 5
Notice:
- There is no need to define aa and bb variables
6. Object attribute calculation name and destructuring
Computed property names, such as object literals, can be destructured.
let key = “z”;
let { [key]: foo } = { z: “bar” };
console.log(foo); // “bar”
2. Destructuring of arrays
1.Basic usage
var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20
2. Both the left and right sides are variables
The right hand side can also be the return value of the function
// 例一
var a, b;
var c = [1, 2];
[a, b] = c;
console.log(a); // 1
console.log(b); // 2
// 例二
function f() {
return [1, 2];
}
var a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2
3.Default value
In order to prevent an object with a value of undefined from being taken out of the array, a default value can be preset for any object in the array on the left side of the expression.
var a, b;
[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7
4. Exchange variables
The values of two variables can be exchanged in a destructuring expression. Without destructuring assignment, exchanging two variables requires a temporary variable (or use the XOR-swap trick in low-level languages).
var a = 1;
var b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
5. Ignore certain return values
You can also ignore return values that you are not interested in:
function f() {
return [1, 2, 3];
}
var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3
You can also ignore all return values:
[,,] = f();
6. Assign the remaining array to a variable
When destructuring an array, you can use the remainder pattern to assign the remainder of the array to a variable.
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
Notice:
- If there is a comma to the right of the remaining element, a SyntaxError will be thrown because the remaining element must be the last element of the array.
var [a, ...b,] = [1, 2, 3];
// SyntaxError: rest element may not have a trailing comma
3. Destructuring in functions
1.Basic usage
function test({
size = 'big', cords = {
x: 0, y: 0 }, radius = 25} = {
})
{
console.log(size, cords, radius);
}
test({
cords: {
x: 18, y: 30 },
radius: 30
}); // big {x: 18, y: 30} 30
2. Usage in es6 arrow function
Arguments cannot be accessed in arrow functions, so how can the input parameters be obtained dynamically when they are uncertain? Characteristics of arrow functions☞Click here
var test = (...arg) => {
console.log(arg)
}
test(1,2,3) // [1, 2, 3]
4. Destructuring in strings
1. Get a single character of a character
var [a, b, c] = 'abcde';
console.log(a);//"a"
console.log(b);//"b"
console.log(c);//"c"
2. Get the string length
const {
length } = 'abcde';
console.log(length);// 5
5. Practical application of vue project
1. Object merging attributes and extracting variables
// vue监听不到object属性变化时
let tmp = {
a:"change"}
this.obj = Object.assign({
},this.obj, ...tmp)
// 提取接口返回result的值
let result = {
a: 'input', b: 'button'}
let {
a, b} = result
2. How to use import in actual projects
// dom.js
/* istanbul ignore next */
/*eslint-disable*/
import Vue from 'vue';
const isServer = Vue.prototype.$isServer;
const SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
const MOZ_HACK_REGEXP = /^moz([A-Z])/;
const ieVersion = isServer ? 0 : Number(document.documentMode);
/* istanbul ignore next */
const trim = function(string) {
return (string || '').replace(/^[\s\uFEFF]+|[\s\uFEFF]+$/g, '');
};
/* istanbul ignore next */
const camelCase = function(name) {
return name.replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
return offset ? letter.toUpperCase() : letter;
}).replace(MOZ_HACK_REGEXP, 'Moz$1');
};
/* istanbul ignore next */
export const on = (function() {
if (!isServer && document.addEventListener) {
return function(element, event, handler) {
if (element && event && handler) {
element.addEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event && handler) {
element.attachEvent('on' + event, handler);
}
};
}
})();
/* istanbul ignore next */
export const off = (function() {
if (!isServer && document.removeEventListener) {
return function(element, event, handler) {
if (element && event) {
element.removeEventListener(event, handler, false);
}
};
} else {
return function(element, event, handler) {
if (element && event) {
element.detachEvent('on' + event, handler);
}
};
}
})();
/* istanbul ignore next */
export const once = function(el, event, fn) {
var listener = function() {
if (fn) {
fn.apply(this, arguments);
}
off(el, event, listener);
};
on(el, event, listener);
};
/* istanbul ignore next */
export function hasClass(el, cls) {
if (!el || !cls) return false;
if (cls.indexOf(' ') !== -1) throw new Error('className should not contain space.');
if (el.classList) {
return el.classList.contains(cls);
} else {
return (' ' + el.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
};
/* istanbul ignore next */
export function addClass(el, cls) {
if (!el) return;
var curClass = el.className;
var classes = (cls || '').split(' ');
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.add(clsName);
} else if (!hasClass(el, clsName)) {
curClass += ' ' + clsName;
}
}
if (!el.classList) {
el.className = curClass;
}
};
/* istanbul ignore next */
export function removeClass(el, cls) {
if (!el || !cls) return;
var classes = cls.split(' ');
var curClass = ' ' + el.className + ' ';
for (var i = 0, j = classes.length; i < j; i++) {
var clsName = classes[i];
if (!clsName) continue;
if (el.classList) {
el.classList.remove(clsName);
} else if (hasClass(el, clsName)) {
curClass = curClass.replace(' ' + clsName + ' ', ' ');
}
}
if (!el.classList) {
el.className = trim(curClass);
}
};
/* istanbul ignore next */
export const getStyle = ieVersion < 9 ? function(element, styleName) {
if (isServer) return;
if (!element || !styleName) return null;
styleName = camelCase(styleName);
if (styleName === 'float') {
styleName = 'styleFloat';
}
try {
switch (styleName) {
case 'opacity':
try {
return element.filters.item('alpha').opacity / 100;
} catch (e) {
return 1.0;
}
default:
return (element.style[styleName] || element.currentStyle ? element.currentStyle[styleName] : null);
}
} catch (e) {
return element.style[styleName];
}
} : function(element, styleName) {
if (isServer) return;
if (!element || !styleName) return null;
styleName = camelCase(styleName);
if (styleName === 'float') {
styleName = 'cssFloat';
}
try {
var computed = document.defaultView.getComputedStyle(element, '');
return element.style[styleName] || computed ? computed[styleName] : null;
} catch (e) {
return element.style[styleName];
}
};
/* istanbul ignore next */
export function setStyle(element, styleName, value) {
if (!element || !styleName) return;
if (typeof styleName === 'object') {
for (var prop in styleName) {
if (styleName.hasOwnProperty(prop)) {
setStyle(element, prop, styleName[prop]);
}
}
} else {
styleName = camelCase(styleName);
if (styleName === 'opacity' && ieVersion < 9) {
element.style.filter = isNaN(value) ? '' : 'alpha(opacity=' + value * 100 + ')';
} else {
element.style[styleName] = value;
}
}
};
// 引用dom.js中的getStyle
import {
getStyle} from './dom.js'
Reference articles:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
https://github.com/lukehoban/es6features#destructuring