小知识随手记(十):多重重复解构对象、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;的效果(摸不着,看不见)。

posted @ 2020-12-03 16:59  古兰精  阅读(390)  评论(0编辑  收藏  举报