記錄自己用的常見的一些方法

dragonnahs發表於2019-02-21

常見的一些算數方法

github地址

  1. 字串中各個字串出現的次數
var arr = `abcdaabc`;

var info = arr
    .split(``)
    .reduce((p, k) => (p[k]++ || (p[k] = 1), p), {});

console.log(info); //{ a: 3, b: 2, c: 2, d: 1 }

複製程式碼

reduce 對於低版本相容性不是很好,
可以用下面的方法

var temp = {};
`abcdaabc`.replace(/(w{1})/g,function($1){
    temp[$1] ? temp[$1]+=1 : temp[$1] = 1;
})
console.log(temp) // {a: 3, b: 2, c: 2, d: 1}

// 或者
function getTimesO(str){
  var obj = {}
  str.split(``).map(function(val,index){
    if(!obj[val]){
      obj[val] = 1 
    }else{
      obj[val] += 1
    }
  })
  return obj
}

複製程式碼
  1. 阻止事件冒泡
function stopBubble(e)
{
    if (e && e.stopPropagation)
        e.stopPropagation()
    else
        window.event.cancelBubble=true
}

複製程式碼
  1. 判斷資料型別,
  • typeof

typeof 變數 返回的是變數的資料型別,但是不能區分陣列和物件

  • instanceof

變數 instanceof Object||Array 判斷變數是陣列還是物件,返回true和false

  • Array.isArray()

Array.isArray(變數) 判斷變數是不是陣列,返回true和false

  1. 在console.log()中加上字首,‘iphone’

封裝log函式

  • 初步封裝
function log(){
  console.log.apply(console,arguments)
}

複製程式碼
  • 第二次封裝,怎麼才能在引數前面加字首
function log(){
  var newArguments = []
  if(arguments.length > 0){
    for(var i = 0; i < arguments.length; i++){
      newArguments.push(`iphone`,arguments[i])
    }
  }
  console.log.apply(console,newArguments)
}

複製程式碼

也可以下面的寫法

function getLog(){
  var args = Array.prototype.slice.call(arguments) // 把arguments偽陣列轉化為真陣列
  args.unshift(`(app)`) // 呼叫陣列的方法
  console.log.apply(console,args)
}
getLog(`df`) // (app) df



複製程式碼
  1. 陣列排序
  • 第一種 (二分法排序)
function sortMany(arr){
  if(arr.length <= 1){
    return arr
  }
  var left = [], right = []
  var middleIndex = Math.floor(arr.length/2)
  var middleValue = arr.splice(middleIndex,1)[0]
  for(var i = 0; i < arr.length; i++){
    if(arr[i] < middleValue){
      left.push(arr[i])
    }else{
      right.push(arr[i])
    }
  }
  return sortMany(left).concat(middleValue,sortMany(right))

}

複製程式碼

二分法的搜尋(需要先對陣列進行排序)

var arr = [1,2,3,4,5,6,7]

function searchBinary(arr, target){
    let s = 0
    let e = arr.length-1
    let m = Math.floor((s + e)/2)
    let sortTag = arr[s] <= arr[e]

    while(s < e && arr[m] !== target){
        if(arr[m] > target){
            sortTag && (e = m - 1)
            !sortTag && (s = m + 1)
        }else{
            sortTag && (s = m + 1)
            !sortTag && (e = m -1)
        }
        m = Math.floor((s + e)/2)
    }
    if(arr[m] === target){
        return m
    }else{
        return -1
    }
}

searchBinary(arr, 3) // 2

複製程式碼
  • 第二種氣泡排序
function sortTwo(arr){
  for(var i=0;i<arr.length-1;i++){
    for(var j=i+1;j<arr.length;j++){
      if(arr[i]>arr[j]){
        var temp = arr[j]
        arr[j] = arr[i]
        arr[i] = temp
      }
    }
  }
  return arr
}

複製程式碼
  • 第三種陣列內建的排序
Array.prototype.innerSort = function(){
    this.sort(function (a,b){
        return a - b;
    })
    return this
}

複製程式碼
  1. 陣列的去重
function deletMany(arr){
  var obj = {}
  var newArr = []
  for(var i=0; i<arr.length-1;i++){
    if(!obj[arr[i]]){
      newArr.push(arr[i])
      obj[arr[i]] = 1
    }
  }
  return newArr
}

複製程式碼
  1. 物件的深拷貝問題

程式碼如下,實現物件的深拷貝

function deepCopy(p, c){
      var c = c || {}
      for(var i in p){
        if(typeof p[i] === `object`){
          c[i] = (p[i].constructor === Array) ? [] : {}
          deepCopy(p[i], c[i])
        }else{
          c[i] = p[i]
        }
      }
      return c
    }

複製程式碼

拷貝分為深拷貝和淺拷貝,拷貝就是把父物件的屬性全部拷貝給子物件。

  • 淺拷貝只是把物件的第一層屬性拷貝下來,如果第一層中有複雜資料型別,只是拷貝的指標,如果父屬性的屬性變化也會導致拷貝的子物件的屬性變化,這有時是不需要的。
  • 上面的程式碼實現的是使用遞迴實現的深拷貝,也可以使用JSON.stringfy先轉成簡單型別,再使用JSON.parse轉換成複雜型別。

另外一種物件深拷貝

function copyObject(orig){
  var copy = Object.create(Object.getPrototypeOf(orig))
  copyOwnPropertiesFrom(copy, orig)
  return copy
}

function copyOwnPropertiesFrom(target, source){
  Object
    .getOwnPropertyNames(source)
    .forEach(function(val){
      var desc = Object.getOwnPropertyDescriptor(source, val)
      if(typeof desc.value === `object`){
        target[val] = copyObject(source[val])
      }else{
        Object.defineProperty(target, val, desc)
      }
    })
    return target
}

複製程式碼
  1. 判斷型別的封裝
let type = (o) => {
    const s = Object.prototype.toString.call(o)
    return s.match(/[object (.*?)]/)[1].toLowerCase()
}

[
    "Undefiend",
    `Null`,
    `Object`,
    `Array`,
    "String",
    "Boolean",
    `RegExp`,
    `Function`
].forEach(t => {
    type[`is`+ t] = (o) => {
        return type(o) === t.toLowerCase()
    }
});
type.isArray([]) //true

複製程式碼
  1. 金額格式化

function toThousands(num) {
    var potStr = `.00`
    num = (num||0).toString()
    if(num.indexOf(`.`) !== -1){
       potStr = num.substr(num.indexOf(`.`),3)
    }
    
    var result = [ ], counter = 0;
    num = num.substring(0,num.indexOf(`.`)).split(``);
    for (var i = num.length - 1; i >= 0; i--) {
        counter++;
        result.unshift(num[i]);
        if (!(counter % 3) && i != 0) { result.unshift(`,`); }
    }
    return result.join(``)+potStr;
}

複製程式碼
  1. lazyMan

function _LazyMan(name){
    this.name = name
    this.quene = []
    
    console.log(`Hi This is ` + this.name)
    setTimeout(() => {
        this.next()
    }, 0);
    
}

_LazyMan.prototype.next = function (){
    if(this.quene.length){
        
        const fn = this.quene.shift()
        if((typeof fn).toLowerCase() === `function`){
            fn()
            return this
        }
    }else{
        return this
    }
}

_LazyMan.prototype.sleep = function(time){
    
    const fn1 = () => {
        
        setTimeout(() => {
            console.log(`Wake up after ` + time)
            this.next()
        }, time);
    }
    this.quene.push(fn1)   
    return this
}
_LazyMan.prototype.dinner = function (){
    const fn = () => {
        console.log(`Eat dinner`)
        this.next()
    }
    this.quene.push(fn)
    return this
}

function LazyMan(name){
    return new _LazyMan(name)
}

LazyMan(`Hank`).sleep(2000).dinner()


複製程式碼
  1. 防抖節流

在專案中一般會遇到防止多次點選的情況,這種情況以前處理的時候是使用一個開關,後來研究了下防抖這種方法,在這裡記錄下

function debounce(fn, delay, immidate){
    var timer;
    return function (){
        var that = this;
        var args = arguments;
        clearTimeout(timer)
        if(immidate){
            // 立即執行的走這裡
            var doNow = !timer;
            timer = setTimeout(function(){
                timer = null
            }, delay)
            if(doNow){
                fn.apply(that, args)
            }
        }else{
            timer = setTimeout(function(){
                fn.apply(that, args)
            }, delay)
        }
        
    }
}
function foo(){
    console.log(`scroll timer is running`)
}

document.getElementById(`box`).addEventListener(`mousemove`, debounce(foo, 2000, true))

複製程式碼

相關文章