js のヒントを共有する

小云云
リリース: 2023-03-21 19:42:01
オリジナル
1567 人が閲覧しました

この記事では主に js のヒントを紹介します。記事は少し長いですが、お役に立てれば幸いです。

1. JavaScript フォールトトレラント処理コード (js エラーのシールド)

<span style="font-size: 14px;"><script language="javascript"><br>    <!--    /*屏蔽所有的js错误*/<br/>    function killerrors() {<br/>        return true;<br/>    }<br/>    window.onerror = killerrors;    //--></script><br></span>
ログイン後にコピー

プログラミング スキルを向上させるために、これらの短くて実践的な JavaScript スキルを提供できることは、私にとって非常に嬉しいことです。 1 日 2 分以内で、このひどい JavaScript 言語が私たちに提供する機能、つまりパフォーマンス (パフォーマンス)、規約 (プロトコル)、ハッキング (コード ハック)、面接の質問 (インタビューの質問) を読むことができるようになります。 ) およびその他すべての項目。

2. 比較する場合、==

== (または !=) の代わりに === を使用します。比較される 2 つのオブジェクトは同じ型に変換されて比較されます。 === (または !==) は、比較される 2 つの型と値を比較しません。== と比較して、=== の比較はより厳密になります。 [10] == 10 // true
[10] === 10 // false
“10” == 10 // true
“10” === 10 // false
[] == 0 // true
[] === 0 // false
"" == false // true でも true == "a" は false
"" === false // false

3.もっと便利 文字列を数値に変換するメソッド

は非常に一般的です。これを行う最も簡単かつ最速の (jspref) 方法は、+ (プラス) アルゴリズムを使用することです。

var one = ‘1’; varnumberOne = +one; // Number 1

アルゴリズムの - (マイナス記号) 変換タイプを使用して、負の値に変換することもできます。

var one = ‘1’; var negativeNumberOne = -one; // Number -1

4 - 配列をクリアします

配列を定義し、その内容をクリアしたいとします。通常、これを実行します:

var list = [1, 2, 3, 4]; 
function empty() { 
//清空数组 
list = []; 
} 
empty();
但是还有一种更高性能的方法。
你可以使用这些代码: 
var list = [1, 2, 3, 4]; 
function empty() { 
//清空数组 
list.length = 0; 
} 
empty();
· list =[] 将一个变量指定个引用到那个数组,而其他引用都不受影响。这意味着,对于先前数组的内容的引用仍然保留在内存中,从而导致内存泄漏。 
· list.length = 0 删除数组内的所有东西,这不需要引用任何其他的东西 
然而,如果你有一个copy的数组(A和copy-A),如果你使用list.length = 0 删除其内容,副本也会失去它的内容。 
var foo = [1,2,3]; 
var bar = [1,2,3]; 
var foo2 = foo; 
var bar2 = bar; 
foo = []; 
bar.length = 0; 
console.log(foo, bar, foo2, bar2); 
//[] [] [1, 2, 3] []
ログイン後にコピー

StackOverflow の詳細:Difference-between-array-length-0-and-array

5 - 配列の並べ替えを "シャッフル" (ランダムに並べ替え) します

このコードは、Fisher Yates シャッフル アルゴリズムを使用して、指定された配列をシャッフル (ランダムに並べ替え) します。

function shuffle(arr) { 
var i, 
j, 
temp; 
for (i = arr.length - 1; i > 0; i–) { 
j = Math.floor(Math.random() * (i + 1)); 
temp = arr[i]; 
arr[i] = arr[j]; 
arr[j] = temp; 
} 
return arr;  
};
ログイン後にコピー


ケース: ?
1
2
3
4

var a = [1, 2, 3, 4, 5, 6, 7, 8]; var b = shuffle(a);
console.log(b);
// [2, 7, 8, 6, 5, 3, 1, 4]

6 - オブジェクトを返す関数は連鎖可能です

オブジェクト指向 JavaScript オブジェクトの関数を作成する場合、関数からオブジェクトを返すと、関数を実行のために連鎖させることができます。

function Person(name) { 
this.name = name; 
this.sayName = function() { 
console.log(“Hello my name is: “, this.name); 
return this; 
}; 
this.changeName = function(name) { 
this.name = name; 
return this; 
}; 
} 
var person = new Person(“John”); 
person.sayName().changeName(“Timmy”).sayName(); 
//Hello my name is: John 
//Hello my name is: Timmy
ログイン後にコピー


7 - 文字列安全な連結

未知の型の変数がいくつかあり、それらを連結したいとします。確かに、連結時にはアルゴリズム演算は適用されません:

var one = 1; var two = '3';
var result = ”.concat(one, two, three); //"123"

このような連結は、予期しない結果を招く可能性があります:

var one = 1;

var three = '3'; var result = one + two + three; //「123」ではなく「33」


パフォーマンスについて言えば、join と concat の実行速度はほぼ同じです。 MDN での concat

8 - より高速な丸め

二重チルダ「~~」演算子を見たことがありますか? これは、数学の高速な代替として使用することもできます。理由は何ですか?

入力は 32 ビット - (入力 + 1) に変換されます。これは、0 に近づくための優れたツールです。負の値の場合は Math.ceil() を、正の値の場合は Math.floor() を模倣します。実行が失敗した場合は 0 を返します。失敗した場合に NaN を返す Math.floor() の代わりに使用すると便利です

// 单位移 
console.log(~1337) // -1338 
// 双位移 
console.log(
47.11) // -> 47 
console.log(
-12.88) // -> -12 
console.log(
1.9999) // -> 1 
console.log(~~3) // -> 3 
//失败的情况 
console.log(
[]) // -> 0  
console.log(
NaN) // -> 0 
console.log(~~null) // -> 0 
//大于32位整数则失败 
console.log(
(2147483647 + 1) === (2147483647 + 1)) // -> 0
ログイン後にコピー


ただし、~~ の方がパフォーマンスが優れている可能性がありますが、読みやすさを考慮して、Math.floor() を使用してください。

9 - Node.js:让module在没被require的时候运行

在node里,你可以根据代是运行了require(‘./something.js’)还是node something.js,来告诉你的程序去做两件不同的事情。如果你想与你的一个独立的模块进行交互,这是很有用的。

if (!module.parent) { 
// 运行 
node something.js
 
app.listen(8088, function() { 
console.log(‘app listening on port 8088’); 
}) 
} else { 
// 使用 
require('/.something.js')
 
module.exports = app; 
}
ログイン後にコピー


更多信息,请看the documentation for modules

10 - 给回调函数传递参数

在默认情况下,你无法将参数传给回调函数,如下:

function callback() { 
console.log(‘Hi human’); 
} 
document.getElementById(‘someelem’).addEventListener(‘click’, callback);
你可以采取JavaScript闭包的优点来给回调函数传参,案例如下:
function callback(a, b) { 
return function() { 
console.log(‘sum = ‘, (a+b)); 
} 
} 
var x = 1, y = 2; 
document.getElementById(‘someelem’).addEventListener(‘click’, callback(x, y));
ログイン後にコピー

什么是闭包呢?闭包是指一个针对独立的(自由)变量的函数。换句话说,闭包中定义的函数会记住它被创建的环境。了解更多请参阅MDN所以这种方式当被调用的时候,参数X/Y存在于回调函数的作用域内。

另一种方法是使用绑定方法。例如:

var alertText = function(text) { 
alert(text); 
}; 
document.getElementById(‘someelem’).addEventListener(‘click’, alertText.bind(this, ‘hello’));
ログイン後にコピー


两种方法在性能上有一些略微区别,详情参阅jsperf

11 - 使用更简单的类似indexOf的包含判断方式

原生的JavaScript没有contains方法。对检查字符串或字符串数组项中是否存在某值,你可以这样做:

var someText = ‘JavaScript rules’; 
if (someText.indexOf(‘JavaScript’) !== -1) { 
} 
// 或者 
if (someText.indexOf(‘JavaScript’) >= 0) { 
}
ログイン後にコピー


但是我们再看看这些ExpressJs代码片段。

// examples/mvc/lib/boot.js 
for (var key in obj) { 
// “reserved” exports 
if (~[‘name’, ‘prefix’, ‘engine’, ‘before’].indexOf(key)) continue;
// examples/lib/utils.js
exports.normalizeType = function(type){
return ~type.indexOf(‘/’)
? acceptParams(type)
{ value: mime.lookup(type), params: {} }; 
};
// examples/web-service/index.js 
// key is invalid 
if (!~apiKeys.indexOf(key)) return next(error(401, ‘invalid api key’));
ログイン後にコピー

问题是~位运算符。”运算符执行操作这样的二进制表达式,但他们返回标准的JavaScript的数值.”
他们将-1转换为0,而0在JavaScript中又是false。

var someText = ‘text’; 
!!~someText.indexOf(‘tex’); // someText 包含 “tex” - true 
!~someText.indexOf(‘tex’); // someText 不包含 “tex” - false 
~someText.indexOf(‘asd’); // someText 不包含 “asd” - false 
~someText.indexOf(‘ext’); // someText 包含 “ext” - true 
String.prototype.includes()
ログイン後にコピー


在ES6(ES 2015)中介绍了includes()方法可以用来确定是否一个字符串包含另一个字符串:

‘something’.includes(‘thing’); // true

在ECMAScript 2016 (ES7)中,甚至数组都可以这样操作,如indexOf:

!!~[1, 2, 3].indexOf(1); // true
[1, 2, 3].includes(1); // true

不幸的是,这只是在Chrome,Firefox,Safari 9或以上的浏览器中被支持。

12 - arrow 函数(ES6)

介绍下ES6里的新功能,arrow函数可能会是个很方便的工具,用更少行数写更多代码。他的名字来源于他的语法,=>和小箭头->比就像一个“胖胖的箭头”。可能有些人知道,这种函数类型和其他静态语言如lambda表达式的匿名函数。它被称为匿名,因为这些箭头函数没有一个描述性的函数名。
那么这样有什么好处呢?

语法:更少的LOC,不用一次次的键入函数关键字。

语义:从上下文中捕捉关键字this。

简单语法案例:

看看下面的两段代码片段,他们做的是一样的工作。你能很快的理解arrow函数的功能。

// arrow函数的日常语法 param => expression // 可能也会写在括号中 // 括号是多参数要求 (param1 [, param2]) => expression
// 使用日常函数 var arr = [5,3,2,9,1]; var arrFunc = arr.map(function(x) { return x * x; }); console.log(arr)
// 使用arrow函数 var arr = [5,3,2,9,1]; var arrFunc = arr.map((x) => x*x); console.log(arr)
ログイン後にコピー


正如你所看到的,这个例子中的arrow函数可以节省你输入括号内参数和返回关键字的时间。建议把圆括号内的参数输入,如 (x,y) => x+y 。在不同的使用情况下,它只是

用来应对遗忘的一种方式。但是上面的代码也会这样执行:x => x*x.目前看来,这些仅仅是导致更少的LOC和更好的可读性的句法改进。

this 绑定

还有一个更好的理由使用arrow函数。那就是在会出现this问题的背景下。使用arrow函数,你就不用担心.bind(this)和 that=this 了。因为arrow函数会从上下文中找到this。

看下面的例子:

// 全局定义this.i 
this.i = 100; 
var counterA = new CounterA(); 
var counterB = new CounterB(); 
var counterC = new CounterC(); 
var counterD = new CounterD();
// 不好的示例 
function CounterA() { 
// CounterA’s this 实例 (!! 忽略这里) 
this.i = 0; 
setInterval(function () { 
// this 指全局对象,而不是 CounterA’s this 
// 因此,开始计数与100,而不是0 (本地的 this.i) 
this.i++; 
document.getElementById(“counterA”).innerHTML = this.i; 
}, 500); 
} 
// 手动绑定 that = this 
function CounterB() { 
this.i = 0; 
var that = this; 
setInterval(function() { 
that.i++; 
document.getElementById(“counterB”).innerHTML = that.i; 
}, 500); 
} 
// 使用 .bind(this) 
function CounterC() { 
this.i = 0; 
setInterval(function() { 
this.i++; 
document.getElementById(“counterC”).innerHTML = this.i; 
}.bind(this), 500); 
} 
// 使用 arrow函数 
function CounterD() { 
this.i = 0; 
setInterval(() => { 
this.i++; 
document.getElementById(“counterD”).innerHTML = this.i; 
}, 500); 
}
ログイン後にコピー

关于arrow函数的进一步信息可以看这里 。查看不同的语法选请访问该站点。

13 - 测量一个JavaScript代码块性能的技巧

快速测量一个JavaScript块的性能,我们可以使用控制台的功能像console.time(label)和console.timeEnd(label)

console.time(“Array initialize”); 
var arr = new Array(100), 
len = arr.length, 
i; 
for (i = 0; i < len; i++) { 
arr[i] = new Object(); 
}; 
console.timeEnd(“Array initialize”); // 输出: Array initialize: 0.711ms
ログイン後にコピー


更多信息Console object, JavaScript benchmarking

demo:jsfiddle-codepen (在浏览器控制台输出)

14 - ES6中参数处理

在许多编程语言中,函数的参数是默认的,而开发人员必须显式定义一个参数是可选的。在JavaScript中的每个参数是可选的,但我们可以这一行为而不让一个函数利用ES6的默认值作为参数。

const _err = function( message ){
throw new Error( message );
}
const getSum = (a = _err(‘a is not defined’), b = _err(‘b is not defined’)) => a + b
getSum( 10 ) // throws Error, b is not defined
getSum( undefined, 10 ) // throws Error, a is not defined

_err是立即抛出一个错误的函数。如果没有一个参数作为值,默认值是会被使用,_err将被调用,将抛出错误。你可以在Mozilla开发者网络看到的更多默认参数的例子。

15 - 提升

理解提升将帮助你组织你的function。只需要记住,变量声明和定义函数会被提升到顶部。变量的定义是不会的,即使你在同一行中声明和定义一个变量。此外,变量声明让系统知道变量存在,而定义是将其赋值给它。

function doTheThing() { 
// 错误: notDeclared is not defined 
console.log(notDeclared); 
// 输出: undefined 
console.log(definedLater); 
var definedLater; 
definedLater = ‘I am defined!’ 
// 输出: ‘I am defined!’ 
console.log(definedLater) 
// Outputs: undefined 
console.log(definedSimulateneously); 
var definedSimulateneously = ‘I am defined!’ 
// 输出: ‘I am defined!’ 
console.log(definedSimulateneously) 
// 输出: ‘I did it!’ 
doSomethingElse(); 
function doSomethingElse(){ 
console.log(‘I did it!’); 
} 
// 错误: undefined is not a function 
functionVar(); 
var functionVar = function(){ 
console.log(‘I did it!’); 
} 
}
ログイン後にコピー


为了使事情更容易阅读,在函数作用域内提升变量的声明将会让你明确该变量的声明是来自哪个作用域。在你需要使用变量之前定义它们。在作用域底部定义函数,确保代码清晰规范。

16 - 检查一个对象是否有属性

当你要检查一个对象是否存在某个属性时,你可能会这样做 :

var myObject = {
name: ‘@tips_js’
};
if (myObject.name) { … }

这是可以的,但你必须知道这个还有两原生的方式,in operator 和 object.hasownproperty,每个对象是对象,既可用方法。每个object都继承自Object,这两个方法都可用。

两个方法的一些不同点:

var myObject = {
name: ‘@tips_js’
};
myObject.hasOwnProperty(‘name’); // true
‘name’ in myObject; // true
myObject.hasOwnProperty(‘valueOf’); // false, valueOf 是从原型链继承的
‘valueOf’ in myObject; // true

他们之间的不同在于检查的性质,换句话说,当该对象本身有查找的属性时hasOwnProperty返回yrue,然而,in operator不区分属性创建的对象和属性继承的原型链。
这里有另外一个例子:

var myFunc = function() { <br>this.name = ‘@tips_js’;
};
myFunc.prototype.age = ‘10 days’;
var user = new myFunc();
user.hasOwnProperty(‘name’); // true
user.hasOwnProperty(‘age’); // false, 因为age是原型链上的

点击看例子。同时,建议在检查对象的属性存在时,阅读这些有关的常见错误。

17 - 模板字符串

截至ES6,JS已经有模板字符串作为替代经典的结束引用的字符串。
案例:普通字符串

var firstName = ‘Jake’;
var lastName = ‘Rawr’;
console.log(‘My name is ’ + firstName + ’ ’ + lastName);
// My name is Jake Rawr  
模板字符串:
var firstName = ‘Jake’;
var lastName = ‘Rawr’;
console.log(
<span style="font-size: 14px;">My name is ${firstName} ${lastName}</span>);
// My name is Jake Rawr

在模板字符串中${}中,你可以写不用写/n或者简单逻辑来实现多行字符串。
您还可以使用函数来修改模板字符串的输出,它们被称为模板字符串的标记。你可能还想读到更多的理解模板字符串相关信息。

18- ノードリストを配列に変換する

querySelectorAll メソッドは、配列に似たノードリストオブジェクトを返します。これらのデータ構造は、配列の形式で現れることが多いため配列に似ていますが、map や foreach などの配列メソッドは使用できません。これは、ノードリストを DOM 要素の配列に変換するための高速かつ安全で再利用可能な方法です。 /later on .. nodelistToArray.forEach(…);

nodelistToArray.slice(…);

//etc…


applyメソッドは一連のパラメータを配列形式に変換しますこれが与えられた場合は関数に渡されます。 MDN は、apply が配列のようなオブジェクトを呼び出し、それが querySelectorAll が返すものであると指摘しています。関数のコンテキストでこれを指定する必要がないため、null または 0 を渡します。返される結果は、配列メソッドを使用して使用できる DOM 要素の配列です。


es2015 を使用している場合は、...(spread 演算子) を使用できます

const nodelist = […document.querySelectorAll('p')] // 返されるのは実数の配列です

/ /後で

nodelist.forEach(…); nodelist.slice(…);

厳密モード JavaScript 開発者がより安全に JavaScript を記述できるようにします。
デフォルトでは、JavaScript では開発者が怠惰になる可能性があります。たとえば、初めて変数を宣言するときに var を使用することは、経験の浅い開発者のように見えるかもしれませんが、これは変数名のスペルミスの原因でもあります。誤ってまたは偶然に外部スコープに言及されました。



プログラマは、コンピュータに退屈な作業をさせたり、作業中のエラーをチェックしたりすることを好みます。 「use strict」は、これを実行してエラーを JavaScript エラーに変換するように指示します。

このディレクティブを js ファイルの先頭に追加できます:

// スクリプト ファイル全体が strict モード構文になります
"use strict"
var v = "こんにちは! 私は strict です。モード スクリプト!";

または関数内:

function f() { // 関数スコープ内の Strict モード構文

'use strict';

functionnested() { return "And so am I!"; } return "こんにちは!私は厳密モード関数です! " +nested(); }

function f2() { return "私は厳密ではありません。" }



このディレクティブを含む または関数内では、大規模な JavaScript プロジェクトでのいくつかの不正な動作を JavaScript エンジンの実行で直接禁止しました。特に、厳密モードでは次の動作が変更されます:



· 変数は、var より前に宣言されている場合にのみ使用できます
· 読み取り専用プロパティを書き込もうとするとエラーが発生します
· コンストラクターは新しいキーワードを使用して呼び出す必要があります
· this はデフォルトではグローバル オブジェクトを指しません
· eval() の使用は非常に制限されています
· 予約文字または将来の予約文字が変数名として使用されないように保護します

Strict モードは新しいプロジェクトでは有益ですが、ほとんどのプロジェクトではそれが使用されていない古いプロジェクトでそれを使用することは非常に困難です。複数のファイルを 1 つにマージする場合にも、ファイル全体が厳密モードで実行される可能性があるため、問題になります。 これは宣言ではなく、単なるリテラルであり、ブラウザの以前のバージョンでは無視されます。ストリクト モードのサポート:


· IE 10+
· FF 4+
· Chrome 13+
· Safari 5.1+
· Opera 12+

Strict モードの MDN の説明を参照してください。

20 - 配列または単一の要素をパラメータとして処理するメソッド


単一の要素をパラメータとして配列と関数を操作するための別のメソッドを書くよりも、一般的なメソッドを書く方が良いです。機能があるので、すべてを操作できます。これは、いくつかの jQuery メソッドに似ています (CSS マッチングによりすべてのセレクターが変更されます)。
最初にすべてを配列に入れる必要があります。Array.concat は配列または単一のオブジェクトを受け入れます。

function printUpperCase(words) { var elements = [].concat(words);

for (var) i = 0; i }

printUpperCase は、単一の要素をパラメーターまたは配列として受け取ることができるようになりました:
printUpperCase("cactus")
// => CACTUS
printUpperCase(["cactus", "bear", "potato"]);
// => サボテン
// クマ
// ポテト

21 - 未定義と null の違い

· 未定義は、変数が宣言されていない、または変数が宣言されていても代入されていないことを意味します。値
· Null は特定の値、つまり「値なし」を指します
JavaScript は未割り当ての変数をデフォルトで未定義として定義します
· JavaScript は未割り当ての変数に null 値を設定せず、プログラマがそれを表すために使用します。値のない変数。json 形式のデータでは値
未定義は無効ですが、null は有効です
未定義の型は未定義です
null はオブジェクトに似ています。なぜですか。
・両方ともプリミティブ値です
・どちらも false(Boolean(undefined) // false, Boolean(null) // false) とみなされます。
・変数が未定義かどうかを識別する

変数の種類 === “未定義”
・変数がnullであるかどうかを確認する

変数 === “null”
値を考慮すると、それらは等しいが、型と値は一緒に考慮され、等しくありません

null == 未定義 // true
null === 未定義 // false

22 - 非 ASCII 文字形式で文字列を並べ替えます

JavaScript のネイティブ メソッドは、配列を文字列形式で並べ替えることです。単純な array.sort() を実行すると、文字列がアルファベット順に並べ替えられます。もちろん、カスタム並べ替え機能も利用できます。

['上海', 'ニューヨーク', 'ムンバイ', 'ブエノスアイレス'].sort();
// ["ブエノスアイレス", "ムンバイ", "ニューヨーク", "上海"]

['é'、'a'、'ú'、'c'] などの非 ASCII 文字を使用して並べ替えようとすると、['c'、'e'、' という奇妙な結果が得られます。 á'、'ú']、これは英語の言語のみを並べ替えることができるために発生します。

簡単な例を見てみましょう:

// スペイン語
['único','árbol', 'cosas', 'fútbol'].sort();
// ["cosas", "fútbol" " ", "árbol", "único"] // 並べ替えが間違っています
// ドイツ語
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); "Woche", "wäre", "wöchentlich"] // 並べ替えが間違っています

幸いなことに、この動作を回避するには 2 つの方法があります。ECMAScript 国際化 API は localecompare と Intl.Collat​​or を提供します。 どちらの方法にも独自のカスタム パラメーターがあり、完全に機能するように構成できます。

localeCompare()を使用します

['único','árbol', 'cosas', 'fútbol'].sort(function (a, b) { return a.localeCompare(b);
} );
// ["arbol", "cosas", "fútbol", "único"]
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(function (a, b) {
return a.localeCompare(b);
});
// ["Wann", "wäre", "Woche", "wöchentlich"]

intl.collat​​or() を使用します

['único ','árbol', 'cosas', 'fútbol'].sort(Intl.Collat​​or().compare); // ["arbol", "cosas", "fútbol", "único"]
['Woche ', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collat​​or().compare)
// ["Wöchentlich", "Wäre", "Wöchentlich"]

・各メソッドで位置をカスタマイズできます

・FFブラウザでは、より大きな値や文字列を比較する場合、intl.collat​​or()の方が高速になります そのため、英語以外の言語を使用している場合に、文字列配列の場合は、予期しない並べ替えを避けるために必ずこのメソッドを使用してください。

23 - ネストされた条件の改善

JavaScript の if ステートメントのネストを改善し、より効率的にするにはどうすればよいでしょうか。

if (色) { if (色 === '黒') {
printBlackBackground();
} else if (色 === '赤') {
printRedBackground();
} color === 'blue') {
printBlueBackground();
} else if (color === 'green') {
printGreenBackground();
printYellowBackground();

改良点は、ネストされた if ステートメントの代わりに switch ステートメントを使用することです。これはよりクリーンで整理されていますが、デバッグが難しいためお勧めできません。その理由は次のとおりです。

switch(color) { case 'black':
printBlackBackground();
case 'blue':
break; ;
case 'green':
printGreenBackground();
default:
printYellowBackground(); しかし、複数の判定条件がある場合はどうなるでしょうか?この場合、より簡潔かつ整然としたものにしたい場合は、switch を使用できます。 switch ステートメントにパラメータとして true を渡すと、それぞれのケースに条件を付けることができます。


switch(true) {
case (typeof color === 'string' && color === 'black'):
printBlackBackground();
break; color === 'red'):
printRedBackground();
case (typeof color === 'string' && color === 'blue'):
printBlueBackground(); color === 'string' && color === 'green'):

printGreenBackground();

case (typeof color === 'string' && color === ' yellow'): printYellowBackground() ; break;

}



ただし、各条件で複数のチェックを避け、switch の使用を避ける必要があります。また、最も効率的な方法はオブジェクトを使用することであることも考慮する必要があります。
var colorObj = {
'black': printBlackBackground,
'red': printRedBackground,
'blue': printBlueBackground,
'green': printGreenBackground,
' yellow': printYellowBackground
};



if (カラーcolorObj) {
colorObjcolor;
}

その他の関連情報はこちらです。


24 - ReactJs 子構築のキーは非常に重要です



keys は、動的配列に渡す必要があるすべてのコンポーネントを表すプロパティです。これは、React が各 DOM コンポーネントを識別して、異なるコンポーネントか同じコンポーネントかを知るために使用する一意かつ固有の ID です。キーを使用して、子コンポーネントが再作成されずに保存されるようにし、奇妙な事態が発生するのを防ぎます。

· 既存の独立オブジェクト値を使用します
· 子コンポーネントではなく、親コンポーネントでキーを定義します

//Badrender() {

{{item .name}}

}

//OK
・配列の使用は良い習慣ではありません
・random() は決して実行されません

//悪い



・独自の ID を作成できます。メソッドを確認してくださいは高速で、オブジェクトにアタッチされています

· 子の数が膨大な場合、または複雑なコンポーネントが含まれている場合は、キーを使用してパフォーマンスを向上させます

· すべての子に ReactCSSTransitionGroup キー属性を指定する必要があります

25 - AngularJs:




apply

AngularJs の最も優れた機能は、双方向のデータ バインディングです。これが機能するために、AngularJs はモデルの変更とビュー ループ (



ダイジェスト ループ) を評価し、場合によっては新しいループを手動で実行する必要があり、このフェーズはパフォーマンスであるため、適切なオプションが必要です。最も効果的なのは $apply

このコア メソッドを使用すると、オプションの関数引数を実行した後に

ダイジェスト ループを開始できます。

ダイジェスト( );

$ダイジェスト

在这种情况下,$digest方法在当前作用域和它的子作用域执行,你应该注意到,父级的作用域将不被检查,并没有受到影响。
建议:

· 只在浏览器DOM事件在Angular之外被触发的时候使用

digest
· 给$apply传递函数表达式,这有一个错误处理机制,允许在消化周期中整合变化。

apply(() => {
$scope.tip = ‘Javascript Tip’;
});

· 如果你仅仅想更新当前作用域或者他的子作用域,用

digest。性能不言而喻咯。
· 当

evalAsync。这是一个在当前循环或下一次循环的期间或对表达式做出评估的核心方法,这可以提高你的应用程序的性能。

25 - 在数组插入一个项

将一个项插入到现有数组中,是一个日常常见的任务,你可以使用push在数组的末尾添加元素,使用unshift在开始的位置,或者在中间使用splice。

这些都是已知的方法,但这并不意味着没有一个更高性能的途径。我们来看一看。
在数组的末尾添加一个元素很容易与push(),但还有一个更高性能的途径。
var arr = [1,2,3,4,5];
arr.push(6);
arr[arr.length] = 6; //在Chrome 47.0.2526.106 (Mac OS X 10.11.1)上提高了 43% 的速度

这两种方法都修改了数组,不相信我?看这个jsperf
现在,如果我们正在尝试将一个项目添加到数组的开头:

var arr = [1,2,3,4,5];
arr.unshift(0);
[0].concat(arr); //在Chrome 47.0.2526.106 (Mac OS X 10.11.1)上提高了 98% 的速度

这里更详细一点:unshift编辑原有的数组,concat返回一个新数组。jsperf
添加在阵列中的物品很容易使用splice,它是做它的最高效的方式。
?
1
2

var items = [‘one’, ‘two’, ‘three’, ‘four’];
items.splice(items.length / 2, 0, ‘hello’);

我试着在不同的浏览器和操作系统中运行这些测试,结果是相似的。我希望这些建议对你有用,鼓励你自己做测试!

1、javascript 容错处理代码(屏蔽js错误)

<span style="font-size: 14px;"><script language="javascript"><br>    <!--    /*屏蔽所有的js错误*/<br/>    function killerrors() {<br/>        return true;<br/>    }<br/>    window.onerror = killerrors;    //--></script><br></span>
ログイン後にコピー

能够为大家提供这些简短而实用的JavaScript技巧来提高大家编程能力,这对于我来说是件很开心的事。每天仅花上不到2分钟的时间中,你将可以读遍JavaScript这门可怕的语言所呈现给我们的特性:performance(性能), conventions(协议), hacks(代码hack), interview questions(面试问题)及所有其他的项。

2、 使用 === 代替 ==

==(或者!=)做对比的时候会将进行对比的两者转换到同一类型再比较。===(或者!==)则不会,他会将进行对比的两者做类型对比和值对比,相对于 == ,=== 的对比会更加严谨。
[10] == 10 // true
[10] === 10 // false
“10” == 10 // true
“10” === 10 // false
[] == 0 // true
[] === 0 // false
“” == false // true 但是 true == “a” 是false
“” === false // false

3、转换数值的更加的方法

将字符串转换为数字是非常常见的。最简单和最快的(jspref)的方式来实现,将使用+(加)算法。

var one = ‘1’;
var numberOne = +one; // Number 1

アルゴリズムの - (マイナス記号) 変換タイプを使用して、負の値に変換することもできます。

var one = ‘1’;
var negativeNumberOne = -one; // Number -1

4 - 配列をクリアします

配列を定義し、その内容をクリアしたいとします。通常は次のようにします:

var list = [1, 2, 3, 4];
function empty() {
//配列を空にする
list = []}
empty();
;

しかし、よりパフォーマンスの高い方法があります。

次のコードを使用できます: var list = [1, 2, 3, 4];
function empty() {
//配列を空にする
list.length = 0;
empty();

· list =[] は変数への参照をその配列に割り当てますが、他の参照は影響を受けません。これは、前の配列の内容への参照がメモリ内に残り、メモリ リークが発生することを意味します。

· list.length = 0 は配列内のすべてを削除します。これには他への参照は必要ありません ただし、コピーされた配列 (A および copy-A) がある場合、list.length = 0 を使用するとその内容が削除されます、コピーの内容も失われます。
var foo = [1,2,3];
var foo2 = foo;
bar.length = 0; console.log(foo, bar, foo2, bar2);
//[] [] [1, 2, 3] []



StackOverflow の詳細: 配列の長さ 0 と-の間の差array

5 - 配列を「シャッフル」(ランダムに並べ替え) sort

このコードは、Fisher Yates シャッフル アルゴリズムを使用して、指定された配列をシャッフル (ランダムに並べ替え) します。

function shuffle(arr) { var i, j,

temp;

for (i = arr.length - 1; i > 0; i–) { j = Math.floor(Math.random() * (i + 1));
arr[i] = arr[j] = temp;



の場合: ?
1
2
3
4


var a = [1, 2, 3, 4, 5, 6, 7, 8];

var b = shuffle(a); ;

// [2, 7, 8, 6, 5, 3, 1, 4]


6 - オブジェクト指向の JavaScript オブジェクト関数を作成する場合、オブジェクトを返す関数は連鎖操作に使用できます

関数はオブジェクトを返します。関数は実行のために連鎖させることができます。



function person(name) { <br>this.name = name;
this.sayName = function() {

console.log(「こんにちは、this.name)」; ;

this.changeName = function(name) { this を返す }

var person("John").changeName("ティミー") ”).sayName();

//こんにちは、私の名前は: John //こんにちは、私の名前は: Timmy

7 - 文字列安全な接続



未知の型の変数がいくつかあるとします。それらを接続します。確かに、連結時にはアルゴリズム演算は適用されません:



var one = 1;
var two = '3';
var result = ”.concat(one, two, three); //"123"



このような連結は、予期しない結果を招く可能性があります:

var one = 1; var three = '3';

var result = one + two + three; //「123」ではなく「33」

パフォーマンスについて言えば、join と concat の実行速度はほぼ同じです。 MDN での concat



8 - より高速な丸め

二重チルダ「~~」演算子を見たことがありますか? これは、数学の高速な代替として使用することもできます。理由は何ですか? 入力は 32 ビット - (入力 + 1) に変換されます。これは、0 に近づくための優れたツールです。負の値の場合は Math.ceil() を模倣し、正の値の場合は Math.floor() を模倣します。実行が失敗した場合は 0 を返します。これは、失敗した場合に NaN を返す Math.floor() の代わりに役立つ可能性があります

// 単位シフト
console.log(~1337) // -1338
// ダブルシフト
console.log(47.11) // -> 47
console.log(
-12.88) // -> ; -12
console.log(1.9999) // -> 1
console.log(~~3) // -> 3
//障害状況
console.log(
[]) // - > ; 0
console.log(NaN) // -> 0
console.log(~~null) // -> 0
//32 ビット整数
console.log(
) より大きい場合は失敗(2147483647 + 1) === (2147483647 + 1)) // -> 0

~~ の方がパフォーマンスが良い可能性がありますが、読みやすさを考慮して Math.floor() を使用してください。

9 - Node.js: モジュールが必要ないときに実行しましょう

nodeでは、コードに従ってrequire('./something.js')またはnode something.jsを実行しましょう。プログラムに 2 つの異なることを実行するように指示します。これは、スタンドアロン モジュールの 1 つを操作する場合に便利です。

if (!module.parent) {
//
<code><span style="font-size: 14px;">node something.js</span>
app.listen(8088, function() {
console.log(‘app listening on port 8088’);
})
} else {
// 使用
<span style="font-size: 14px;">require('/.something.js')</span>node something.js
を実行します
app.listen(8088, function() {
console.log('app listenポート 8088');

}) else {

// require('/.something.js')

を使用します

module.exports = app; 詳細については、モジュールのドキュメントを参照してください

10 - コールバック関数にパラメータを渡す


デフォルトでは、次のようにコールバック関数にパラメータを渡すことはできません:

function callback() {

console.log('Hi human'); } document.getElementById('someelem').addEventListener('click', callback);


JavaScript クロージャを利用してコールバック関数パラメータを渡すことができます、その場合は次のとおりです:



function callback(a, b) {
return function() {
console.log('sum = ', (a+b))

}

} var x = 1, y = 2; document.getElementById('someelem').addEventListener('click', callback(x, y));

クロージャとは何ですか?クロージャは、独立した (自由な) 変数に対する関数です。言い換えれば、クロージャで定義された関数は、それが作成された環境を記憶しています。詳細については、「MDN」を参照してください。このようにして、呼び出されると、パラメータ X/Y はコールバック関数のスコープ内に存在します。


もう 1 つの方法は、バインディング メソッドを使用することです。例:

varalertText = function(text) {

alert(text) }; ) ;

2 つのメソッドのパフォーマンスには若干の違いがあります。詳細については、jsperf を参照してください

11 - IndexOf

に似た、より単純な包含判定メソッドを使用します。ネイティブ JavaScript には、メソッドが含まれています。文字列または文字列配列項目に値が存在するかどうかを確認するには、次のようにします。



var someText = 'JavaScript rules'
if (someText.indexOf('JavaScript') !== -1) {
}

// or

if (someText.indexOf('JavaScript') >= 0) { }

ただし、これらの ExpressJ のコード スニペットをもう一度見てみましょう。


//examples/mvc/lib/boot.js

for (var key in obj) {
    // 「予約済み」エクスポート
  • if (~['name', 'prefix', 'engine', 'before '].indexOf(key)) continue;

  • //examples/lib/utils.js

  • exports.normalizeType = function(type){

  • return ~type. IndexOf('/')

  • ? acceptParams(type)


  • { value: mime.lookup(type), params:
};



// Examples/web-service/index.js

// キーが無効です if (!~apiKeys.indexOf(key)) return next(error(401, 'invalid api key'));

🎜問題は~ビット演算子。 「演算子はこのようなバイナリ式の演算を実行しますが、標準の JavaScript 数値を返します。🎜演算子は -1 を 0 に変換します。これは JavaScript では false です。」 🎜🎜

var someText = 'text';
!!~someText.indexOf('tex'); // someText には "tex" が含まれます - true
!~someText.indexOf('tex'); // someText には " tex" ” - false
~someText.indexOf('asd'); // someText に "asd" が含まれていません - false
~someText.indexOf('ext'); // someText に "ext" が含まれています - true
String. prototype.includes ()

ES6 (ES 2015) で導入された include() メソッドを使用して、文字列に別の文字列が含まれているかどうかを判断できます。 / true

ECMAScript 2016 (ES7) では、indexOf:

!!~[1, 2, 3].indexOf(1); // true [ 1, 2, 3].includes(1); // true


残念ながら、これは Chrome、Firefox、Safari 9 以降でのみサポートされています。

12 - アロー関数 (ES6)

ES6 の新機能を紹介すると、アロー関数は、より少ない行数でより多くのコードを記述するための非常に便利なツールです。彼の名前は、=> が小さな矢印 -> と比較して「太い矢印」のように見える構文に由来しています。この関数タイプがラムダ式などの他の静的言語の匿名関数に似ていることをご存知の方もいるかもしれません。これらのアロー関数には説明的な関数名がないため、匿名と呼ばれます。 それで、これにはどんなメリットがあるのでしょうか?


構文: LOC が少なく、関数キーワードを何度も入力する必要がありません。

セマンティクス: コンテキストからキーワード this をキャプチャします。

簡単な構文の例:

以下の 2 つのコード スニペットを見てください。同じ働きをします。アロー関数の機能をすぐに理解できます。

// アロー関数の日常構文 param => 式

// 括弧内に記述することもできます

// 括弧は複数パラメータの要件です


// 毎日の関数を使用します
var arr = [5,3,2,9,1]
var arrFunc = arr.map(function(x) {

return x * x;

}); arr)


// アロー関数を使用します
var arr = [5,3,2,9,1]
var arrFunc = arr.map((x) => x*x); (arr)

ご覧のとおり、この例のアロー関数を使用すると、括弧内のパラメーターと return キーワードを入力する時間を節約できます。 (x,y) => x+y のように、パラメーターを括弧内に入力することをお勧めします。それは、ユースケースに応じて、単なる


忘れに対処する方法です。ただし、上記のコードは次のように実行されます: x => x*x 現時点では、これらは LOC を減らし、読みやすさを向上させる単なる構文上の改善であると思われます。

このバインディング

アロー関数を使用するもっと良い理由があります。それがこの問題が発生する状況です。アロー関数を使用すると、.bind(this) と that=this を気にする必要はありません。アロー関数がコンテキストからこれを見つけるためです。

以下の例を見てください:

// グローバル定義 this.i

this.i = 100;

var counterA = new CounterA(); var counterC = new CounterC(); var counterD = new CounterD();


// 悪い例
function CounterA() {
// CounterA の
<br>this

インスタンス(!! ここは無視してください)

this.i = 0; setInterval(function () {
//
this<span style="font-size: 14px;">this</span> 实例 (!! 忽略这里) <br>this.i = 0;
setInterval(function () {
//
<span style="font-size: 14px;">this</span> 指全局对象,而不是 CounterA’s <span style="font-size: 14px;">this</span>
は、CounterA の <br>this
ではなく、グローバル オブジェクトを参照します。
// したがって、0 ではなく 100 でカウントを開始します (ローカル this.i)
document.getElementById(“counterA”).innerHTML = this.i
}
// that = this
function CounterB() { <br>this.i = 0;
var that = this(function() {
document.getElementById(“counterB”).innerHTML = that) を手動でバインドします。 i;
}, 500);
}
// .bind(this) を使用します
function CounterC() { <br>this.i = 0;
setInterval(function() { <br>this.i++;
document.getElementById(“ counterC”).innerHTML = this.i;
}.bind(this), 500);
// アロー関数を使用します
function CounterD() { <br>this.i = 0;
setInterval(); { <br>this.i++;
document.getElementById(“counterD”).innerHTML = this.i
}, 500);

矢印機能の詳細については、こちらをご覧ください。さまざまな構文オプションを確認するには、このサイトにアクセスしてください。

13 - JavaScript ブロックのパフォーマンスを測定するためのヒント

JavaScript ブロックのパフォーマンスをすばやく測定するには、console.time(label) や console.timeEnd(label) などのコンソール関数を使用できます

console.time(“配列の初期化”);
var arr = new Array(100),
len = arr.length,
i;
for (i = 0; i arr[ i ] = new Object();
console.timeEnd(“配列の初期化”); // 出力: 配列の初期化: 0.711ms

デモ: jsfiddle- codepen (ブラウザコンソールの出力)

14 - ES6 でのパラメータ処理

多くのプログラミング言語では、関数のパラメータはデフォルトであり、開発者はパラメータをオプションとして明示的に定義する必要があります。 JavaScript のすべてのパラメーターはオプションですが、関数に ES6 のデフォルト値をパラメーターとして取らせることなくこれを行うことができます。

const _err = function( message ){

throw new Error( message ); } const getSum = (a = _err('a が定義されていません'), b = _err('b が定義されていません') ) => a + b

getSum( 10 ) // Error をスローする、b が定義されていない

getSum( unknown, 10 ) // Error をスローする、a が定義されていない


_err は即座にエラーをスローする関数です。値として引数がない場合は、デフォルト値が使用され、_err が呼び出され、エラーがスローされます。 Mozilla Developer Network でデフォルト パラメータのその他の例を参照できます。

15 - ブースト

ブーストを理解すると、関数を整理するのに役立ちます。変数宣言と関数定義は最上位に引き上げられることに注意してください。変数の宣言と定義を同じ行で行った場合でも、変数の定義は機能しません。さらに、変数宣言はシステムに変数が存在することを知らせますが、定義は変数に値を割り当てます。

function doTheThing() {

// エラー: notDeclared が定義されていません

console.log(notDeclared); // 出力: un 未定義 var definedLater;定義されています!'

// 出力: '私は定義されています!'

console.log(defineLater) // 出力: 未定義
console.log(defineSimulateneously) = '私は定義されています!'
'私は定義されました!'
console.log(defineSimulateneously)
// 出力: '私はそれをしました!'
doSomethingElse(){
console.log('私はそれをしました!');
// エラー: 未定義は関数ではありません
functionVar();
var functionVar = function(){
console.log('やった!');
}



読みやすくするため、関数スコープ内で変数宣言をホイストすると、変数がどのスコープから宣言されているかがわかります。変数は使用する前に定義してください。明確で標準化されたコードを保証するために、スコープの下部で関数を定義します。



16 - オブジェクトにプロパティがあるかどうかを確認する



オブジェクトに特定のプロパティがあるかどうかを確認したい場合は、次のようにします:

var myObject = { name: '@tips_js' };

if (myObject.name) { … }

これは可能ですが、これを行うには、operator と object.hasownproperty の 2 つのネイティブな方法があることを知っておく必要があります。各オブジェクトはオブジェクトであり、使用可能なプロパティがあります。方法。すべてのオブジェクトは Object を継承し、両方のメソッドを使用できます。

2 つのメソッドのいくつかの違い:



var myObject = {
name: '@tips_js'
}; // true

'name' in myObject; / true

myObject.hasOwnProperty('valueOf'); // false、valueOf は myObject のプロトタイプ チェーン 'valueOf' から継承されます。 // true

それらの違いはチェックの性質にあります。つまり、オブジェクト自体に検索対象のプロパティがある場合、hasOwnProperty は yrue を返します。ただし、in 演算子は、プロパティによって作成されたオブジェクトとプロパティ継承のプロトタイプ チェーンを区別しません。 別の例を示します:


var myFunc = function() { <br>this.name = '@tips_js'
};
myFunc.prototype.age = '10 days';
var user = new myFunc( ) ;
user.hasOwnProperty('name'); // true
user.hasOwnProperty('age') // 年齢はプロトタイプチェーンにあるため

点击看例子。同时,建议在检查对象的属性存在时,阅读这些有关的常见错误。

17 - 模板字符串

截至ES6,JS已经有模板字符串作为替代经典的结束引用的字符串。
案例:普通字符串

var firstName = ‘Jake’;
var lastName = ‘Rawr’;
console.log(‘My name is ’ + firstName + ’ ’ + lastName);
// My name is Jake Rawr  
模板字符串:
var firstName = ‘Jake’;
var lastName = ‘Rawr’;
console.log(
<span style="font-size: 14px;">My name is ${firstName} ${lastName}</span>);
// My name is Jake Rawr

在模板字符串中${}中,你可以写不用写/n或者简单逻辑来实现多行字符串。
您还可以使用函数来修改模板字符串的输出,它们被称为模板字符串的标记。你可能还想读到更多的理解模板字符串相关信息。

18- ノードリストを配列に変換する

querySelectorAll メソッドは、配列に似たノードリストオブジェクトを返します。これらのデータ構造は、配列の形式で現れることが多いため配列に似ていますが、map や foreach などの配列メソッドは使用できません。これは、ノードリストを DOM 要素の配列に変換するための高速かつ安全で再利用可能な方法です。 /later on .. nodelistToArray.forEach(…);

nodelistToArray.slice(…);

//etc…


applyメソッドは一連のパラメータを配列形式に変換しますこれが与えられた場合は関数に渡されます。 MDN は、apply が配列のようなオブジェクトを呼び出し、それが querySelectorAll が返すものであると指摘しています。関数のコンテキストでこれを指定する必要がないため、null または 0 を渡します。返される結果は、配列メソッドを使用して使用できる DOM 要素の配列です。


es2015 を使用している場合は、...(spread 演算子) を使用できます

const nodelist = […document.querySelectorAll('p')] // 返されるのは実数の配列です

/ /後で

nodelist.forEach(…); nodelist.slice(…);

厳密モード JavaScript 開発者がより安全に JavaScript を記述できるようにします。
デフォルトでは、JavaScript では開発者が怠惰になる可能性があります。たとえば、初めて変数を宣言するときに var を使用することは、経験の浅い開発者のように見えるかもしれませんが、これは変数名のスペルミスの原因でもあります。誤ってまたは偶然に外部スコープに言及されました。



プログラマは、コンピュータに退屈な作業をさせたり、作業中のエラーをチェックしたりすることを好みます。 「use strict」は、これを実行してエラーを JavaScript エラーに変換するように指示します。

このディレクティブを js ファイルの先頭に追加できます:

// スクリプト ファイル全体が strict モード構文になります
"use strict"
var v = "こんにちは! 私は strict です。モード スクリプト!";

または関数内:

function f() { // 関数スコープ内の Strict モード構文

'use strict';

functionnested() { return "And so am I!"; } return "こんにちは!私は厳密モード関数です! " +nested(); }

function f2() { return "私は厳密ではありません。" }



このディレクティブを含む または関数内では、大規模な JavaScript プロジェクトでのいくつかの不正な動作を JavaScript エンジンの実行で直接禁止しました。特に、厳密モードでは次の動作が変更されます:



· 変数は、var より前に宣言されている場合にのみ使用できます
· 読み取り専用プロパティを書き込もうとするとエラーが発生します
· コンストラクターは新しいキーワードを使用して呼び出す必要があります
· this はデフォルトではグローバル オブジェクトを指しません
· eval() の使用は非常に制限されています
· 予約文字または将来の予約文字が変数名として使用されないように保護します

Strict モードは新しいプロジェクトでは有益ですが、ほとんどのプロジェクトではそれが使用されていない古いプロジェクトでそれを使用することは非常に困難です。複数のファイルを 1 つにマージする場合にも、ファイル全体が厳密モードで実行される可能性があるため、問題になります。 これは宣言ではなく、単なるリテラルであり、ブラウザの以前のバージョンでは無視されます。ストリクト モードのサポート:


· IE 10+
· FF 4+
· Chrome 13+
· Safari 5.1+
· Opera 12+

Strict モードの MDN の説明を参照してください。

20 - 配列または単一の要素をパラメータとして処理するメソッド


単一の要素をパラメータとして配列と関数を操作するための別のメソッドを書くよりも、一般的なメソッドを書く方が良いです。機能があるので、すべてを操作できます。これは、いくつかの jQuery メソッドに似ています (CSS マッチングによりすべてのセレクターが変更されます)。
最初にすべてを配列に入れる必要があります。Array.concat は配列または単一のオブジェクトを受け入れます。

function printUpperCase(words) { var elements = [].concat(words);

for (var) i = 0; i }

printUpperCase は、単一の要素をパラメーターまたは配列として受け取ることができるようになりました:
printUpperCase("cactus")
// => CACTUS
printUpperCase(["cactus", "bear", "potato"]);
// => サボテン
// クマ
// ポテト

21 - 未定義と null の違い

· 未定義は、変数が宣言されていない、または変数が宣言されていても代入されていないことを意味します。値
· Null は特定の値、つまり「値なし」を指します
JavaScript は未割り当ての変数をデフォルトで未定義として定義します
· JavaScript は未割り当ての変数に null 値を設定せず、プログラマがそれを表すために使用します。値のない変数。json 形式のデータでは値
未定義は無効ですが、null は有効です
未定義の型は未定義です
null はオブジェクトに似ています。なぜですか。
・両方ともプリミティブ値です
・どちらも false(Boolean(undefined) // false, Boolean(null) // false) とみなされます。
・変数が未定義かどうかを識別する

変数の種類 === “未定義”
・変数がnullであるかどうかを確認する

変数 === “null”
値を考慮すると、それらは等しいが、型と値は一緒に考慮され、等しくありません

null == 未定義 // true
null === 未定義 // false

22 - 非 ASCII 文字形式で文字列を並べ替えます

JavaScript のネイティブ メソッドは、配列を文字列形式で並べ替えることです。単純な array.sort() を実行すると、文字列がアルファベット順に並べ替えられます。もちろん、カスタム並べ替え機能も利用できます。

['上海', 'ニューヨーク', 'ムンバイ', 'ブエノスアイレス'].sort();
// ["ブエノスアイレス", "ムンバイ", "ニューヨーク", "上海"]

['é'、'a'、'ú'、'c'] などの非 ASCII 文字を使用して並べ替えようとすると、['c'、'e'、' という奇妙な結果が得られます。 á'、'ú']、これは英語の言語のみを並べ替えることができるために発生します。

簡単な例を見てみましょう:

// スペイン語
['único','árbol', 'cosas', 'fútbol'].sort();
// ["cosas", "fútbol" " ", "árbol", "único"] // 並べ替えが間違っています
// ドイツ語
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(); "Woche", "wäre", "wöchentlich"] // 並べ替えが間違っています

幸いなことに、この動作を回避するには 2 つの方法があります。ECMAScript 国際化 API は localecompare と Intl.Collat​​or を提供します。 どちらの方法にも独自のカスタム パラメーターがあり、完全に機能するように構成できます。

localeCompare()を使用します

['único','árbol', 'cosas', 'fútbol'].sort(function (a, b) { return a.localeCompare(b);
} );
// ["arbol", "cosas", "fútbol", "único"]
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(function (a, b) {
return a.localeCompare(b);
});
// ["Wann", "wäre", "Woche", "wöchentlich"]

intl.collat​​or() を使用します

['único ','árbol', 'cosas', 'fútbol'].sort(Intl.Collat​​or().compare); // ["arbol", "cosas", "fútbol", "único"]
['Woche ', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collat​​or().compare)
// ["Wöchentlich", "Wäre", "Wöchentlich"]

・各メソッドで位置をカスタマイズできます

・FFブラウザでは、より大きな値や文字列を比較する場合、intl.collat​​or()の方が高速になります そのため、英語以外の言語を使用している場合に、文字列配列の場合は、予期しない並べ替えを避けるために必ずこのメソッドを使用してください。

23 - ネストされた条件の改善

JavaScript の if ステートメントのネストを改善し、より効率的にするにはどうすればよいでしょうか。

if (色) { if (色 === '黒') {
printBlackBackground();
} else if (色 === '赤') {
printRedBackground();
} color === 'blue') {
printBlueBackground();
} else if (color === 'green') {
printGreenBackground();
printYellowBackground();

改良点は、ネストされた if ステートメントの代わりに switch ステートメントを使用することです。これはよりクリーンで整理されていますが、デバッグが難しいためお勧めできません。その理由は次のとおりです。

switch(color) { case 'black':
printBlackBackground();
case 'blue':
break; ;
case 'green':
printGreenBackground();
default:
printYellowBackground(); しかし、複数の判定条件がある場合はどうなるでしょうか?この場合、より簡潔かつ整然としたものにしたい場合は、switch を使用できます。 switch ステートメントにパラメータとして true を渡すと、それぞれのケースに条件を付けることができます。


switch(true) {
case (typeof color === 'string' && color === 'black'):
printBlackBackground();
break; color === 'red'):
printRedBackground();
case (typeof color === 'string' && color === 'blue'):
printBlueBackground(); color === 'string' && color === 'green'):

printGreenBackground();

case (typeof color === 'string' && color === ' yellow'): printYellowBackground() ; break;

}



ただし、各条件で複数のチェックを避け、switch の使用を避ける必要があります。また、最も効率的な方法はオブジェクトを使用することであることも考慮する必要があります。
var colorObj = {
'black': printBlackBackground,
'red': printRedBackground,
'blue': printBlueBackground,
'green': printGreenBackground,
' yellow': printYellowBackground
};



if (カラーcolorObj) {
colorObjcolor;
}

その他の関連情報はこちらです。


24 - ReactJs 子構築のキーは非常に重要です



keys は、動的配列に渡す必要があるすべてのコンポーネントを表すプロパティです。これは、React が各 DOM コンポーネントを識別して、異なるコンポーネントか同じコンポーネントかを知るために使用する一意かつ固有の ID です。キーを使用して、子コンポーネントが再作成されずに保存されるようにし、奇妙な事態が発生するのを防ぎます。

· 既存の独立オブジェクト値を使用します
· 子コンポーネントではなく、親コンポーネントでキーを定義します

//Badrender() {

{{item .name}}

}

//OK
・配列の使用は良い習慣ではありません
・random() は決して実行されません

//悪い



・独自の ID を作成できます。メソッドを確認してくださいは高速で、オブジェクトにアタッチされています

· 子の数が膨大な場合、または複雑なコンポーネントが含まれている場合は、キーを使用してパフォーマンスを向上させます

· すべての子に ReactCSSTransitionGroup キー属性を指定する必要があります

25 - AngularJs:




apply

AngularJs の最も優れた機能は、双方向のデータ バインディングです。これが機能するために、AngularJs はモデルの変更とビュー ループ (



ダイジェスト ループ) を評価し、場合によっては新しいループを手動で実行する必要があり、このフェーズはパフォーマンスであるため、適切なオプションが必要です。最も効果的なのは $apply

このコア メソッドを使用すると、オプションの関数引数を実行した後に

ダイジェスト ループを開始できます。

ダイジェスト( );

$ダイジェスト

在这种情况下,$digest方法在当前作用域和它的子作用域执行,你应该注意到,父级的作用域将不被检查,并没有受到影响。
建议:

· 只在浏览器DOM事件在Angular之外被触发的时候使用

digest
· 给$apply传递函数表达式,这有一个错误处理机制,允许在消化周期中整合变化。

apply(() => {
$scope.tip = ‘Javascript Tip’;
});

· 如果你仅仅想更新当前作用域或者他的子作用域,用

digest。性能不言而喻咯。
· 当

evalAsync。这是一个在当前循环或下一次循环的期间或对表达式做出评估的核心方法,这可以提高你的应用程序的性能。

25 - 在数组插入一个项

将一个项插入到现有数组中,是一个日常常见的任务,你可以使用push在数组的末尾添加元素,使用unshift在开始的位置,或者在中间使用splice。

这些都是已知的方法,但这并不意味着没有一个更高性能的途径。我们来看一看。
在数组的末尾添加一个元素很容易与push(),但还有一个更高性能的途径。
var arr = [1,2,3,4,5];
arr.push(6);
arr[arr.length] = 6; //在Chrome 47.0.2526.106 (Mac OS X 10.11.1)上提高了 43% 的速度

这两种方法都修改了数组,不相信我?看这个jsperf
现在,如果我们正在尝试将一个项目添加到数组的开头:

var arr = [1,2,3,4,5];
arr.unshift(0);
[0].concat(arr); //在Chrome 47.0.2526.106 (Mac OS X 10.11.1)上提高了 98% 的速度

这里更详细一点:unshift编辑原有的数组,concat返回一个新数组。jsperf
添加在阵列中的物品很容易使用splice,它是做它的最高效的方式。
?
1
2

var items = [‘one’, ‘two’, ‘three’, ‘four’];
items.splice(items.length / 2, 0, ‘hello’);

我试着在不同的浏览器和操作系统中运行这些测试,结果是相似的。我希望这些建议对你有用,鼓励你自己做测试!

以上がjs のヒントを共有するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート