您好,登錄后才能下訂單哦!
JavaScript概述
JavaScript是一種屬于網絡的高級腳本語言,已經被廣泛用于Web應用開發,常用來為網頁添加各式各樣的動態功能,為用戶提供更流暢美觀的瀏覽效果。通常JavaScript腳本是通過嵌入在HTML中來實現自身的功能的。
是一種解釋性腳本語言(代碼不進行預編譯)。
主要用來向HTML(標準通用標記語言下的一個應用)頁面添加交互行為。
可以直接嵌入HTML頁面,但寫成單獨的js文件有利于結構和行為的分離。
跨平臺特性,在絕大多數瀏覽器的支持下,可以在多種平臺下運行(如Windows、Linux、Mac、Android、iOS等)。
Javascript腳本語言同其他語言一樣,有它自身的基本數據類型,表達式和算術運算符及程序的基本程序框架。Javascript提供了四種基本的數據類型和兩種特殊數據類型用來處理數據和文字。而變量提供存放信息的地方,表達式則可以完成較復雜的信息處理。
可以實現web頁面的人機交互。
在 JavaScript 中 數組(Array)隨處可見,使用ECMAScript 6 中的新特性 擴展運算符 我們可以做很多很棒事情。
1. 迭代一個空數組
JavaScript 中直接創建的數組是松散的,以至于會有很多坑。試著用數組的構造方法創建一個數組,你就會瞬間明白了。
const arr = new Array(4); [undefined, undefined, undefined, undefined] // 谷歌瀏覽器中是 [empty x 4]
你會發現,通過一個松散的數組去循環調用一些轉換是非常難的。
const arr = new Array(4); arr.map((elem, index) => index); [undefined, undefined, undefined, undefined]
想要解決這個問題,你可以使用在創建新數組的時候使用 Array.apply。
const arr = Array.apply(null, new Array(4)); arr.map((elem, index) => index); [0, 1, 2, 3]
2. 給方法傳一個空參數
如果你想調用一個方法,并不填其中的一個參數時,JavaScript 就會報錯。
method('parameter1', , 'parameter3'); // Uncaught SyntaxError: Unexpected token ,
一個我們常用的解決方法是傳遞 null 或 undefined。
method('parameter1', null, 'parameter3') // or method('parameter1', undefined, 'parameter3');
根據 ES6 中對擴展運算符的介紹,有一個更簡潔的方法可以將空參數傳遞給一個方法。正如上面所提到的,數組是松散的,所以給它傳空值是可以的,我們正是用到了這個優點。
method(...['parameter1', , 'parameter3']); // 代碼執行了...
3. 數組去重
我一直不明白為什么數組不提供一個內置函數可以讓我們方便的取到去重以后的值。擴展運算符幫到了我們,使用擴展運算符配合 Set可以生成一個不重復的數組。
const arr = [...new Set([1, 2, 3, 3])]; // [1, 2, 3]
4.從后向前獲取數組元素
如果你想從后向前獲取一個數組的元素,可以這樣寫:
var arr = [1, 2, 3, 4] console.log(arr.slice(-1)) // [4] console.log(arr.slice(-2)) // [3, 4] console.log(arr.slice(-3)) // [2, 3, 4] console.log(arr.slice(-4)) // [1, 2, 3, 4]
5.短路條件句
如果你想在某個條件邏輯值為true時,執行某個函數,就像這樣:
if (condition) { dosomething() }
這時,你可以這樣子運用短路:
condition && dosomething()
6.用操作符 “||” 來設置默認值
如果你必須給一個變量賦默認值,可以簡單的這樣寫:
var a console.log(a) // undefined a = a || 'default value' console.log(a) // default value a = a || 'new value' console.log(a) // default value
7.在相等比較中使用 Object.is()
我們都知道 JavasSript 是弱類型的,并且當我們使用==作比較時,在一些情況下由于類型轉換或者說“把兩個操作數中的一個轉換成另一個,然后再比較”,會出現意想不到的結果。就像這樣:
0 == ' ' //true null == undefined //true [1] == true //true
因此 JavaScript 中給我們提供了全等操作符 ===, 它比不全等操作符更加嚴格并且不會發生類型轉換。但是用 === 來進行比較并不是最好的解決方案。你可能會得到:
NaN === NaN //false
ES6 中提供了新的 Object.is() 方法,它具有 === 的一些特點,而且更好、更精確,在一些特殊案例中表現的很好:
Object.is(0 , ' '); //false Object.is(null, undefined); //false Object.is([1], true); //false Object.is(NaN, NaN); //true
8.給一個函數 Bind 對象
我們經常需要將一個對象綁定到一個方法的 this 上。在 JS 中,如果你想要調用一個函數并指定它的 this 時可以使用 bind 方法。
Bind 語法
fun.bind(thisArg[, arg1[, arg2[, ...]]])
參數
thisArg
當綁定函數被調用時,該參數會作為原函數運行時的 this 指向。
arg1, arg2, …
當綁定函數被調用時,這些參數將置于實參之前傳遞給被綁定的方法。
返回值
返回由指定的this值和初始化參數改造的原函數拷貝
JS 中的實例
const myCar = { brand: 'Ford', type: 'Sedan', color: 'Red' }; const getBrand = function () { console.log(this.brand); }; const getType = function () { console.log(this.type); }; const getColor = function () { console.log(this.color); }; getBrand(); // object not bind,undefined getBrand(myCar); // object not bind,undefined getType.bind(myCar)(); // Sedan let boundGetColor = getColor.bind(myCar); boundGetColor(); // Red
9.獲取文件拓展名
解決方法 1: 正則表達式
function getFileExtension1(filename) { return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename)[0] : undefined; }
解決方法 2: String的split方法
function getFileExtension2(filename) { return filename.split('.').pop(); }
這兩種解決方法不能解決一些邊緣情況,這有另一個更加強大的解決方法。
解決方法 3: String的slice、lastIndexOf方法
function getFileExtension3(filename) { return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2); } console.log(getFileExtension3('')); // '' console.log(getFileExtension3('filename')); // '' console.log(getFileExtension3('filename.txt')); // 'txt' console.log(getFileExtension3('.hiddenfile')); // '' console.log(getFileExtension3('filename.with.many.dots.ext')); // 'ext'
這是如何實現的呢?
String.lastIndexOf() 方法返回指定值(本例中的'.')在調用該方法的字符串中最后出現的位置,如果沒找到則返回 -1。
對于'filename'和'.hiddenfile',lastIndexOf的返回值分別為0和-1無符號右移操作符(?>) 將-1轉換為4294967295,將-2轉換為4294967294,這個方法可以保證邊緣情況時文件名不變。
String.prototype.slice() 從上面計算的索引處提取文件的擴展名。如果索引比文件名的長度大,結果為""。
10.預防unapply攻擊
重寫內置對象的原型方法,外部代碼可以通過重寫代碼達到暴漏和修改已綁定參數的函數。這在es5的方法下使用polyfill時是一個嚴重的安全問題。
// bind polyfill 示例 function bind(fn) { var prev = Array.prototype.slice.call(arguments, 1); return function bound() { var curr = Array.prototype.slice.call(arguments, 0); var args = Array.prototype.concat.apply(prev, curr); return fn.apply(null, args); }; } // unapply攻擊 function unapplyAttack() { var concat = Array.prototype.concat; Array.prototype.concat = function replaceAll() { Array.prototype.concat = concat; // restore the correct version var curr = Array.prototype.slice.call(arguments, 0); var result = concat.apply([], curr); return result; }; }
上面的函數聲明忽略了函數bind的prev參數,意味著調用unapplyAttack之后首次調用.concat將會拋出錯誤。
使用Object.freeze,可以使對象不可變,你可以防止任何內置對象原型方法被重寫。
(function freezePrototypes() { if (typeof Object.freeze !== 'function') { throw new Error('Missing Object.freeze'); } Object.freeze(Object.prototype); Object.freeze(Array.prototype); Object.freeze(Function.prototype); }());
11.Javascript多維數組扁平化
下面是將多位數組轉化為單一數組的三種不同方法。
var arr = [[1, 2],[3, 4, 5], [6, 7, 8, 9]];
期望結果:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
解決方案1:使用concat()和apply()
var newArr = [].concat.apply([], arr); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
解決方案2:使用reduce()
var newArr = arr.reduce(function(prev, curr) { return prev.concat(curr); }); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
解決方案3:使用 ES6 的展開運算符
var newArr = [].concat(...arr); console.log(newArr); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
12. 函數中如何使用可選參數(包括可選回調函數)
實例函數中第2個與第3個參數為可選參數
function example( err, optionA, optionB, callback ) { // 使用數組取出arguments var args = new Array(arguments.length); for(var i = 0; i < args.length; ++i) { args[i] = arguments[i]; }; // 第一個參數為錯誤參數 // shift() 移除數組中第一個參數并將其返回 err = args.shift(); // 如果最后一個參數是函數,則它為回調函數 // pop() 移除數組中最后一個參數并將其返回 if (typeof args[args.length-1] === 'function') { callback = args.pop(); } // 如果args中仍有元素,那就是你需要的可選參數 // 你可以像這樣一個一個的將其取出: if (args.length > 0) optionA = args.shift(); else optionA = null; if (args.length > 0) optionB = args.shift(); else optionB = null; // 像正常一樣繼續:檢查是否有錯誤 if (err) { return callback && callback(err); } // 打印可選參數 console.log('optionA:', optionA); console.log('optionB:', optionB); console.log('callback:', callback); /* 你想做的邏輯 */ } // ES6語法書寫更簡短 function example(...args) { // 第一個參數為錯誤參數 const err = args.shift(); // 如果最后一個參數是函數,則它為回調函數 const callback = (typeof args[args.length-1] === 'function') ? args.pop() : null; // 如果args中仍有元素,那就是你需要的可選參數你可以像這樣一個一個的將其取出: const optionA = (args.length > 0) ? args.shift() : null; const optionB = (args.length > 0) ? args.shift() : null; // ... 重復取更多參數 if (err && callback) return callback(err); /* 你想做的邏輯 */ }
以上就是JavaScript的技巧的詳細內容,更多請關注億速云其它相關文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。