( 譯、持續更新 ) JavaScript 上分小技巧(三)

来源:http://www.cnblogs.com/ys-ys/archive/2016/02/04/5181088.html
-Advertisement-
Play Games

最近家裡雜事較多,自學時間實在少的可憐,所以都在空閑時間看看老外寫的內容,學習之外順便翻譯分享~等學習的時間充足些再寫寫自己的一些學習內容和知識點分析(最近有在接觸的:複習(C#,SQL)、(學習)TypeScript,(基礎操作)MongoDB。TypeScript之後入手AngularJs 2.


最近家裡雜事較多,自學時間實在少的可憐,所以都在空閑時間看看老外寫的內容,學習之外順便翻譯分享~等學習的時間充足些再寫寫自己的一些學習內容和知識點分析(最近有在接觸的:複習(C#,SQL)、(學習)TypeScript,(基礎操作)MongoDB。TypeScript之後入手AngularJs 2.0)

後續如有內容,本篇將會照常更新併排滿15個知識點,以下是其他幾篇譯文的地址:

第一篇地址:( 譯、持續更新 ) JavaScript 上分小技巧(一)

第二篇地址:( 譯、持續更新 ) JavaScript 上分小技巧(二)

#35 - 簡潔的代碼
對於我們懶惰的程式員來說,有時候打字都是浪費時間。所以,我們可以使用一些技巧來幫助我們,使我們的代碼更清潔和更簡單。
類似的使用:

x += 23; // x = x + 23;
y -= 15; // y = y - 15;
z *= 10; // z = z * 10;
k /= 7; // k = k / 7;
p %= 3; // p = p % 3;
d **= 2; // d = d ** 2;
m >>= 2; // m = m >> 2;
n <<= 2; // n = n << 2;
n ++; // n = n + 1;
n --; // n = n - 1;

if-else(使用三元運算符)

這是我們平常的規範寫法:

var newValue;
if(value > 10) 
  newValue = 5;
else
  newValue = 2;

我們可以使用三元運算符:

var newValue = (value > 10) ? 5 : 2;

null,undefined,空值檢查

if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
    var variable2 = variable1;
}

簡短的寫法:

var variable2 = variable1 || '';

註:如果variable1是一個數,將會先檢查它是否為0。

數組/對象的表示方法
數組:

var a = new Array();
a[0] = "myString1";
a[1] = "myString2";

我們用下麵的代碼代替上面的代碼:

var a = ["myString1", "myString2"];

對象:

var skillSet = new Array();
skillSet['Document language'] = 'HTML5';
skillSet['Styling language'] = 'CSS3';

我們使用下麵的代碼代替上面的代碼:

var skillSet = {
    'Document language' : 'HTML5', 
    'Styling language' : 'CSS3'
};

#34 - 執行非同步調用的迴圈
讓我們試著寫一個非同步函數,它每秒列印一次迴圈的索引值。

for (var i=0; i<5; i++) {
    setTimeout(function(){
        console.log(i); 
    }, 1000);
}

以上程式將會輸出:

_> 5
_> 5
_> 5
_> 5
_> 5

所以,它根本沒有正確的執行。
原因:
因為timeout的非同步,而每次的timeout指向的是原始的i,不是副本中的。所以迴圈直到i=5,然後timeout運行,並且列印當前的i(5)。
好吧,這個問題似乎很容易。一個馬上就可以解決的方案是即可將當前的i值當作一個臨時變數緩存在迴圈中。

for (var i=0; i<5; i++) {
    var temp = i;
    setTimeout(function(){
        console.log(i); 
    }, 1000);
}

但是上面的程式輸出的還是:

_> 5
_> 5
_> 5
_> 5
_> 5

所以,那也行不通,因為代碼塊不會創建一個作用域並且變數的初始化被提升到作用域的前面。事實上,和之前的代碼是一樣的:
解決方案:
有很多種不同的方案來複制i。最常見的是創建一個閉包,通過聲明一個函數,並將i作為參數傳入。在這裡,我們用自執行函數:

for (var i=0; i<5; i++) {
    (function(num){
        setTimeout(function(){
            console.log(num); 
        }, 1000); 
    })(i);  
}

在JavaScript中,參數是按值傳遞給函數。像數字、日期和字元串的原始類型基本上是複製的。如果你在函數內改變了它們,不影響它在外部範圍的值。對象是特殊的:如果內部函數改變了它的一個屬性,則在所有作用域中的對應值跟著變化。

#33 - 使用一行代碼簡單的創建一個[1,...,N]的範圍數組
下麵這行代碼能夠創建一個[1,...,N]的範圍數組

Array.apply(null,{length:N}).map(Fn,Context);

讓我們將這行代碼拆分成幾部分。我們都知道javascript的apply()函數的作用。在apply()里,第一個參數是根據第二個參數而來的上下文對象,它是被我們稱為apply()函數的參數列表。

function add(a, b){
    return (a+b);
}
add.apply(null,[5, 6]);

將會返回5+6的和。
javascript中的數組的map()函數有2個參數,第一個是回調函數,第二個是回調函數的上下文對象。回調函數有3個參數:value(值)、index(索引)、我們處理的整個陣列。所以普通語法是:

[1, 2, 3].map(function(value, index, arr){
    //Code
}, this);

下麵的這行代碼創建一個給定長度的數組:

Array.apply(null,{length:N});

把所有部分放到一起就是解決方案:

Array.apply(null,{length:N}).map(Fn,Context);

如果你想創建一個[1,...,N]的範圍數組:

Array.apply(null, {length: N}).map(function(value, index){
  return index+1;  
});

#32 - Map() 有秩序的給對象填加屬性
object是Object類型中的一個成員,它是個包含原始值、對象或者函數的一個無序的屬性集合。儲存在對象屬性中的函數被成為方法。ECMAScript
看以下代碼:

var myObject = {
    z: 1,
    '@': 2,
    b: 3,
    1: 4,
    5: 5
 };
console.log(myObject) // Object {1: 4, 5: 5, z: 1, @: 2, b: 3}
for (item in myObject) {...
// 1
// 5
// z
// @
// b

每個瀏覽器針對對象技術都有著各自的規則,所以秩序是不確定的。
怎麼解決這個問題呢?
Map
使用ES6中的一個新特性---Map。一個Map對象按插入的順序來迭代它的元素---for...of迴圈為每個迴圈項返回一個[key,value]形式的數組。

var myObject = new Map();
myObject.set('z', 1);
myObject.set('@', 2);
myObject.set('b', 3);
for (var [key, value] of myObject) {
  console.log(key, value);
...
// z 1
// @ 2
// b 3

舊瀏覽器的hack
Mozilla 建議:
因此,如果你想在一個交叉的瀏覽器環境中模擬一個有序的關聯數組,你不得不使用2個單獨的數組(一個鍵的數組和一個值的數組),或構建一個單屬性對象的數組等。

// 使用兩個數組
var objectKeys = [z, @, b, 1, 5];
for (item in myObject) {
    myObject[item]
...
// 創建一個單屬性對象的數組
var myData = [{z: 1}, {'@': 2}, {b: 3}, {1: 4}, {5: 5}];

#31 - 避免將"arguments"進行修改或者傳遞到其他函數 - 這將扼殺優化
背景:
在javascript的函數中,名為arguments的變數讓你能夠操作傳入函數的所有參數。arguments是個類似數組的object,arguments能夠使用數組符號來做操作,並且有length屬性,但是它不能改使用一些數組內置的方法,比如filter、map和forEach。正是因為如此,將參數轉換為數組來使用是一種相當普遍的做法:

var args = Array.prototype.slice.call(arguments);

從Array的prototypr中調用slice方法,傳入arguments;slice方法返回一個新的淺度複製arguments的數組對象。這是一個常用的速記法:

var args = [].slice.call(arguments);

在這個案例中,我們更簡單的用一個字面量的空數組來代替從Array的prototype調用slice方法。
優化:
不幸的是,在基於Chrome和Node的JavaScript V8引擎上,在函數內將arguments傳入任何其他函數都會導致性能變慢。看這篇文章:優化殺手。將arguments傳遞給任何其他函數稱為參數泄露。
作為替代,如果想要可以使用的參數數組,你需要做這些:

var args = new Array(arguments.length);
for(var i = 0; i < args.length; ++i) {
  args[i] = arguments[i];
}

這是更詳細的,但在生產代碼中,以這些來進行性能優化是值得的。

          ### 2016-02-04 更新 ###          


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 身處大天朝,必須學會的一項技能就是解決中文顯示問題。這個字元問題還搞了我一天,以下是個人解決亂碼問題的實踐結果,希望可以給其他人一些幫助 讀取xml文件代碼: 1 CCDictionary* message = CCDictionary::createWithContentsOfFile("chin
  • 官方文檔:http://zetcode.com/gui/pyqt4/ 中文文檔:http://www.qaulau.com/books/PyQt4_Tutorial/index.html 先記錄簡單的,以下代碼可顯示一個基本的window: #!/usr/bin/python # -*- codin
  • 有了以上的基本基礎,已經上面寫的幾個小練習,大家肯定有很多的不滿,比如查詢為什麼查詢一次就退出了呢?下麵我們來學習條件語句 一、萬惡的加號 以前我們在print的時候如果要加上變數都有是使用+來作為連接,但是這樣做是不好的 因為在使用加號的時候,會在記憶體中開闢新的記憶體地址來存放新的內容這樣做的壞處就
  • 獲取【下載地址】 QQ: 313596790 【免費支持更新】支持三大資料庫 mysql oracle sqlsever 更專業、更強悍、適合不同用戶群體A 代碼生成器(開發利器); 增刪改查的處理類,service層,mybatis的xml,SQL( mysql 和oracle)腳本, jsp頁面
  • 觀察者模式 定義了對象之間的一對多依賴,這樣一來,當一個對象改變狀態時,它的所有依賴者都會收到通知並自動更新。 觀察者模式需要實現兩個介面。observable(可觀察者)和observer(觀察者)。 observable定義了三個方法:register、remove、notify observe
  • 設計目標 儘量快的處理命令和事件,保證吞吐量; 處理完一個命令後不需要等待命令產生的事件持久化完成就能處理下一個命令,從而保證領域內的業務邏輯處理不依賴於持久化IO,實現真正的in-memory; 保證命令、事件處理的順序性,先來的先處理,先產生的先處理; 保證一個聚合根的事件只有一個線程在持久化,
  • 獲取【下載地址】 QQ: 313596790 【免費支持更新】支持三大資料庫 mysql oracle sqlsever 更專業、更強悍、適合不同用戶群體A 代碼生成器(開發利器); 增刪改查的處理類,service層,mybatis的xml,SQL( mysql 和oracle)腳本, jsp頁面
  • 最近做iOS開發的過程中, 發現要涉及到JS和原生OC(Swift)的交互, 作為一個Developer, 本著剋服一切問題的原則, 開始學習HTML, 在這裡記錄下自己的學習筆記, 方便以後的複習, 和新手初學的參考. HTML不同於過去學過的各種面向對象語言, 函數式語言, 它不像其他語言有明確
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...