JSの使い方のヒントをまとめました

php中世界最好的语言
リリース: 2018-04-23 09:17:58
オリジナル
1301 人が閲覧しました

今回はJSの使い方スキルとJSを使う際の注意点についてまとめてみました。以下は実際の事例ですので見ていきましょう。

あなたのプログラミング スキルを向上させるために、これらの短くて実用的な 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 の詳細: 差分-between-array-length-0-and-array

#21 - 「シャッフル」 (ランダムにソート) 配列のソート

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

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) に変換するため、ダブル シフトは入力を -(-(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(&#39;a is not defined&#39;), b = _err(&#39;b is not defined&#39;)) => 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('p');
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('p')]; // 返回的是个真实的数组
//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öchentlich', 'wäre', 'Wann'].sort();
// ["Wann", "Woche", "wäre", "wö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öchentlich', 'wäre', 'Wann'].sort(function (a, b) {
return a.localeCompare(b);
});
// ["Wann", "wäre", "Woche", "wöchentlich"]
ログイン後にコピー

使用 intl.collator()

['único','árbol', 'cosas', 'fútbol'].sort(Intl.Collator().compare);
// ["árbol", "cosas", "fútbol", "único"]
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort(Intl.Collator().compare);
// ["Wann", "wäre", "Woche", "wö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() {
<p key={{item.key}}>{{item.name}}</p>
}
...
//好的
<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');
ログイン後にコピー

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

JS发送json格式POST请求实现步奏

根据环境传递参数方法选择不同域名

以上がJSの使い方のヒントをまとめましたの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!