Heim  >  Artikel  >  Web-Frontend  >  Tipps in JS, die das Glück verbessern können

Tipps in JS, die das Glück verbessern können

coldplay.xixi
coldplay.xixinach vorne
2020-06-16 17:05:522915Durchsuche

Tipps in JS, die das Glück verbessern können

In diesem Artikel werden hauptsächlich einige in JS verwendete Tipps vorgestellt, die die Zufriedenheit beim täglichen Codieren verbessern können. ~

Interessierte Schüler können sich Let's anschließen Besprechen Sie gemeinsam in der WeChat-Gruppe am Ende des Artikels ~

1. Typ-Zwang

1.1 String-Zwang in Zahlen

kann mit *1 in Zahlen umgewandelt werden eigentlich ist es, die .valueOf-Methode aufzurufen) Verwenden Sie dann Number.isNaN, um festzustellen, ob es NaN ist, oder verwenden Sie a !== a, um festzustellen, ob es NaN ist, da NaN !== NaN

'32' * 1            // 32'ds' * 1            // NaNnull * 1            // 0undefined * 1    // NaN1  * { valueOf: ()=>'3' }        // 3复制代码

häufig verwendet wird: kann kann auch verwendet werden +Um eine Zeichenfolge in eine Zahl umzuwandeln

+ '123'            // 123+ 'ds'               // NaN+ ''                    // 0+ null              // 0+ undefined    // NaN+ { valueOf: ()=>'3' }    // 3复制代码

1.2-Objekt muss zwangsweise in eine Zeichenfolge umgewandelt werden

Sie können die 字符串+Object-Methode verwenden, um das Objekt in eine umzuwandeln string (eigentlich Aufruf der .toString()-Methode)

'the Math object:' + Math                // "the Math object:[object Math]"'the JSON object:' + JSON              // "the JSON object:[object JSON]"复制代码

Natürlich können Sie auch die Methoden toString und valueOf des Objekts überschreiben, um die Typkonvertierung des Objekts anzupassen:

2  * { valueOf: ()=>'3' }                // 6'J' + { toString: ()=>'S' }                // "JS"复制代码

《Effektives JavaScript》P11: Wenn + in der Verbindungszeichenfolge verwendet wird und ein Objekt sowohl die Methoden toString als auch valueOf hat, löst JS diese Mehrdeutigkeit, indem es blind die Methode valueOf verwendet. Das Objekt wird über die Methode valueOf in eine Zahl und über die Methode toString in eine Zeichenfolge umgewandelt

'' + {toString:()=>'S',valueOf:()=>'J'}                // J复制代码

1.3 Verwenden Sie Boolean, um alle falschen Werte im Array

Wir wissen, dass JS einige falsche Werte enthält:

, false, null, 0, "", undefined Wie kann man falsche Werte im Array schnell filtern? Sie können den Booleschen Konstruktor verwenden, um eine Konvertierung durchzuführen NaN

const compact = arr => arr.filter(Boolean)
compact([0, 1, false, 2, '', 3, 'a', 'e' * 23, NaN, 's', 34])             // [ 1, 2, 3, 'a', 's', 34 ]复制代码
1.4 Doppelbitoperator~~

kann einen Doppelbitoperator verwenden, um

für positive Zahlen und Math.floor( ) für negative Zahlen zu ersetzen Zahlen. Der Vorteil des doppelt negativen Positionierungsoperators besteht darin, dass er denselben Vorgang schneller ausführt. Math.ceil( )

Math.floor(4.9) === 4      //true// 简写为:~~4.9 === 4      //true复制代码
Bitte beachten Sie jedoch, dass für positive Zahlen das Ergebnis der

-Operation das gleiche ist wie das von ~~, und für negative Zahlen das Ergebnis der Operation von Math.floor( ) das gleiche ist: Math.ceil( )

~~4.5                // 4Math.floor(4.5)      // 4Math.ceil(4.5)       // 5~~-4.5        		// -4Math.floor(-4.5)     // -5Math.ceil(-4.5)      // -4复制代码
1.5 Kurzschlussoperator

Wir wissen, dass logisches UND

und logisches ODER && Kurzschlussoperatoren sind Anforderungen in der Operation von links nach rechts, letztere werden nicht mehr ausgeführt; Es kann wie folgt verstanden werden: ||

  • ist eine falsche Operation. Wenn ein falscher Wert auftritt, wird ein falscher Wert zurückgegeben und nicht erneut ausgeführt . Andernfalls wird der letzte wahre Wert zurückgegeben. &&
  • ist eine Wahrheitsoperation, die von links nach rechts beurteilt wird Andernfalls wird der letzte falsche Wert ||
let param1 = expr1 && expr2let param2 = expr1 || expr2复制代码
Wenn expr1 in „false“ konvertiert werden kann, geben Sie expr1 zurück, andernfalls geben Sie expr2 zurück. Daher wird bei Verwendung in einer booleschen Umgebung „true“ zurückgegeben, wenn beide Operationsergebnisse „true“ sind, andernfalls wird „false“ zurückgegeben.
Operator Example zurückgegeben. th> Erklärung
expr1&&expr2
|| expr1||expr2 td> Wenn expr1 in true konvertiert werden kann, wird expr1 zurückgegeben, andernfalls wird expr2 zurückgegeben, wenn es in einem booleschen Wert verwendet wird Umgebung (in der bedingten Beurteilung von if) wird true zurückgegeben, solange eines der beiden Operationsergebnisse wahr ist. Wenn beide Operationsergebnisse falsch sind, wird false zurückgegeben.
! !expr Wenn ein einzelner Ausdruck in „true“ konvertiert werden kann, geben Sie „false“ zurück, andernfalls geben Sie „true“ zurück.

因此可以用来做很多有意思的事,比如给变量赋初值:

let variable1let variable2 = variable1  || 'foo'复制代码

如果variable1是真值就直接返回了,后面短路就不会被返回了,如果为假值,则会返回后面的foo

也可以用来进行简单的判断,取代冗长的if语句:

let variable = param && param.prop复制代码

如果param如果为真值则返回param.prop属性,否则返回param这个假值,这样在某些地方防止paramundefined的时候还取其属性造成报错。

1.6 取整 | 0

对一个数字| 0可以取整,负数也同样适用,num | 0

1.3 | 0         // 1-1.9 | 0        // -1复制代码

1.7 判断奇偶数 & 1

对一个数字& 1可以判断奇偶数,负数也同样适用,num & 1

const num=3;
!!(num & 1)                    // true!!(num % 2)                    // true复制代码

2. 函数

2.1 函数默认值

func = (l, m = 3, n = 4 ) => (l * m * n);
func(2)             //output: 24复制代码

注意,传入参数为undefined或者不传入的时候会使用默认参数,但是传入null还是会覆盖默认参数。

2.2 强制参数

默认情况下,如果不向函数参数传值,那么JS 会将函数参数设置为undefined。其它一些语言则会发出警告或错误。要执行参数分配,可以使用if语句抛出未定义的错误,或者可以利用强制参数

mandatory = ( ) => {  throw new Error('Missing parameter!');
}
foo = (bar = mandatory( )) => {     // 这里如果不传入参数,就会执行manadatory函数报出错误
  return bar;
}复制代码

2.3 隐式返回值

返回值是我们通常用来返回函数最终结果的关键字。只有一个语句的箭头函数,可以隐式返回结果(函数必须省略大括号{ },以便省略返回关键字)。

要返回多行语句(例如对象文本),需要使用( )而不是{ }来包裹函数体。这样可以确保代码以单个语句的形式进行求值。

function calcCircumference(diameter) {  return Math.PI * diameter
}// 简写为:calcCircumference = diameter => (  Math.PI * diameter;
)复制代码

2.4 惰性载入函数

在某个场景下我们的函数中有判断语句,这个判断依据在整个项目运行期间一般不会变化,所以判断分支在整个项目运行期间只会运行某个特定分支,那么就可以考虑惰性载入函数

function foo(){    if(a !== b){        console.log('aaa')
    }else{        console.log('bbb')
    }
} 
// 优化后function foo(){    if(a != b){
        foo = function(){            console.log('aaa')
        }
    }else{
        foo = function(){            console.log('bbb')
        }
    }    return foo();
}复制代码

那么第一次运行之后就会覆写这个方法,下一次再运行的时候就不会执行判断了。当然现在只有一个判断,如果判断很多,分支比较复杂,那么节约的资源还是可观的。

2.5 一次性函数

跟上面的惰性载入函数同理,可以在函数体里覆写当前函数,那么可以创建一个一次性的函数,重新赋值之前的代码相当于只运行了一次,适用于运行一些只需要执行一次的初始化代码

var sca = function() {    console.log('msg')
    sca = function() {        console.log('foo')
    }
}
sca()        // msgsca()        // foosca()        // foo复制代码

3. 字符串

3.1 字符串比较时间先后

比较时间先后顺序可以使用字符串:

var a = "2014-08-08";var b = "2014-09-09"; 
console.log(a>b, a<b); // false trueconsole.log("21:00"<"09:10");  // falseconsole.log("21:00"<"9:10");   // true   时间形式注意补0复制代码

因为字符串比较大小是按照字符串从左到右每个字符的charCode来的,但所以特别要注意时间形式注意补0

4. 数字

4.1 不同进制表示法

ES6中新增了不同进制的书写格式,在后台传参的时候要注意这一点。

29            // 10进制035            // 8进制29      原来的方式0o35            // 8进制29      ES6的方式0x1d            // 16进制290b11101            // 2进制29复制代码

4.2 精确到指定位数的小数

将数字四舍五入到指定的小数位数。使用 Math.round() 和模板字面量将数字四舍五入为指定的小数位数。 省略第二个参数 decimals ,数字将被四舍五入到一个整数。

const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`)
round(1.345, 2)                 // 1.35round(1.345, 1)                 // 1.3复制代码

4.3 数字补0操作

感谢网友 @JserWang @vczhan 提供 这个小技巧 有时候比如显示时间的时候有时候会需要把一位数字显示成两位,这时候就需要补0操作,可以使用slice和string的padStart方法

const addZero1 = (num, len = 2) => (`0${num}`).slice(-len)const addZero2 = (num, len = 2) => (`${num}`).padStart( len   , '0')
addZero1(3) // 03
 addZero2(32,4)  // 0032复制代码

5. 数组

5.1 reduce方法同时实现map和filter

假设现在有一个数列,你希望更新它的每一项(map的功能)然后筛选出一部分(filter的功能)。如果是先使用map然后filter的话,你需要遍历这个数组两次。 在下面的代码中,我们将数列中的值翻倍,然后挑选出那些大于50的数。

const numbers = [10, 20, 30, 40];const doubledOver50 = numbers.reduce((finalList, num) => {
  num = num * 2;  if (num > 50) {
    finalList.push(num);
  }  return finalList;
}, []);
doubledOver50;            // [60, 80]复制代码

5.2 统计数组中相同项的个数

很多时候,你希望统计数组中重复出现项的个数然后用一个对象表示。那么你可以使用reduce方法处理这个数组。

下面的代码将统计每一种车的数目然后把总数用一个对象表示。

var cars = ['BMW','Benz', 'Benz', 'Tesla', 'BMW', 'Toyota'];var carsObj = cars.reduce(function (obj, name) {
  obj[name] = obj[name] ? ++obj[name] : 1;  return obj;
}, {});
carsObj; // => { BMW: 2, Benz: 2, Tesla: 1, Toyota: 1 }复制代码

5.3 使用解构来交换参数数值

有时候你会将函数返回的多个值放在一个数组里。我们可以使用数组解构来获取其中每一个值。

let param1 = 1;let param2 = 2;
[param1, param2] = [param2, param1];console.log(param1) // 2console.log(param2) // 1复制代码

当然我们关于交换数值有不少其他办法:

var temp = a; a = b; b = temp            
b = [a, a = b][0]                     
a = a + b; b = a - b; a = a - b        
复制代码

5.4 接收函数返回的多个结果

在下面的代码中,我们从/post中获取一个帖子,然后在/comments中获取相关评论。由于我们使用的是async/await,函数把返回值放在一个数组中。而我们使用数组解构后就可以把返回值直接赋给相应的变量。

async function getFullPost(){  return await Promise.all([
     fetch('/post'),
     fetch('/comments')
  ]);
}const [post, comments] = getFullPost();复制代码

5.5 将数组平铺到指定深度

使用递归,为每个深度级别 depth 递减 1 。 使用 Array.reduce()Array.concat() 来合并元素或数组。 基本情况下,depth 等于 1 停止递归。 省略第二个参数,depth 只能平铺到 1 (单层平铺) 的深度。

const flatten = (arr, depth = 1) =>
  depth != 1
    ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), [])
    : arr.reduce((a, v) => a.concat(v), []);
flatten([1, [2], 3, 4]);                             // [1, 2, 3, 4]flatten([1, [2, [3, [4, 5], 6], 7], 8], 2);           // [1, 2, 3, [4, 5], 6, 7, 8]复制代码

5.6 数组的对象解构

数组也可以对象解构,可以方便的获取数组的第n个值

const csvFileLine = '1997,John Doe,US,john@doe.com,New York';const { 2: country, 4: state } = csvFileLine.split(',');
 
country            // USstate            // New Yourk复制代码

6. 对象

6.1 使用解构删除不必要属性

有时候你不希望保留某些对象属性,也许是因为它们包含敏感信息或仅仅是太大了(just too big)。你可能会枚举整个对象然后删除它们,但实际上只需要简单的将这些无用属性赋值给变量,然后把想要保留的有用部分作为剩余参数就可以了。

下面的代码里,我们希望删除_internal和tooBig参数。我们可以把它们赋值给internal和tooBig变量,然后在cleanObject中存储剩下的属性以备后用。

let {_internal, tooBig, ...cleanObject} = {el1: '1', _internal:"secret", tooBig:{}, el2: '2', el3: '3'}; 
console.log(cleanObject);                         // {el1: '1', el2: '2', el3: '3'}复制代码

6.2 在函数参数中解构嵌套对象

在下面的代码中,engine是对象car中嵌套的一个对象。如果我们对engine的vin属性感兴趣,使用解构赋值可以很轻松地得到它。

var car = {  model: 'bmw 2018',  engine: {    v6: true,    turbo: true,    vin: 12345
  }
}const modelAndVIN = ({model, engine: {vin}}) => {  console.log(`model: ${model} vin: ${vin}`);
}
modelAndVIN(car); // => model: bmw 2018  vin: 12345复制代码

7. 代码复用

7.1 Object [key]

虽然将 foo.bar 写成 foo ['bar'] 是一种常见的做法,但是这种做法构成了编写可重用代码的基础。许多框架使用了这种方法,比如element的表单验证。

请考虑下面这个验证函数的简化示例:

function validate(values) {  if(!values.first)    return false;  if(!values.last)    return false;  return true;
}console.log(validate({first:'Bruce',last:'Wayne'})); // true复制代码

上面的函数完美的完成验证工作。但是当有很多表单,则需要应用验证,此时会有不同的字段和规则。如果可以构建一个在运行时配置的通用验证函数,会是一个好选择。

// object validation rulesconst schema = {  first: {    required:true
  },  last: {    required:true
  }
} 
// universal validation functionconst validate = (schema, values) => {  for(field in schema) {    if(schema[field].required) {      if(!values[field]) {        return false;
      }
    }
  }  return true;
}console.log(validate(schema, {first:'Bruce'})); // falseconsole.log(validate(schema, {first:'Bruce',last:'Wayne'})); // true复制代码

现在有了这个验证函数,我们就可以在所有窗体中重用,而无需为每个窗体编写自定义验证函数。


  1. 添加热心网友 @JserWang @vczhan 提供的 数字补0操作
  2. 添加3.1,字符串比较时间先后
  3. 感谢网友 @Pandaaa 提醒,~~ 在负数时表现与 Math.ceil( ) 相同

网上的帖子大多深浅不一,甚至有些前后矛盾,在下的文章都是学习过程中的总结,如果发现错误,欢迎留言指出~

参考:

  1. JavaScript 开发人员需要知道的简写技巧
  2. 《Effective Javascript》
  3. 不得不知的ES6小技巧
  4. js运算符的一些特殊应用
  5. JS高级技巧(简洁版)
  6. 小议 js 下字符串比较大小

推荐教程:《javascript基础教程

Das obige ist der detaillierte Inhalt vonTipps in JS, die das Glück verbessern können. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen