-
一些優(yōu)雅的寫法
邏輯運算符if (a == 1) { b() } // 可以寫成 a == 1 && b() if (conected) { login(); } // 可以寫成 conected && login(); // 如果一些屬性或函數(shù)存在于一個對象中,你也可以這樣做檢測,如下面的代碼所示: user && user.login();初始化變量
var a = obj || {} var name = name || "Oliver Queen"; -
類型轉換
("""" + ) > String() > .toString() > new String() 多字符串拼接,先壓數(shù)組,后
join盡量使用直接量,區(qū)別在于引擎直接解釋和調用具體數(shù)據(jù)類型內(nèi)部構造器。
字符串操作盡量不用循環(huán),而使用正則表達式,區(qū)別在于JavaScript引擎運行邏輯與調用C語言API。
同理,三元比較返回大小與
Math.min相比,應選擇后者。自定義高級對象和
Date、RegExp對象在構造時都會消耗大量時間。如果可以復用,應采用緩存的方式。JavaScript中各種高度、寬度:辨析詳解:
| Name | Code |
|---|---|
| 網(wǎng)頁可見區(qū)域寬 | document.body.clientWidth |
| 網(wǎng)頁可見區(qū)域寬 | document.body.clientWidth |
| 網(wǎng)頁可見區(qū)域高 | document.body.clientHeight |
| 網(wǎng)頁可見區(qū)域寬 (包括邊線的寬) | document.body.offsetWidth |
| 網(wǎng)頁可見區(qū)域高 (包括邊線的寬) | document.body.offsetHeight |
| 網(wǎng)頁正文全文寬 | document.body.scrollWidth |
| 網(wǎng)頁正文全文高 | document.body.scrollHeight |
| 網(wǎng)頁被卷去的高 | document.body.scrollTop |
| 網(wǎng)頁被卷去的左 | document.body.scrollLeft |
| 網(wǎng)頁正文部分上 | window.screenTop |
| 網(wǎng)頁正文部分左 | window.screenLeft |
| 屏幕分辨率的高 | window.screen.height |
| 屏幕分辨率的寬 | window.screen.width |
| 屏幕可用工作區(qū)高度 | window.screen.availHeight |
| 屏幕可用工作區(qū)寬度 | window.screen.availWidth |

!!variable做檢測,只要變量的值為:false、0、null、" "、undefined或者NaN都將返回的是false,反之返回的是true。使用
+variable將String和Date直接轉為數(shù)字。-
數(shù)組原生函數(shù)方式獲取元素:
var array = [1,2,3,4,5,6]; console.log(array.slice(1,2)); // [1,2] console.log(array.slice(3)); // [3,4,5,6] console.log(array.slice(-1)); // [6] console.log(array.slice(-2)); // [5,6] console.log(array.slice(-3)); // [4,5,6] 數(shù)組截斷可以直接指定數(shù)組
length屬性等于想要的長度即可。-
字符串替換所有:
var string = "john john"; console.log(string.replace(/hn/, "ana")); // "joana john" console.log(string.replace(/hn/g, "ana")); // "joana joana" -
合并數(shù)組:
var array1 = [1,2,3]; var array2 = [4,5,6]; console.log(array1.push.apply(array1, array2)); // [1,2,3,4,5,6]; 原理是拼起來。 console.log(array1.concat(array2)); // [1,2,3,4,5,6]; 原理是生成一個新的數(shù)組。 -
NodeList to Array
var elements = document.querySelectorAll("p"); // NodeList var arrayElements = [].slice.call(elements); // Now the NodeList is an array var arrayElements = Array.from(elements); // This is another way of converting NodeList to Array -
數(shù)組元素的洗牌
var list = [1,2,3]; console.log(list.sort(() => Math.random() - 0.5)); // [2,1,3] -
JavaScript獲取對象的屬性的三種方法
for...in: 該方法依次訪問一個對象及其原型鏈中所有可枚舉的屬性 Object.keys(O): 該方法返回一個數(shù)組,它包含了對象O自身的所有可枚舉屬性的名稱 Object.getOwnPropertyNames(O):該方法返回一個數(shù)組,它包含了對象O所有擁有的屬性(包括不可枚舉)的名稱 -
JavaScript中substring()、substr()、slice()的區(qū)別
var stringValue = "hello world";
| Code | Comments |
|---|---|
stringValue.slice(3) |
"lo world" |
stringValue.substring(3) |
"lo world" |
stringValue.substr(3) |
"lo world" |
stringValue.slice(3,7) |
"lo w" |
stringValue.substring(3,7) |
"lo w" |
stringValue.substr(3,7) |
"lo worl" |
stringValue.slice(-3) |
"rld" 從后往前數(shù)3個開始 |
stringValue.substring(-3) |
"hello world" 為負,默認從0開始 |
stringValue.substr(-3) |
"rld" |
stringValue.slice(3,-4) |
"lo w" 下標從3開始到-4(從后往前數(shù)4個) |
stringValue.substring(3,-4) |
"hel" |
stringValue.substr(3,-4) |
"" 長度為負,默認不顯示 |
-
~~運算符用在JavaScript中有按位取反的作用,~即是取反兩次,而位運算的操作值要求是整數(shù),其結果也是整數(shù),所以經(jīng)過位運算的都會自動變成整數(shù),可以巧妙的去掉小數(shù)部分,類似于parseInt,比如:let a = 1.23; let b = -1.23; console.log(~~a); // 1 console.log(~~b); // -1 -
||運算符
巧妙的使用||運算符我們可以給變量設置默認值,比如:let c = 1; let d = c || 2; // 如果c的值為true則取存在的值,否則為2 console.log(d); // 1 -
...運算符
...運算符是ES6中用于解構數(shù)組的方法,可以用于快速獲取數(shù)組的參數(shù),比如:let [num1, ...nums] = [1, 2, 3]; console.log(num1); // 1 console.log(nums); // [2, 3] -
new Set()
可能有人知道ES6中提供了新的數(shù)據(jù)結構 Set,但是能夠靈活運用的人或許不多。利用Set數(shù)據(jù)結構我們能夠輕松的去重一個數(shù)組,比如:let arr = [1, 2, 2, 3]; let set = new Set(arr); let newArr = Array.from(set); // Array.from方法可以將 Set 結構轉為數(shù)組。 console.log(newArr); // [1, 2, 3] -
Object.assign()
Object.assign()也是ES6中提供的對象的擴展方法,其可以用于對象的合并拷貝,比如:let obj1 = {a: 1}; let obj2 = {b: 2}; let obj3 = Object.assign({}, obj1, obj2); console.log(obj3); // {a: 1, b: 2} -
注入
evilCode.replace(/.+/,eval)// -
JavaScript中訪問屬性和訪問變量的標識符查找規(guī)則
標識符查找- 訪問屬性,查找的是原型鏈;
- 訪問變量,查找的是作用域鏈;
當通過屬性調用的方式調用對象的方法時,該對象只會成this的值;不會成為它的方法(即:對象中屬性值是函數(shù)的屬性)的作用域鏈中的作用域對象,不過可以通過with操作符使對象成為它的方法的作用域鏈中的作用域對象。
gby; //結果:報錯:ReferenceError: Can't find variable: gby; window.gby; //結果:undefined訪問變量時是通過搜索作用域鏈來查找變量的,而訪問屬性是通過搜索原型鏈來查找屬性的,因為這兩種訪問方式的搜索方式不一樣,所以導致了結果不一樣;
-
以下來自內(nèi)容部分來自《淺談JavaScript、ES5、ES6》:
-
ES6支持動態(tài)聲明對象屬性
const obj = { [ 'prop_' + (() => 42)() ]: 42 } console.log(obj); // {prop_42: 42} -
賦值解構
let singer = { first: "Bob", last: "Dylan" }; let { first: f, last: l } = singer; // 相當于 f = "Bob", l = "Dylan" let [all, year, month, day] = /^(dddd)-(dd)-(dd)$/.exec("2015-10-25"); // v8 不支持? let [x, y] = [1, 2, 3]; // x = 1, y = 2 let [, , x, y] = [1, 2, 3]; // x = 3, y = undefined -
函數(shù)參數(shù) - 默認值、參數(shù)打包、 數(shù)組展開(Default 、Rest 、Spread)
// Default function findArtist(name = 'lu', age = '26') { console.log(name, age); } findArtist(...['li', ]); // li 26 // Rest function f(x, ...y) { // y is an Array return x * y.length; } console.log(f(3, "hello", true)); // 6 // Spread function f2(x, y, z) { return x + y + z; } // Pass each elem of array as argument console.log(f2(...[1, 2, 3])) // 6 Iterators(迭代器)+
for..of。迭代器有個next方法,調用會:
(1).返回迭代對象的一個元素:{ done: false, value: elem }
(2).如果已到迭代對象的末端:{ done: true, value: retVal }-
Class
class Artist { constructor(name) { this.name = name; } perform() { return this.name + " performs "; } } class Singer extends Artist { constructor(name, song) { super(name); this.song = song; } perform() { return super.perform() + "[" + this.song + "]"; } } let james = new Singer("Etta James", "At last"); console.log(james instanceof Artist); // true console.log(james instanceof Singer); // true console.log(james.perform()); // "Etta James performs [At last]" -
Modules
ES6的內(nèi)置模塊功能借鑒了CommonJS和AMD各自的優(yōu)點:
(1).具有CommonJS的精簡語法、唯一導出出口(single exports)和循環(huán)依賴(cyclic dependencies)的特點。
(2).類似AMD,支持異步加載和可配置的模塊加載// lib/math.js export function sum(x, y) { return x + y; } export var pi = 3.141593; // app.js import * as math from "lib/math"; alert("2π = " + math.sum(math.pi, math.pi)); // otherApp.js import { sum, pi } from "lib/math"; alert("2π = " + sum(pi, pi)); // Dynamic loading – ‘System’ is default loader // Module Loaders: System.import('lib/math').then(function (m) { alert("2π = " + m.sum(m.pi, m.pi)); }); // Directly manipulate module cache System.get('jquery'); System.set('jquery', Module({ $: $ })); // WARNING: not yet finalized -
Map + Set + WeakMap + WeakSet
四種集合類型,WeakMap、WeakSet作為屬性鍵的對象如果沒有別的變量在引用它們,則會被回收釋放掉。// Sets var s = new Set(); s.add("hello").add("goodbye").add("hello"); s.size === 2; s.has("hello") === true; // Maps var m = new Map(); m.set("hello", 42); m.set(s, 34); m.get(s) == 34; //WeakMap var wm = new WeakMap(); wm.set(s, { extra: 42 }); wm.size === undefined // Weak Sets var ws = new WeakSet(); ws.add({ data: 42 }); //Because the added object has no other references, it will not be held in the set -
Math + Number + String + Array + Object APIs 一些新的API
Number.EPSILON Number.isInteger(Infinity) // false Number.isNaN("NaN") // false Math.acosh(3) // 1.762747174039086 Math.hypot(3, 4) // 5 Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2 "abcde".includes("cd") // true "abc".repeat(3) // "abcabcabc" Array.from(document.querySelectorAll('*')) // Returns a real Array Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior [0, 0, 0].fill(7, 1) // [0,7,7] [1, 2, 3].find(x => x == 3) // 3 [1, 2, 3].findIndex(x => x == 2) // 1 [1, 2, 3, 4, 5].copyWithin(3, 0) // [1, 2, 3, 1, 2] ["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"] ["a", "b", "c"].keys() // iterator 0, 1, 2 ["a", "b", "c"].values() // iterator "a", "b", "c" Object.assign(Point, { origin: new Point(0, 0) }) plain -
Proxies 使用代理(Proxy)監(jiān)聽對象的操作,然后可以做一些相應事情。
可監(jiān)聽的操作:get、set、has、deleteProperty、apply、construct、getOwnPropertyDescriptor、defineProperty、getPrototypeOf、setPrototypeOf、enumerate、ownKeys、preventExtensions、isExtensible。var target = {}; var handler = { get: function (receiver, name) { return `Hello, ${name}!`; } }; var p = new Proxy(target, handler); p.world === 'Hello, world!'; // true -
Symbol是一種基本類型。Symbol 通過調用symbol函數(shù)產(chǎn)生,它接收一個可選的名字參數(shù),該函數(shù)返回的symbol是唯一的。
var key = Symbol("key"); var key2 = Symbol("key"); key == key2 // false -
Promises是處理異步操作的對象,使用了 Promise 對象之后可以用一種鏈式調用的方式來組織代碼,讓代碼更加直觀。
function fakeAjax(url) { return new Promise(function (resolve, reject) { // setTimeouts are for effect, typically we would handle XHR if (!url) { return setTimeout(reject, 1000); } return setTimeout(resolve, 1000); }); } // no url, promise rejected fakeAjax().then(function () { console.log('success'); }, function () { console.log('fail'); }); 替換字符串最后一個匹配,參考
str.replace(/(.*)and/, '$1but');// 正則表達時,貪婪模式,.*會一直匹配到最后一個
-