検索
ホームページウェブフロントエンドjsチュートリアルJavaScript のヒント集 (非常に完全)_JavaScript のヒント

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

#24 - ==
の代わりに === を使用します

== (または !=) 比較する場合、比較対象の 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 

#23 - 値を変換するより良い方法

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

var one = '1';
var numberOne = +one; // Number 1 

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

var one = '1';
var negativeNumberOne = -one; // Number -1 

#22 - 配列をクリアする

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

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 bar = [1,2,3];
var foo2 = foo;
var bar2 = bar;
foo = [];
bar.length = 0;
console.log(foo, bar, foo2, bar2);
//[] [] [1, 2, 3] [] 

StackOverflow の詳細: 配列の長さ 0 と配列の間の違い

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

このコードは、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; 
}; 

ケース:

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] 

#20 - オブジェクトを返す関数は連鎖操作に使用できます

オブジェクト指向 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 

#19 - 文字列の安全な接続

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

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

この接続は、あなたが期待したものとはまったく異なります。代わりに、一部の連結と加算によって予期しない結果が生じる可能性があります:

var one = 1;
var two = 2;
var three = '3';
var result = one + two + three; //"33" 而不是 "123" 

パフォーマンスに関しては、join と concat を比較すると、実行速度はほぼ同じです。 concat について詳しくは、MDN
をご覧ください。

#18 - 丸めの高速化

今日のヒントはパフォーマンスに関するものです。二重チルダ「~~」演算子を見たことがありますか?二重 NOT 演算子と呼ばれることもあります。 Math.floor() のより高速な代替品として使用できます。なぜ?
Unit shift~ は 32 ビット入力を -(input+1) に変換するため、double シフトは入力を -(-(input+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() を使用してください。

#17 - Node.js: 不要なときにモジュールを実行する

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

if (!module.parent) {
// 运行 `node something.js`
app.listen(8088, function() {
console.log('app listening on port 8088');
})
} else {
// 使用 `require('/.something.js')`
module.exports = app;
}

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

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

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

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

#15 - 使用更简单的类似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或以上的浏览器中被支持。

#14 - 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 (在浏览器控制台输出)

#12 - 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开发者网络看到的更多默认参数的例子。

#11 - 提升

理解提升将帮助你组织你的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!');
}
}

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

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

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

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() {
this.name = '@tips_js';
};
myFunc.prototype.age = '10 days';
var user = new myFunc();
user.hasOwnProperty('name'); // true
user.hasOwnProperty('age'); // false, 因为age是原型链上的 

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

#09 - 模板字符串

截至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(`My name is ${firstName} ${lastName}`);
// My name is Jake Rawr 

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

#08 - 将节点列表转换为数组

querySelectorAll 方法返回一个和数组类似的节点列表对象。这些数据结构类似数组,因为经常以数组形式出现,但是又不能用数组的方法,比如map和foreach。这里是一个快速、安全、可重用的方式将一个节点列表到一个DOM元素数组:

const nodelist = document.querySelectorAll('div');
const nodelistToArray = Array.apply(null, nodelist);
//later on ..
nodelistToArray.forEach(...);
nodelistToArray.map(...);
nodelistToArray.slice(...);
//etc... 

apply方法是将一系列数组格式的参数传递给一个给定this的函数。MDN指出,apply将会调用类似数组的对象,而这正是querySelectorAll所返回的。因为我们不需要在函数的上下文中指定this,所以我们传入null或0。返回的结果是一组能使用数组方法的DOM元素数组。

如果你使用的是es2015可以利用...(spread operator)

const nodelist = [...document.querySelectorAll('div')]; // 返回的是个真实的数组
//later on ..
nodelist.forEach(...);
nodelist.map(...);
nodelist.slice(...);
//etc... 

#07 - "use strict" 和懒惰

严格模式的JavaScript让开发人员更加安全的编写JavaScript。
默认情况下,JavaScript允许开发者懒惰,例如,我们在第一次声明变量的时候可以不用var,虽然这可能看起来像一个没有经验的开发人员,同时这也是很多错误的根源,变量名拼写错误或意外地将它提到了外部作用域。

程序员喜欢让电脑为我们做些无聊的事,检查一些我们工作的错误。"use strict"指令我们做这些,将我们的错误转换成JavaScript的错误。

我们把这个指令可以通过添加在一个js文件的顶部:

// 整个script文件都将是严格模式语法
"use strict";
var v = "Hi! I'm a strict mode script!";
或者在函数内:
function f()
{
// 函数范围内的严格模式语法
'use strict';
function nested() { return "And so am I!"; }
return "Hi! I'm a strict mode function! " + nested();
}
function f2() { return "I'm not strict."; }

在包含这个指令的JavaScript文件或者函数内,我们将一些较大的JavaScript项目中的不良行为直接在JavaScript引擎执行中禁止了。在其他情况中,严格模式改变以下的行为:

· 变量只有在前面 var 声明了才能用
· 试图写入只读属性产生的误差
· 必须用 new 关键字调用构造函数
· this 不会默认指向全局对象
· 非常有限的使用eval()
· 保护保留字符或未来保留字符不被作为变量名使用

严格模式在新项目中是很有好处的,但是在大多数地方没使用到它的老项目里使用它是非常具有挑战性的。当你把多个文件合并到一个文件时,它也是个问题,就像可能导致整个文件都在严格模式下执行。
它不是一个声明,只是一个字面量,早期版本的浏览器会忽略它。严格模式支持:

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

参阅MDN对于严格模式的描述。

#06 - 处理一个数组或单个元素作为参数的方法

相比于写个单独的方法去分别操作一个数组和一个元素作为参数的函数,更好的是写一个通用的函数,这样就都可以操作。这类似于一些jQuery的方法(css匹配将修改所有的选择器)。
你仅需要先将一切放进数组,Array.concat会接收数组或单一的对象:

function printUpperCase(words) {
var elements = [].concat(words);
for (var i = 0; i < elements.length; i++) {
console.log(elements[i].toUpperCase());
}
}

printUpperCase现在可以接收无论单一的元素作为参数还是一个数组:

printUpperCase("cactus");
// => CACTUS
printUpperCase(["cactus", "bear", "potato"]);
// => CACTUS
// BEAR
// POTATO 

#05 - undefined 和 null 的不同

· undefined指的是一个变量未被声明,或者一个变量被声明但未赋值
· null是指一个特定的值,即"没有值"
. JavaScript给未赋值的变量默认定义为undefined
· JavaScript不会给未赋值的变量设置null值,它被程序员用来表示一个无价值的值
· undefined在json格式数据中是无效的,而null有效
· undefined 类型是 undefined
· null类似是object.为什么呢?
· 两者都是原始值
· 两者都被认为false(Boolean(undefined) // false, Boolean(null) // false)。
· 辨认变量是不是undefined

typeof variable === "undefined"
· 检查变量是不是null

variable === "null"
从值考虑他们是相等的,但是从类型和值共同考虑他们是不相等的

null == undefined // true
null === undefined // false

#04 - 以非ASCII字符形式来排序字符串

JavaScript有个原生的方法对字符串格式的数组进行排序,做一个简单的array.sort()将会把字符串们按首字母的数序排列。当然,也可以提供自定义排序功能。

['Shanghai', 'New York', 'Mumbai', 'Buenos Aires'].sort();
// ["Buenos Aires", "Mumbai", "New York", "Shanghai"] 

当你试图用非ASCII字符,如 ['é', 'a', 'ú', 'c']这样的进行排序,你会得到一个奇怪的结果['c', 'e', 'á', 'ú'],因为只有用英语的语言才能排序,所以发生这种情况。

看一个简单的例子:

// Spanish
['único','árbol', 'cosas', 'fútbol'].sort();
// ["cosas", "fútbol", "árbol", "único"] // 错误的排序
// German
['Woche', 'w&ouml;chentlich', 'w&auml;re', 'Wann'].sort();
// ["Wann", "Woche", "w&auml;re", "w&ouml;chentlich"] // 错误的排序 

幸运的是,有两种方法来避免这种行为,ECMAScript国际化的API提供了localecompare和and Intl.Collator。
这两种方法都有自己的自定义参数,以便将其配置来充分的完成功能。

使用 localeCompare()

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

使用 intl.collator()

['único','árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare);
// ["árbol", "cosas", "fútbol", "único"]
['Woche', 'w&ouml;chentlich', 'w&auml;re', 'Wann'].sort(Intl.Collator().compare);
// ["Wann", "w&auml;re", "Woche", "w&ouml;chentlich"] 

· 每个方法都可以自定义位置

· 在FF浏览器,intl.collator()会更快,当比较的是较大的数值或字符串
因此,当你在用英语以外的语言来赋值给字符串数组时,记得要使用此方法来避免意外的排序。

#03 - 改善嵌套条件

我们怎样才能改善并且使JavaScript中的if语句做出更有效的嵌套。

if (color) {
if (color === 'black') {
printBlackBackground();
} else if (color === 'red') {
printRedBackground();
} else if (color === 'blue') {
printBlueBackground();
} else if (color === 'green') {
printGreenBackground();
} else {
printYellowBackground();
}
}

一个改善的办法是用switch语句代替嵌套的if语句。虽然它是更加简洁,更加有序,但不推荐这样做,因为很难debug。这里指出原因。

switch(color) {
case 'black':
printBlackBackground();
break;
case 'red':
printRedBackground();
break;
case 'blue':
printBlueBackground();
break;
case 'green':
printGreenBackground();
break;
default:
printYellowBackground();
}

但是,当我们有多个判断条件的情况下呢?在这种情况下,如果我们想让它更加简洁,更加有序,我们可以使用switch。如果我们将true的作为一个参数传递给该switch语句,它可以让我们在每一个情况下放置一个条件。

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

但我们必须避免在每一个条件下进行多次检查,尽量避免使用switch。我们也必须考虑到最有效的方法是通过一个object。

var colorObj = {
'black': printBlackBackground,
'red': printRedBackground,
'blue': printBlueBackground,
'green': printGreenBackground,
'yellow': printYellowBackground
};

if (color in colorObj) {
colorObj[color]();
}

这里有更多相关的信息。

#02 - ReactJs 子级构造的keys是很重要的

keys是代表你需要传递给动态数组的所有组件的一个属性。这是一个独特的和指定的ID,react用它来标识每个DOM组件以用来知道这是个不同的组件或者是同一个组件。使用keys来确保子组件是可保存的并且不是再次创造的,并且防止怪异事情的产生。

· 使用已存在的一个独立的对象值
· 定义父组件中的键,而不是子组件

//不好的
...
render() {
<div key={{item.key}}>{{item.name}}</div>
}
...
//好的
<MyComponent key={{item.key}}/> 
· 使用数组不是个好习惯
· random()从不会执行
//不好的
<MyComponent key={{Math.random()}}/> 

· 你可以创建你的唯一id,请确保该方法是快速的并已经附加到对象上的
· 当子级的数量是庞大的或包含复杂的组件,使用keys来提高性能
· 你必须为所有的子级ReactCSSTransitionGroup提供key属性

#01 - AngularJs: $digest vs $apply

AngularJs最让人欣赏的特点是双向数据绑定。为了是它工作,AngularJs评估模型的变化和视图的循环($digest)。你需要了解这个概念,以便了解框架是如何在引擎中工作的。
Angular评估每时的每个事件的变化。这就是$digest循环。有时你必须手动运行一个新的循环,你必须有正确的选择,因为这个阶段是性能方面表现出最具影响力的。

$apply

这个核心方法让你来启动一个$digest循环。这意味着所以的watch列表中的对象都将被检查,整个应用程序启动了$digest循环。在内部,执行可选的函数参数之后,调用$rootScope.$digest();

$digest

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

· 只在浏览器DOM事件在Angular之外被触发的时候使用$apply或者$digest
· 给$apply传递函数表达式,这有一个错误处理机制,允许在消化周期中整合变化。

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

· 如果你仅仅想更新当前作用域或者他的子作用域,用$digest,并且防止整个应用程序的$digest。性能不言而喻咯。
· 当$apply有很多东西绑定时,这对机器来说是个艰难的过程,可能会导致性能问题。
· 如果你使用的是Angular 1.2.x以上的,使用$evalAsync。这是一个在当前循环或下一次循环的期间或对表达式做出评估的核心方法,这可以提高你的应用程序的性能。

#00 - 在数组插入一个项

将一个项插入到现有数组中,是一个日常常见的任务,你可以使用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,它是做它的最高效的方式。

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

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

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScript:Web言語の汎用性の調査JavaScript:Web言語の汎用性の調査Apr 11, 2025 am 12:01 AM

JavaScriptは、現代のWeb開発のコア言語であり、その多様性と柔軟性に広く使用されています。 1)フロントエンド開発:DOM操作と最新のフレームワーク(React、Vue.JS、Angularなど)を通じて、動的なWebページとシングルページアプリケーションを構築します。 2)サーバー側の開発:node.jsは、非ブロッキングI/Oモデルを使用して、高い並行性とリアルタイムアプリケーションを処理します。 3)モバイルおよびデスクトップアプリケーション開発:クロスプラットフォーム開発は、反応および電子を通じて実現され、開発効率を向上させます。

JavaScriptの進化:現在の傾向と将来の見通しJavaScriptの進化:現在の傾向と将来の見通しApr 10, 2025 am 09:33 AM

JavaScriptの最新トレンドには、TypeScriptの台頭、最新のフレームワークとライブラリの人気、WebAssemblyの適用が含まれます。将来の見通しは、より強力なタイプシステム、サーバー側のJavaScriptの開発、人工知能と機械学習の拡大、およびIoTおよびEDGEコンピューティングの可能性をカバーしています。

javascriptの分解:それが何をするのか、なぜそれが重要なのかjavascriptの分解:それが何をするのか、なぜそれが重要なのかApr 09, 2025 am 12:07 AM

JavaScriptは現代のWeb開発の基礎であり、その主な機能には、イベント駆動型のプログラミング、動的コンテンツ生成、非同期プログラミングが含まれます。 1)イベント駆動型プログラミングにより、Webページはユーザー操作に応じて動的に変更できます。 2)動的コンテンツ生成により、条件に応じてページコンテンツを調整できます。 3)非同期プログラミングにより、ユーザーインターフェイスがブロックされないようにします。 JavaScriptは、Webインタラクション、シングルページアプリケーション、サーバー側の開発で広く使用されており、ユーザーエクスペリエンスとクロスプラットフォーム開発の柔軟性を大幅に改善しています。

pythonまたはjavascriptの方がいいですか?pythonまたはjavascriptの方がいいですか?Apr 06, 2025 am 12:14 AM

Pythonはデータサイエンスや機械学習により適していますが、JavaScriptはフロントエンドとフルスタックの開発により適しています。 1. Pythonは、簡潔な構文とリッチライブラリエコシステムで知られており、データ分析とWeb開発に適しています。 2。JavaScriptは、フロントエンド開発の中核です。 node.jsはサーバー側のプログラミングをサポートしており、フルスタック開発に適しています。

JavaScriptをインストールするにはどうすればよいですか?JavaScriptをインストールするにはどうすればよいですか?Apr 05, 2025 am 12:16 AM

JavaScriptは、最新のブラウザにすでに組み込まれているため、インストールを必要としません。開始するには、テキストエディターとブラウザのみが必要です。 1)ブラウザ環境では、タグを介してHTMLファイルを埋め込んで実行します。 2)node.js環境では、node.jsをダウンロードしてインストールした後、コマンドラインを介してJavaScriptファイルを実行します。

クォーツでタスクが開始される前に通知を送信する方法は?クォーツでタスクが開始される前に通知を送信する方法は?Apr 04, 2025 pm 09:24 PM

Quartzタイマーを使用してタスクをスケジュールする場合、Quartzでタスク通知を事前に送信する方法、タスクの実行時間はCron式によって設定されます。今...

JavaScriptでは、コンストラクターのプロトタイプチェーンで関数のパラメーターを取得する方法は?JavaScriptでは、コンストラクターのプロトタイプチェーンで関数のパラメーターを取得する方法は?Apr 04, 2025 pm 09:21 PM

JavaScriptプログラミング、プロトタイプチェーンの関数パラメーターの理解と操作のJavaScriptのプロトタイプチェーンの関数のパラメーターを取得する方法は、一般的で重要なタスクです...

WeChat MiniプログラムWebViewでVUE.JSダイナミックスタイルの変位が失敗した理由は何ですか?WeChat MiniプログラムWebViewでVUE.JSダイナミックスタイルの変位が失敗した理由は何ですか?Apr 04, 2025 pm 09:18 PM

WeChatアプレットWeb-ViewでVue.jsを使用する動的スタイルの変位障害がvue.jsを使用している理由の分析...

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

VSCode Windows 64 ビットのダウンロード

VSCode Windows 64 ビットのダウンロード

Microsoft によって発売された無料で強力な IDE エディター

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール