小知识随手记(十):多重重复解构对象、es6函数带默认参数时将生成声明作用域、一些注意点、动态设置getter/setter、mysql将字符串字段转为数字排序或比大小、pointer-events:none;属性
一、多次重复解构对象
es6居然可以重复解构对象。我们看代码
const obj = {
a: {
b: 1
},
c: 2
};
const { a: { b }, a, c } = obj;
console.log(b, a, c)
一行代码同时获取 a 和 a.b 和 c 。 在a和b都要多次用到的情况下,普通人的逻辑就是先解构出 a
,再在下一行解构出 b
。
接着继续看多重重复解构,nice,挺方便的。
这里有个需要注意的地方就是下面:
// 这种情况下,你把 name 和 age 从 part1 里解构出来了以后,你就无法使用变量 obj 中的 part1 属性了,如:
const { part1: { name, age } } = obj
console.log(part1) // Uncaught ReferenceError: part1 is not defined
// 所以就需要多次解构,如:
const { part1: { name, age }, part1 } = obj
console.log(part1) // 这样就可以取到 part1 了,{name: "零一", age: 23}
二、es6函数带默认参数时将生成声明作用域
我们直接看代码
var x = 10;
function fn(x = 2, y = function () { return x + 1 }) {
var x = 5;
return y();
}
fn(); // 3
改一下:
var x = 10;
function fn(a = 2, y = function () { return x + 1 }) {
var x = 5;
return y();
}
fn(); // 11
取的是最外层的x。那我们再改一下
var b = 10;
function fn(a = 2, y = function () { return x + 1 }) {
var x = 5;
return y();
}
fn(); // VM660:3 Uncaught ReferenceError: x is not defined
再改一下:
var x = 10;
function fn(x = 2, y = function (x) { return x + 1 }) {
var x = 5;
return y(x);
}
fn(); // 6
这样一测试,就比较清楚了。
三、一些注意点
1、parseInt
太小的数字会产生 bug
parseInt(0.00000000454); // 4
parseInt(10.23); // 10
parseInt(0.0000454); // 0
2、与null或undefined相加
1 + null // 1
1 + undefined // NaN
Number(null) // 0
Number(undefined) // NaN
3、arguments 和形参是别名关系,前提是arguments与传的实参一一对应
function test(a, b) {
console.log(a, b); // 2, 3
arguments[0] = 100;
arguments[1] = 200;
console.log(a, b); // 100, 200
}
test(2, 3);
但是如果不是一一对应的话,那么没对应的就没有关系。比如test(2),那么arguments[0]与参数a是别名关系,arguments[1]与参数b就没有关系了。
4、是否存在这样的变量 x
,使得它等于多个数字?
const x = {
value: 0,
toString() {
return ++this.value;
}
}
x == 1 && x == 2 && x == 3; // true
通过隐式转换,这样不是什么难的事情。关于隐式转换,直接看:
5、对象 ===
比较的是内存地址,而 >=
将比较转换后的值
{} === {} // false
// 隐式转换 toString()
{} >= {} // true
6、Function.prototype 是个函数类型。而自定义函数的原型却是对象类型。
typeof Function.prototype === 'function'; // true
function People() {}
typeof People.prototype === 'object'; // true
所以我们设置空函数可以这么做:
// Good
const noop = Function.prototype;
// Bad
const noop = () => {};
7、重复字符串 N 次
有时候出于某种目的需要将字符串重复 N 次,最笨的方法就是用for
循环拼接。其实更简单的方法是用repeat
:
var ss = 'test'
ss.repeat(5)
// "testtesttesttesttest"
8、简单指数运算
//longhand
Math.pow(2,3); // 8
//shorthand
2**3 // 8
四、getter/setter
也可以动态设置
class Hello {
_name = 'lucy';
getName() {
return this._name;
}
// 静态的getter
get id() {
return 1;
}
}
const hel = new Hello();
hel.name; // undefined
hel.getName(); // lucy
// 动态的getter
Hello.prototype.__defineGetter__('name', function() {
return this._name;
});
Hello.prototype.__defineSetter__('name', function(value) {
this._name = value;
});
hel.name; // lucy
hel.getName(); // lucy
hel.name = 'jimi';
hel.name; // jimi
hel.getName(); // jimi
五、mysql将字符串字段转为数字排序或比大小
mysql里面有个坑就是,有时按照某个字段的大小排序(或是比大小)发现排序有点错乱。后来才发现,是我们想当然地把对字符串字段当成数字并按照其大小排序(或是比大小),结果肯定不会是你想要的结果。
这时候需要把字符串转成数字再排序。最简单的办法就是在字段后面加上+0,如把'123'转成数字123:
// 1、排序:
方法一:ORDER BY '123'+0;(首推)
方法二:ORDER BY CAST('123' AS SIGNED);
方法三:ORDER BY CONVERT('123',SIGNED);
// 2、比大小:
SELECT '123'+0; -- 结果为123
SELECT '123'+0>127; -- 结果为0
SELECT '123'+0>12; -- 结果为1
SELECT CAST('123' AS SIGNED); -- 结果为123
SELECT CONVERT('123',SIGNED)>127; -- 结果为0
SELECT CONVERT('123',SIGNED)>12; -- 结果为1
六、浅谈CSS3有意思的属性:pointer-events:none;
1、pointer-events: none; 可以让某个元素实现类似于海市蜃楼的效果,具体理解为,你可以看的到某个元素,但是你无法摸的着。
可以用来取消某个元素上绑定的所有事件。
2、而display:none; 是你摸不着,也看不见。
3、pointer-events: none;摸不着,但是看得见。如果把某个元素再加上opacity:0;则可以很容易实现类似display:none;的效果(摸不着,看不见)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
2017-12-03 ES6中Set集合(与java里类似)