let arr = [300,432,1342,543,23,656,45,6465,4345,232,87,97,754,345]
function quickSort(arr) {
if(arr.length <= 1) {
return arr
}
const pivot = arr[0]
let bigger = []
let smaller = []
for(let i=1; i<arr.length; i++) {
if (arr[i] > pivot) {
bigger.push(arr[i])
}
}
for(let i=1; i<arr.length; i++) {
if (arr[i] < pivot) {
smaller.push(arr[i])
}
}
return quickSort(smaller).concat(pivot, quickSort(bigger))
}
console.log(quickSort(arr))
函數柯里化
案例一:
function curry(fn) {
return function() {
let arg = arguments
return function() {
return fn(...arg, ...arguments)
}
}
}
function fn(a,b,c,d) {
return a+b+c+d
}
let fun = curry(fn)
let fun2 = fun(1,2,3)
console.log(fun2(5))
案例二:
let fn = a => b => c => a+b+c
console.log(fn(1)(2)(3))
數組扁平化
let arr = [0,[3,4,5],[[[[12,5,6,7,54,34],43,34],33]], {a:1}]
function flatten(arr) {
let _arr = []
for(let i=0; i<arr.length; i++) {
const leixing = Object.prototype.toString.call(arr[i])
if (leixing !== '[object Array]') {
_arr.push(arr[i])
} else {
_arr = _arr.concat(flatten(arr[i]))
}
}
return _arr
}
console.log(flatten(arr))
原型鏈上擴展方法
Array.prototype.max = function max() {
console.log(this)
return Math.max.apply(Math, this)
}
let array = [1,2,3,4]
console.log(array.max())
深克隆
let arr = [1,2,3,[4,5,6], {a:1}]
function deepClone(o) {
if (
typeof o == 'number'
||
typeof o == 'string'
||
typeof o == 'boolean'
||
typeof o == 'undefined'
) {
return o
} else if(Array.isArray(o)) {
let _arr = []
for(let i=0; i<o.length; i++) {
_arr.push(deepClone(o[i]))
}
return _arr
} else if(typeof o == 'object') {
let _o = {}
for(let k in o) {
_o[k] = deepClone(o[k])
}
return _o
}
}
let deep = deepClone(arr)
console.log(arr[3] == deep[3]) // false
閉包的特點: 調用永久記住當前作用域的變量
案例一:
var a = 2
function foo() {
var a = 1
function bar() {
console.log(a)
}
bar()
}
foo()
//輸出結果
//1
案例二:
var a = 1
function bar() {
console.log(a)
}
(function(fn) {
var a = 2
fn()
})(bar)
// 輸出結果
// 1
// 函數非嚴格模式下實參與實參列表的關係
function fun(a, b) {
a = (typeof a !== 'undefined') ? a : 10
b = (typeof b !== 'undefined') ? b : 20
console.log(a == arguments[0])
console.log(b == arguments[1])
a = 123
b = 456
console.log(a == arguments[0])
console.log(b == arguments[1])
}
fun(1, 2)
// 輸出結果
// true
// true
// true
// true
// 函數嚴格模式下實參與實參列表的關係
function fun(a, b) {
'use strict'
a = (typeof a !== 'undefined') ? a : 10
b = (typeof b !== 'undefined') ? b : 20
console.log(a == arguments[0])
console.log(b == arguments[1])
a = 123
b = 456
console.log(a == arguments[0])
console.log(b == arguments[1])
}
fun(1, 2)
// true
// true
// false
// false
// 函數改良
// 這種方式跟非嚴格模式下的執行結果是一致的
function fun(a=10, b=20) {
console.log(a == arguments[0])
console.log(b == arguments[1])
a = 123
b = 456
console.log(a == arguments[0])
console.log(b == arguments[1])
}
fun(1, 2)
// true
// true
// false
// false
暫時性死區
解釋: 變量在定義之後, 但沒有聲明的情況下, 是暫時不能訪問的
// 案例一: 函數後面的默認參數可以訪問前面的參數
// 實參其實相當於使用 let來聲明一個變量
function foo(a) {
return a + 5
}
function fun(a, b = foo(a)) {
console.log(a + b)
}
fun(1) // 7
fun(1, 2) // 3
// 案例二: 函數後面的參數無法訪問前面參數的值
function add(a = b, b) {
return a + b
}
console.log(add(1, 2)) // 3
console.log(add(undefined, 2)) // ReferenceError: Cannot access 'b' before initialization
展開運算符
// 不使用展開運算符
let arr = [1,2,3,4]
let max = Math.max.apply(null,arr)
console.log(max)
// 改進
let arr = [1,2,3,4]
let max = Math.max(...arr)
console.log(max)