JaveScript的奇葩写法规则
① => 箭头函数
两个箭头同时使用 arg1 => arg2 =>{return xxx;}
可以理解为
function( arg1 )
{
return function(arg2)
{
return xxx;
}
}
也就是可以是 (arg1,arg2)=>{return xxx;}的简写
也就是function( arg1, arg2 ){ return xxx; }的意思
===
② … 剩余数据
数组中的剩余数据
[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]
对象中的剩余数据
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}
③ [] 数组分配赋值用法
数组分配1
var x = [1, 2, 3, 4, 5];
var [y, z] = x;
console.log(y); // 1
console.log(z); // 2
数组分配2
var foo = ['one', 'two', 'three'];
var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
数组赋值默认值用法
var a, b;
[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7
用数组做变量置换
var a = 1;
var b = 3;
[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
省略赋值用法
var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]
④ {} 对象分配用法
对象分配赋值
var o = {p: 42, q: true};
var {p, q} = o;
console.log(p); // 42
console.log(q); // true
默认值用法
var {a = 10, b = 5} = {a: 3};
console.log(a); // 3
console.log(b); // 5
指定key赋值+默认值
var {a:aa = 10, b:bb = 5} = {a: 3};
console.log(aa); // 3
console.log(bb); // 5
指定属性key解析赋值
let key = 'z';
let {[key]: foo} = {z: 'bar'};
console.log(foo); // "bar"
对象中剩余赋值法
let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }
弱变量定义与赋值
const foo = { 'fizz-buzz': true };
const { 'fizz-buzz': fizzBuzz } = foo;
console.log(fizzBuzz); // "true"
⑤ Object.assign() 合并对象
将源对象( source )的所有可枚举属性,复制到目标对象( target )
var target = { a: 1 };
var source1 = { b: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
var target = { a: 1, b: 1 };
var source1 = { b: 2, c: 2 };
var source2 = { c: 3 };
Object.assign(target, source1, source2);
target // {a:1, b:2, c:3}
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
var obj1 = {a: {b: 1}};
var obj2 = Object.assign({}, obj1);
obj1.a.b = 2;
obj2.a.b // 2
对于这种嵌套的对象,一旦遇到同名属性,Object.assign的处理方法是替换,而不是添加。
var target = { a: { b: 'c', d: 'e' } }
var source = { a: { b: 'hello' } }
Object.assign(target, source)
// { a: { b: 'hello' } }
Object.assign 常见用途
为对象添加属性
class Point {
constructor(x, y) {
Object.assign(this, {x, y});
}
}
为对象添加方法
Object.assign(SomeClass.prototype, {
someMethod(arg1, arg2) {
···
},
anotherMethod() {
···
}
});
// 等同于下面的写法
SomeClass.prototype.someMethod = function (arg1, arg2) {
···
};
SomeClass.prototype.anotherMethod = function () {
···
};
克隆对象
function clone(origin) {
return Object.assign({}, origin);
}
合并多个对象
const merge =(target, ...sources) => Object.assign(target, ...sources);
为属性指定默认值
const DEFAULTS = {
logLevel: 0,
outputFormat: 'html'
};
function processContent(options) {
let options = Object.assign({}, DEFAULTS, options);
}
⑥ (function(){})(); 函数function后面跟()括号
举个例子:
(function(p1,p2){alert(p1+p2);})(1,2);
实际就相当与
function test(p1,p2){
alert(p1+p2);
};
test(1,2);
这种写法可以看做是私有的内部类,一般出于加载时就需要立即执行的代码可以这样来些,第2个就是避免与其它的名称相冲突.
匿名方法的好处,上面也有提到.
1.其它外部调用不到,相对安全.
2.可用于onload事件保证不与其冲突.
3.可看做线程安全.
⑦ !function(){}(); 函数function前面加!感叹号
如果我们尝试为一个“定义函数”末尾加上(),解析器是无法理解的。
function msg(){
alert('message');
}();//解析器是无法理解的
原来,使用括号包裹定义函数体,解析器将会以函数表达式的方式去调用定义函数。也就是说,任何能将函数变成一个函数表达式的作法,都可以使解析器正确的调用定义函数。而 ! 就是其中一个,而 + - || 都有这样的功能。
其实就是为了能省略一个字符……
// 这么写会报错,因为这是一个函数定义:
function(){}()
// 常见的(多了一对括号),调用匿名函数:
(function() {})()
// 但在前面加上一个布尔运算符(只多了一个感叹号),就是表达式了,将执行后面的代码,也就合法实现调用
!function() {}()
感谢您的耐心阅读
Thanks for your reading
版权申明
本文为博主原创文章,未经允许不得转载:
Copyright attention
Please don't reprint without authorize.
微信公众号,文章同步推送,致力于分享一个资深程序员在北上广深拼搏中对世界的理解
QQ交流群: 777859752 (高级程序书友会)