欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript小技巧整理篇(非常全)

 更新時(shí)間:2016年01月26日 10:56:18   作者:野獸''  
這篇文章主要介紹了JavaScript小技巧整理篇(非常全)的相關(guān)資料,需要的朋友可以參考下

能夠?yàn)榇蠹姨峁┻@些簡短而實(shí)用的JavaScript技巧來提高大家編程能力,這對(duì)于我來說是件很開心的事。每天僅花上不到2分鐘的時(shí)間中,你將可以讀遍JavaScript這門可怕的語言所呈現(xiàn)給我們的特性:performance(性能), conventions(協(xié)議), hacks(代碼hack), interview questions(面試問題)及所有其他的項(xiàng)。

#24 - 使用 === 代替 ==

==(或者!=)做對(duì)比的時(shí)候會(huì)將進(jìn)行對(duì)比的兩者轉(zhuǎn)換到同一類型再比較。===(或者!==)則不會(huì),他會(huì)將進(jìn)行對(duì)比的兩者做類型對(duì)比和值對(duì)比,相對(duì)于 == ,=== 的對(duì)比會(huì)更加嚴(yán)謹(jǐn)。

[10] == 10 // true
[10] === 10 // false
"10" == 10 // true
"10" === 10 // false
[] == 0 // true
[] === 0 // false
"" == false // true 但是 true == "a" 是false
"" === false // false 

#23 - 轉(zhuǎn)換數(shù)值的更加的方法

將字符串轉(zhuǎn)換為數(shù)字是非常常見的。最簡單和最快的(jspref)的方式來實(shí)現(xiàn),將使用+(加)算法。

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

你也可以使用-(減號(hào))算法的轉(zhuǎn)換類型并且變成負(fù)數(shù)值。

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

#22 - 清空一個(gè)數(shù)組

你定義一個(gè)數(shù)組,并希望清空它的內(nèi)容。通常,你會(huì)這樣做:

var list = [1, 2, 3, 4];
function empty() {
//清空數(shù)組
list = [];
}
empty(); 

但是還有一種更高性能的方法。

你可以使用這些代碼:

var list = [1, 2, 3, 4];
function empty() {
//清空數(shù)組
list.length = 0;
}
empty(); 

· list =[] 將一個(gè)變量指定個(gè)引用到那個(gè)數(shù)組,而其他引用都不受影響。這意味著,對(duì)于先前數(shù)組的內(nèi)容的引用仍然保留在內(nèi)存中,從而導(dǎo)致內(nèi)存泄漏。
· list.length = 0 刪除數(shù)組內(nèi)的所有東西,這不需要引用任何其他的東西
然而,如果你有一個(gè)copy的數(shù)組(A和copy-A),如果你使用list.length = 0 刪除其內(nèi)容,副本也會(huì)失去它的內(nèi)容。

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

#21 - 對(duì)數(shù)組排序進(jìn)行"洗牌"(隨機(jī)排序)

這段代碼在這里使用Fisher Yates洗牌算法給一個(gè)指定的數(shù)組進(jìn)行洗牌(隨機(jī)排序)。

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 - 返回對(duì)象的函數(shù)能夠用于鏈?zhǔn)讲僮?/span>

當(dāng)創(chuàng)建面向?qū)ο蟮腏avaScript對(duì)象的function時(shí),函數(shù)返回一個(gè)對(duì)象將能夠讓函數(shù)可鏈?zhǔn)降膶懺谝黄饋韴?zhí)行。

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 - 字符串安全連接

假設(shè)你有一些類型未知的變量,你想將它們連接起來。可以肯定的是,算法操作不會(huì)在級(jí)聯(lián)時(shí)應(yīng)用:

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

這樣的連接不正是你所期望的。相反,一些串聯(lián)和相加可能會(huì)導(dǎo)致意想不到的結(jié)果:

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

談到性能,對(duì)join和concat進(jìn)行比較,他們的執(zhí)行速度是幾乎一樣的。你可以在MDN了解更多與concat相關(guān)的知識(shí)

#18 - 更快的四舍五入

今天的技巧是關(guān)于性能。見到過雙波浪線"~~"操作符嗎?它有時(shí)也被稱為double NOT運(yùn)算符。你可以更快的使用它來作為Math.floor()替代品。為什么呢?
單位移~將32位轉(zhuǎn)換輸入-(輸入+1),因此雙位移將輸入轉(zhuǎn)換為-(-(輸入+1)),這是個(gè)趨于0的偉大的工具。對(duì)于輸入的數(shù)字,它將模仿Math.ceil()取負(fù)值和Math.floor()取正值。如果執(zhí)行失敗,則返回0,這可能在用來代替Math.floor()失敗時(shí)返回一個(gè)NaN的時(shí)候發(fā)揮作用。

// 單位移
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位整數(shù)則失敗
console.log(~~(2147483647 + 1) === (2147483647 + 1)) // -> 0 

雖然~~可能有更好的表現(xiàn),為了可讀性,請(qǐng)使用Math.floor()。

#17 - Node.js:讓module在沒被require的時(shí)候運(yùn)行

在node里,你可以根據(jù)代是運(yùn)行了require('./something.js')還是node something.js,來告訴你的程序去做兩件不同的事情。如果你想與你的一個(gè)獨(dú)立的模塊進(jìn)行交互,這是很有用的。

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

更多信息,請(qǐng)看the documentation for modules

#16 - 給回調(diào)函數(shù)傳遞參數(shù)

在默認(rèn)情況下,你無法將參數(shù)傳給回調(diào)函數(shù),如下:

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

你可以采取JavaScript閉包的優(yōu)點(diǎn)來給回調(diào)函數(shù)傳參,案例如下:

function callback(a, b) {
return function() {
console.log('sum = ', (a+b));
}
}
var x = 1, y = 2;
document.getElementById('someelem').addEventListener('click', callback(x, y)); 

什么是閉包呢?閉包是指一個(gè)針對(duì)獨(dú)立的(自由)變量的函數(shù)。換句話說,閉包中定義的函數(shù)會(huì)記住它被創(chuàng)建的環(huán)境。了解更多請(qǐng)參閱MDN所以這種方式當(dāng)被調(diào)用的時(shí)候,參數(shù)X/Y存在于回調(diào)函數(shù)的作用域內(nèi)。

另一種方法是使用綁定方法。例如:

var alertText = function(text) {
alert(text);
};
document.getElementById('someelem').addEventListener('click', alertText.bind(this, 'hello')); 

兩種方法在性能上有一些略微區(qū)別,詳情參閱jsperf

#15 - 使用更簡單的類似indexOf的包含判斷方式

原生的JavaScript沒有contains方法。對(duì)檢查字符串或字符串?dāng)?shù)組項(xiàng)中是否存在某值,你可以這樣做:

var someText = 'JavaScript rules';
if (someText.indexOf('JavaScript') !== -1) {
}
// 或者
if (someText.indexOf('JavaScript') >= 0) {
} 

但是我們?cè)倏纯催@些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')); 

問題是~位運(yùn)算符。"運(yùn)算符執(zhí)行操作這樣的二進(jìn)制表達(dá)式,但他們返回標(biāo)準(zhǔn)的JavaScript的數(shù)值."
他們將-1轉(zhuǎn)換為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()方法可以用來確定是否一個(gè)字符串包含另一個(gè)字符串:

'something'.includes('thing'); // true

在ECMAScript 2016 (ES7)中,甚至數(shù)組都可以這樣操作,如indexOf:

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

不幸的是,這只是在Chrome,F(xiàn)irefox,Safari 9或以上的瀏覽器中被支持。

#14 - arrow 函數(shù)(ES6)

介紹下ES6里的新功能,arrow函數(shù)可能會(huì)是個(gè)很方便的工具,用更少行數(shù)寫更多代碼。他的名字來源于他的語法,=>和小箭頭->比就像一個(gè)“胖胖的箭頭”。可能有些人知道,這種函數(shù)類型和其他靜態(tài)語言如lambda表達(dá)式的匿名函數(shù)。它被稱為匿名,因?yàn)檫@些箭頭函數(shù)沒有一個(gè)描述性的函數(shù)名。
那么這樣有什么好處呢?

語法:更少的LOC,不用一次次的鍵入函數(shù)關(guān)鍵字。

語義:從上下文中捕捉關(guān)鍵字this。

簡單語法案例:

看看下面的兩段代碼片段,他們做的是一樣的工作。你能很快的理解arrow函數(shù)的功能。

// arrow函數(shù)的日常語法
param => expression
// 可能也會(huì)寫在括號(hào)中
// 括號(hào)是多參數(shù)要求
(param1 [, param2]) => expression

// 使用日常函數(shù)
var arr = [5,3,2,9,1];
var arrFunc = arr.map(function(x) {
return x * x;
});
console.log(arr)

// 使用arrow函數(shù)
var arr = [5,3,2,9,1];
var arrFunc = arr.map((x) => x*x);
console.log(arr) 

正如你所看到的,這個(gè)例子中的arrow函數(shù)可以節(jié)省你輸入括號(hào)內(nèi)參數(shù)和返回關(guān)鍵字的時(shí)間。建議把圓括號(hào)內(nèi)的參數(shù)輸入,如 (x,y) => x+y 。在不同的使用情況下,它只是

用來應(yīng)對(duì)遺忘的一種方式。但是上面的代碼也會(huì)這樣執(zhí)行:x => x*x.目前看來,這些僅僅是導(dǎo)致更少的LOC和更好的可讀性的句法改進(jìn)。

this 綁定

還有一個(gè)更好的理由使用arrow函數(shù)。那就是在會(huì)出現(xiàn)this問題的背景下。使用arrow函數(shù),你就不用擔(dān)心.bind(this)和 that=this 了。因?yàn)閍rrow函數(shù)會(huì)從上下文中找到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` 實(shí)例 (!! 忽略這里)
this.i = 0;
setInterval(function () {
// `this` 指全局對(duì)象,而不是 CounterA's `this`
// 因此,開始計(jì)數(shù)與100,而不是0 (本地的 this.i)
this.i++;
document.getElementById("counterA").innerHTML = this.i;
}, 500);
}
// 手動(dòng)綁定 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函數(shù)
function CounterD() {
this.i = 0;
setInterval(() => {
this.i++;
document.getElementById("counterD").innerHTML = this.i;
}, 500);
}

關(guān)于arrow函數(shù)的進(jìn)一步信息可以看這里 。查看不同的語法選請(qǐng)?jiān)L問該站點(diǎn)。

#13 - 測量一個(gè)JavaScript代碼塊性能的技巧

快速測量一個(gè)JavaScript塊的性能,我們可以使用控制臺(tái)的功能像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 (在瀏覽器控制臺(tái)輸出)

#12 - ES6中參數(shù)處理

在許多編程語言中,函數(shù)的參數(shù)是默認(rèn)的,而開發(fā)人員必須顯式定義一個(gè)參數(shù)是可選的。在JavaScript中的每個(gè)參數(shù)是可選的,但我們可以這一行為而不讓一個(gè)函數(shù)利用ES6的默認(rèn)值作為參數(shù)。

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是立即拋出一個(gè)錯(cuò)誤的函數(shù)。如果沒有一個(gè)參數(shù)作為值,默認(rèn)值是會(huì)被使用,_err將被調(diào)用,將拋出錯(cuò)誤。你可以在Mozilla開發(fā)者網(wǎng)絡(luò)看到的更多默認(rèn)參數(shù)的例子。

#11 - 提升

理解提升將幫助你組織你的function。只需要記住,變量聲明和定義函數(shù)會(huì)被提升到頂部。變量的定義是不會(huì)的,即使你在同一行中聲明和定義一個(gè)變量。此外,變量聲明讓系統(tǒng)知道變量存在,而定義是將其賦值給它。

function doTheThing() {
// 錯(cuò)誤: 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!');
}
// 錯(cuò)誤: undefined is not a function
functionVar();
var functionVar = function(){
console.log('I did it!');
}
}

為了使事情更容易閱讀,在函數(shù)作用域內(nèi)提升變量的聲明將會(huì)讓你明確該變量的聲明是來自哪個(gè)作用域。在你需要使用變量之前定義它們。在作用域底部定義函數(shù),確保代碼清晰規(guī)范。

#10 - 檢查一個(gè)對(duì)象是否有屬性

當(dāng)你要檢查一個(gè)對(duì)象是否存在某個(gè)屬性時(shí),你可能會(huì)這樣做 :

var myObject = {
name: '@tips_js'
};
if (myObject.name) { ... } 

這是可以的,但你必須知道這個(gè)還有兩原生的方式,in operator 和 object.hasownproperty,每個(gè)對(duì)象是對(duì)象,既可用方法。每個(gè)object都繼承自O(shè)bject,這兩個(gè)方法都可用。

兩個(gè)方法的一些不同點(diǎn):

var myObject = {
name: '@tips_js'
};
myObject.hasOwnProperty('name'); // true
'name' in myObject; // true
myObject.hasOwnProperty('valueOf'); // false, valueOf 是從原型鏈繼承的
'valueOf' in myObject; // true 

他們之間的不同在于檢查的性質(zhì),換句話說,當(dāng)該對(duì)象本身有查找的屬性時(shí)hasOwnProperty返回yrue,然而,in operator不區(qū)分屬性創(chuàng)建的對(duì)象和屬性繼承的原型鏈。
這里有另外一個(gè)例子:

var myFunc = function() {
this.name = '@tips_js';
};
myFunc.prototype.age = '10 days';
var user = new myFunc();
user.hasOwnProperty('name'); // true
user.hasOwnProperty('age'); // false, 因?yàn)閍ge是原型鏈上的 

點(diǎn)擊看例子。同時(shí),建議在檢查對(duì)象的屬性存在時(shí),閱讀這些有關(guān)的常見錯(cuò)誤。

#09 - 模板字符串

截至ES6,JS已經(jīng)有模板字符串作為替代經(jīng)典的結(jié)束引用的字符串。
案例:普通字符串

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或者簡單邏輯來實(shí)現(xiàn)多行字符串。
您還可以使用函數(shù)來修改模板字符串的輸出,它們被稱為模板字符串的標(biāo)記。你可能還想讀到更多的理解模板字符串相關(guān)信息。

#08 - 將節(jié)點(diǎn)列表轉(zhuǎn)換為數(shù)組

querySelectorAll 方法返回一個(gè)和數(shù)組類似的節(jié)點(diǎn)列表對(duì)象。這些數(shù)據(jù)結(jié)構(gòu)類似數(shù)組,因?yàn)榻?jīng)常以數(shù)組形式出現(xiàn),但是又不能用數(shù)組的方法,比如map和foreach。這里是一個(gè)快速、安全、可重用的方式將一個(gè)節(jié)點(diǎn)列表到一個(gè)DOM元素?cái)?shù)組:

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

apply方法是將一系列數(shù)組格式的參數(shù)傳遞給一個(gè)給定this的函數(shù)。MDN指出,apply將會(huì)調(diào)用類似數(shù)組的對(duì)象,而這正是querySelectorAll所返回的。因?yàn)槲覀儾恍枰诤瘮?shù)的上下文中指定this,所以我們傳入null或0。返回的結(jié)果是一組能使用數(shù)組方法的DOM元素?cái)?shù)組。

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

const nodelist = [...document.querySelectorAll('div')]; // 返回的是個(gè)真實(shí)的數(shù)組
//later on ..
nodelist.forEach(...);
nodelist.map(...);
nodelist.slice(...);
//etc... 

#07 - "use strict" 和懶惰

嚴(yán)格模式的JavaScript讓開發(fā)人員更加安全的編寫JavaScript。
默認(rèn)情況下,JavaScript允許開發(fā)者懶惰,例如,我們?cè)诘谝淮温暶髯兞康臅r(shí)候可以不用var,雖然這可能看起來像一個(gè)沒有經(jīng)驗(yàn)的開發(fā)人員,同時(shí)這也是很多錯(cuò)誤的根源,變量名拼寫錯(cuò)誤或意外地將它提到了外部作用域。

程序員喜歡讓電腦為我們做些無聊的事,檢查一些我們工作的錯(cuò)誤。"use strict"指令我們做這些,將我們的錯(cuò)誤轉(zhuǎn)換成JavaScript的錯(cuò)誤。

我們把這個(gè)指令可以通過添加在一個(gè)js文件的頂部:

// 整個(gè)script文件都將是嚴(yán)格模式語法
"use strict";
var v = "Hi! I'm a strict mode script!";
或者在函數(shù)內(nèi):
function f()
{
// 函數(shù)范圍內(nèi)的嚴(yán)格模式語法
'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."; }

在包含這個(gè)指令的JavaScript文件或者函數(shù)內(nèi),我們將一些較大的JavaScript項(xiàng)目中的不良行為直接在JavaScript引擎執(zhí)行中禁止了。在其他情況中,嚴(yán)格模式改變以下的行為:

· 變量只有在前面 var 聲明了才能用
· 試圖寫入只讀屬性產(chǎn)生的誤差
· 必須用 new 關(guān)鍵字調(diào)用構(gòu)造函數(shù)
· this 不會(huì)默認(rèn)指向全局對(duì)象
· 非常有限的使用eval()
· 保護(hù)保留字符或未來保留字符不被作為變量名使用

嚴(yán)格模式在新項(xiàng)目中是很有好處的,但是在大多數(shù)地方?jīng)]使用到它的老項(xiàng)目里使用它是非常具有挑戰(zhàn)性的。當(dāng)你把多個(gè)文件合并到一個(gè)文件時(shí),它也是個(gè)問題,就像可能導(dǎo)致整個(gè)文件都在嚴(yán)格模式下執(zhí)行。
它不是一個(gè)聲明,只是一個(gè)字面量,早期版本的瀏覽器會(huì)忽略它。嚴(yán)格模式支持:

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

參閱MDN對(duì)于嚴(yán)格模式的描述。

#06 - 處理一個(gè)數(shù)組或單個(gè)元素作為參數(shù)的方法

相比于寫個(gè)單獨(dú)的方法去分別操作一個(gè)數(shù)組和一個(gè)元素作為參數(shù)的函數(shù),更好的是寫一個(gè)通用的函數(shù),這樣就都可以操作。這類似于一些jQuery的方法(css匹配將修改所有的選擇器)。
你僅需要先將一切放進(jìn)數(shù)組,Array.concat會(huì)接收數(shù)組或單一的對(duì)象:

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

printUpperCase現(xiàn)在可以接收無論單一的元素作為參數(shù)還是一個(gè)數(shù)組:

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

#05 - undefined 和 null 的不同

· undefined指的是一個(gè)變量未被聲明,或者一個(gè)變量被聲明但未賦值
· null是指一個(gè)特定的值,即"沒有值"
. JavaScript給未賦值的變量默認(rèn)定義為undefined
· JavaScript不會(huì)給未賦值的變量設(shè)置null值,它被程序員用來表示一個(gè)無價(jià)值的值
· undefined在json格式數(shù)據(jù)中是無效的,而null有效
· undefined 類型是 undefined
· null類似是object.為什么呢?
· 兩者都是原始值
· 兩者都被認(rèn)為false(Boolean(undefined) // false, Boolean(null) // false)。
· 辨認(rèn)變量是不是undefined

typeof variable === "undefined"
· 檢查變量是不是null

variable === "null"
從值考慮他們是相等的,但是從類型和值共同考慮他們是不相等的

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

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

JavaScript有個(gè)原生的方法對(duì)字符串格式的數(shù)組進(jìn)行排序,做一個(gè)簡單的array.sort()將會(huì)把字符串們按首字母的數(shù)序排列。當(dāng)然,也可以提供自定義排序功能。

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

當(dāng)你試圖用非ASCII字符,如 ['é', 'a', 'ú', 'c']這樣的進(jìn)行排序,你會(huì)得到一個(gè)奇怪的結(jié)果['c', 'e', 'á', 'ú'],因?yàn)橹挥杏糜⒄Z的語言才能排序,所以發(fā)生這種情況。

看一個(gè)簡單的例子:

// Spanish
['único','árbol', 'cosas', 'fútbol'].sort();
// ["cosas", "fútbol", "árbol", "único"] // 錯(cuò)誤的排序
// German
['Woche', 'wöchentlich', 'wäre', 'Wann'].sort();
// ["Wann", "Woche", "wäre", "wöchentlich"] // 錯(cuò)誤的排序 

幸運(yùn)的是,有兩種方法來避免這種行為,ECMAScript國際化的API提供了localecompare和and Intl.Collator。
這兩種方法都有自己的自定義參數(shù),以便將其配置來充分的完成功能。

使用 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"] 

· 每個(gè)方法都可以自定義位置

· 在FF瀏覽器,intl.collator()會(huì)更快,當(dāng)比較的是較大的數(shù)值或字符串
因此,當(dāng)你在用英語以外的語言來賦值給字符串?dāng)?shù)組時(shí),記得要使用此方法來避免意外的排序。

#03 - 改善嵌套條件

我們?cè)鯓硬拍芨纳撇⑶沂笿avaScript中的if語句做出更有效的嵌套。

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

一個(gè)改善的辦法是用switch語句代替嵌套的if語句。雖然它是更加簡潔,更加有序,但不推薦這樣做,因?yàn)楹茈ydebug。這里指出原因。

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

但是,當(dāng)我們有多個(gè)判斷條件的情況下呢?在這種情況下,如果我們想讓它更加簡潔,更加有序,我們可以使用switch。如果我們將true的作為一個(gè)參數(shù)傳遞給該switch語句,它可以讓我們?cè)诿恳粋€(gè)情況下放置一個(gè)條件。

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;
}

但我們必須避免在每一個(gè)條件下進(jìn)行多次檢查,盡量避免使用switch。我們也必須考慮到最有效的方法是通過一個(gè)object。

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

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

這里有更多相關(guān)的信息。

#02 - ReactJs 子級(jí)構(gòu)造的keys是很重要的

keys是代表你需要傳遞給動(dòng)態(tài)數(shù)組的所有組件的一個(gè)屬性。這是一個(gè)獨(dú)特的和指定的ID,react用它來標(biāo)識(shí)每個(gè)DOM組件以用來知道這是個(gè)不同的組件或者是同一個(gè)組件。使用keys來確保子組件是可保存的并且不是再次創(chuàng)造的,并且防止怪異事情的產(chǎn)生。

· 使用已存在的一個(gè)獨(dú)立的對(duì)象值
· 定義父組件中的鍵,而不是子組件

//不好的
...
render() {
<div key={{item.key}}>{{item.name}}</div>
}
...
//好的
<MyComponent key={{item.key}}/> 
· 使用數(shù)組不是個(gè)好習(xí)慣
· random()從不會(huì)執(zhí)行
//不好的
<MyComponent key={{Math.random()}}/> 

· 你可以創(chuàng)建你的唯一id,請(qǐng)確保該方法是快速的并已經(jīng)附加到對(duì)象上的
· 當(dāng)子級(jí)的數(shù)量是龐大的或包含復(fù)雜的組件,使用keys來提高性能
· 你必須為所有的子級(jí)ReactCSSTransitionGroup提供key屬性

#01 - AngularJs: $digest vs $apply

AngularJs最讓人欣賞的特點(diǎn)是雙向數(shù)據(jù)綁定。為了是它工作,AngularJs評(píng)估模型的變化和視圖的循環(huán)($digest)。你需要了解這個(gè)概念,以便了解框架是如何在引擎中工作的。
Angular評(píng)估每時(shí)的每個(gè)事件的變化。這就是$digest循環(huán)。有時(shí)你必須手動(dòng)運(yùn)行一個(gè)新的循環(huán),你必須有正確的選擇,因?yàn)檫@個(gè)階段是性能方面表現(xiàn)出最具影響力的。

$apply

這個(gè)核心方法讓你來啟動(dòng)一個(gè)$digest循環(huán)。這意味著所以的watch列表中的對(duì)象都將被檢查,整個(gè)應(yīng)用程序啟動(dòng)了$digest循環(huán)。在內(nèi)部,執(zhí)行可選的函數(shù)參數(shù)之后,調(diào)用$rootScope.$digest();

$digest

在這種情況下,$digest方法在當(dāng)前作用域和它的子作用域執(zhí)行,你應(yīng)該注意到,父級(jí)的作用域?qū)⒉槐粰z查,并沒有受到影響。
建議:

· 只在瀏覽器DOM事件在Angular之外被觸發(fā)的時(shí)候使用$apply或者$digest
· 給$apply傳遞函數(shù)表達(dá)式,這有一個(gè)錯(cuò)誤處理機(jī)制,允許在消化周期中整合變化。

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

· 如果你僅僅想更新當(dāng)前作用域或者他的子作用域,用$digest,并且防止整個(gè)應(yīng)用程序的$digest。性能不言而喻咯。
· 當(dāng)$apply有很多東西綁定時(shí),這對(duì)機(jī)器來說是個(gè)艱難的過程,可能會(huì)導(dǎo)致性能問題。
· 如果你使用的是Angular 1.2.x以上的,使用$evalAsync。這是一個(gè)在當(dāng)前循環(huán)或下一次循環(huán)的期間或?qū)Ρ磉_(dá)式做出評(píng)估的核心方法,這可以提高你的應(yīng)用程序的性能。

#00 - 在數(shù)組插入一個(gè)項(xiàng)

將一個(gè)項(xiàng)插入到現(xiàn)有數(shù)組中,是一個(gè)日常常見的任務(wù),你可以使用push在數(shù)組的末尾添加元素,使用unshift在開始的位置,或者在中間使用splice。

這些都是已知的方法,但這并不意味著沒有一個(gè)更高性能的途徑。我們來看一看。
在數(shù)組的末尾添加一個(gè)元素很容易與push(),但還有一個(gè)更高性能的途徑。

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% 的速度 

這兩種方法都修改了數(shù)組,不相信我?看這個(gè)jsperf
現(xiàn)在,如果我們正在嘗試將一個(gè)項(xiàng)目添加到數(shù)組的開頭:

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% 的速度 

這里更詳細(xì)一點(diǎn):unshift編輯原有的數(shù)組,concat返回一個(gè)新數(shù)組。jsperf
添加在陣列中的物品很容易使用splice,它是做它的最高效的方式。

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

我試著在不同的瀏覽器和操作系統(tǒng)中運(yùn)行這些測試,結(jié)果是相似的。我希望這些建議對(duì)你有用,鼓勵(lì)你自己做測試!

相關(guān)文章

  • js實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘

    js實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘

    這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)動(dòng)態(tài)時(shí)鐘,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • JavaScript?數(shù)組基本操作全解

    JavaScript?數(shù)組基本操作全解

    今天這篇文章就是來和大家詳細(xì)聊聊JavaScript中數(shù)組的基本操作,很多語言都是在數(shù)組這有個(gè)分水嶺。聽懂了接下來就很容易,聽不懂就難辦了,大家要認(rèn)真看喲。希望大家讀完有所收獲,那我辛苦碼字也就值了
    2022-02-02
  • JavaScript數(shù)組和對(duì)象的復(fù)制

    JavaScript數(shù)組和對(duì)象的復(fù)制

    本篇文章主要介紹了JavaScript數(shù)組和對(duì)象的復(fù)制的相關(guān)知識(shí)。具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-03-03
  • JS中Math對(duì)象使用示例(秒懂如何使用Math對(duì)象)

    JS中Math對(duì)象使用示例(秒懂如何使用Math對(duì)象)

    這篇文章主要給大家介紹了關(guān)于JS中Math對(duì)象使用的相關(guān)資料,Math和其他的對(duì)象不同,它不是一個(gè)構(gòu)造函數(shù),它屬于一個(gè)工具類,不用創(chuàng)建對(duì)象,它里面封裝了數(shù)學(xué)運(yùn)算相關(guān)的屬性和方法,需要的朋友可以參考下
    2024-06-06
  • Javascript改變CSS樣式(局部和全局)

    Javascript改變CSS樣式(局部和全局)

    改變CSS樣式分為局部和全局,下面為大家介紹下使用Javascript具體的實(shí)現(xiàn),感興趣的朋友可以參考下
    2013-12-12
  • 微信小程序?qū)崿F(xiàn)購物車代碼實(shí)例詳解

    微信小程序?qū)崿F(xiàn)購物車代碼實(shí)例詳解

    這篇文章主要介紹了微信小程序?qū)崿F(xiàn)購物車代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • js 求時(shí)間差的實(shí)現(xiàn)代碼

    js 求時(shí)間差的實(shí)現(xiàn)代碼

    下面小編就為大家?guī)硪黄猨s 求時(shí)間差的實(shí)現(xiàn)代碼。小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家。也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-04-04
  • js 創(chuàng)建一個(gè)浮動(dòng)div的代碼

    js 創(chuàng)建一個(gè)浮動(dòng)div的代碼

    js 創(chuàng)建一個(gè)浮動(dòng)div的代碼,一般用來指導(dǎo)用戶下面的操作與多條件選擇。點(diǎn)擊一下就可顯示,具體的大家可以自由發(fā)揮。
    2009-12-12
  • JavaScript實(shí)現(xiàn)頁面跳轉(zhuǎn)的5種方法總結(jié)

    JavaScript實(shí)現(xiàn)頁面跳轉(zhuǎn)的5種方法總結(jié)

    在前臺(tái)開發(fā)中會(huì)涉及頁面跳轉(zhuǎn)的問題,下面這篇文章主要給大家總結(jié)介紹了關(guān)于JavaScript實(shí)現(xiàn)頁面跳轉(zhuǎn)的5種方法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • 原生js添加節(jié)點(diǎn)appendChild、insertBefore方式

    原生js添加節(jié)點(diǎn)appendChild、insertBefore方式

    這篇文章主要介紹了原生js添加節(jié)點(diǎn)appendChild、insertBefore方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評(píng)論