JavaScript 유용한 코드 조각 모음

다양한 JavaScript 코드 예제들을 살펴보겠습니다. ### 프로토타입 확장
Function.prototype.확장 = function (이름, 기능) {
  if (!this.prototype[이름]) {
    this.prototype[이름] = 기능;
  }
  return this;
};
### 상속 구현 - 방법 1
Function.확장("상속받기", function (부모) {
  var _프로토타입 = Object.create(부모.prototype);
  _프로토타입.constructor = this.prototype.constructor;
  this.prototype = _프로토타입;
  return this;
});
### 상속 구현 - 방법 2
function 상속받기(자식, 부모) {
    var _프로토타입 = Object.create(부모.prototype);
    _프로토타입.constructor = 자식.prototype.constructor;
    자식.prototype = _프로토타입;
    return {
        "자식": 자식,
        "부모": 부모
    };
}
### 상속 구현 - 방법 3
var 상속 = (function () {
	var 임시함수 = function () {};
	return function (클래스, 부모클래스) {
		임시함수.prototype = 부모클래스.prototype;
		클래스.prototype = new 임시함수();
		클래스.상위클래스 = 부모클래스.prototype;			// 상위 클래스 저장
		클래스.prototype.constructor = 클래스;	 // 생성자 포인터 재설정
   }
})();
### 얕은 복사
function 간단한복사() {
    var 복사본 = {};
    for(var 키 in 원본) {
        복사본[키] = 원본[키];
    }
    return 복사본;
}
### 깊은 복사
export function 깊은복사(obj, 부모 = null) {
    let 결과 = new obj.constructor();
    let 키들 = Object.keys(obj),
        키 = null,
        값 = null,
        _부모 = 부모;
    while (_부모) {
        if (_부모.원본 === obj) {
            return _부모.현재;
        }
        _부모 = _부모.부모;
    }
    for (let i = 0; i < 키들.length; i++) {
        키 = 키들[i]
        값 = obj[키]
        if (값 && isType(값) === 'date') {
            결과[키] = new Date(값)
            continue
        }
        if (값 && isType(값) === 'regExp') {
            결과[키] = new RegExp(값)
            continue
        }
        if (값 && (isType(값) === 'object' || isType(값) === 'array')) {
            결과[키] = 깊은복사(값, {
                원본: obj,
                현재: 결과,
                부모: 부모
            })
        } else {
            결과[키] = 값
        }
    }
    return 결과
}
### 속성을 포함한 얕은 복사
function 구성(target, source){
    var desc = Object.getOwnPropertyDescriptor;
    var prop = Object.getOwnPropertyNames;
    var def_prop=Object.defineProperty;
    prop(source).forEach(function(key) {
        def_prop(target, key, desc(source, key))
    })
    return target;
}
### Mixin 혼합
function 믹스() {
    var arg, prop, child = {};
    for(arg = 0; arg < arguments.length; arg += 1) {
    	for(prop in arguments[arg]) {
    		if(arguments[arg].hasOwnProperty(prop)) {
    			child[prop] = arguments[arg][prop];
    		}
    	}
    }
    return child;
}
### 객체 네임스페이스 생성
var MYAPP = MYAPP || {};
MYAPP.namespace = function(ns_string) {
	var 부분들 = ns_string.split('.'),
		parent = MYAPP,
		i;
	if(부분들[0] === "MYAPP") {
		부분들 = 부분들.slice(1);
	}
	for(i = 0; i < 부분들.length; i += 1) {
		if(typeof parent[부분들[i]] === "undefined") {
			parent[부분들[i]] = {};
		}
		parent = parent[부분들[i]];
	}
	return parent;
};
MYAPP.namespace('example.deeply.nested.property');
### 함수 커링(Currying)
function 커링(fn){
    var args = Array.prototype.slice.call(arguments, 1);
    return function(){
         var innerArgs = Array.prototype.slice.call(arguments);
         var finalArgs = args.concat(innerArgs);
         return fn.apply(null, finalArgs);
    };
}
function 더하기(num1, num2){
    return num1 + num2;
}
var 커리된더하기 = 커링(더하기, 5);
alert(커리된더하기(3)); //8
### 함수 스로틀링
function 스로틀(fn, 대기시간){
	var 타이머;
	return function(...args){
      if(!타이머){
          타이머 = setTimeout(()=>타이머=null, 대기시간);
          return fn.apply(this, args);
      }
	}
}
### 함수 디바운싱
function 디바운스(fn, 지연시간){
	var 타이머 = null;
	return function(...args){
    	clearTimeout(타이머);
    	타이머 = setTimeout(() => fn.apply(this, args), 지연시간);
	}
}
### 타입 확인
export function 타입확인(obj, type) {
    const toString = Object.prototype.toString
    const 매핑 = {
        '[object Boolean]': 'boolean',
        '[object Number]': 'number',
        '[object String]': 'string',
        '[object Function]': 'function',
        '[object Array]': 'array',
        '[object Date]': 'date',
        '[object RegExp]': 'regExp',
        '[object Object]': 'object',
        '[object Undefined]': 'undefined',
        '[object Null]': 'null',
        '[object Error]': 'error',
    }
    if (obj instanceof HTMLElement) {
        return type ? type === 'element' : 'element'
    }
    return type ? type === 매핑[toString.call(obj)] : 매핑[toString.call(obj)]
}
### 소프트 바인딩\[기본 바인딩 설정 가능\]
Function.prototype.소프트바인딩 = function(obj) {
    var fn = this;
    var curried = [].slice.call( arguments, 1 );
    var bound = function() {
          return fn.apply(
                (!this || this === (window || global)) ?
                     obj : this,
                    curried.concat.apply( curried, arguments )
              );
    };
    bound.prototype = Object.create( fn.prototype );
    return bound;
};
### 시간 스탬프를 시간 설명으로 변환
function 시간설명(time) {
   var 단위 = [36 * 30 * 24 * 60 * 60 * 1000, 30 * 24 * 60 * 60 * 1000, 24 * 60 * 60 * 1000, 60 * 60 * 1000, 60 * 1000, 1000],
       이름 = ['년', '월', '일', '시간', '분', '초'],
       value = '';

    for (let i = 0; i < 단위.length; i++) {
        let n = parseInt(time / 단위[i]);
        time %= 단위[i];
        if (n > 0) {
            value += n + 이름[i];
        }
    }
    console.log(value);
    return value;
}
### toFixed 정밀도 수정
Number.prototype.toFixed = function (n) {
    if (n > 20 || n < 0) {
        throw new RangeError('toFixed() 숫자 인자는 0과 20 사이여야 합니다.');
    }
    const number = this;
    if (isNaN(number) || number >= Math.pow(10, 21)) {
        return number.toString();
    }
    if (typeof (n) == 'undefined' || n == 0) {
        return (Math.round(number)).toString();
    }

    let result = number.toString();
    const arr = result.split('.');

    if (arr.length < 2) {
        result += '.';
        for (let i = 0; i < n; i += 1) {
            result += '0';
        }
        return result;
    }

    const integer = arr[0];
    const decimal = arr[1];
    if (decimal.length == n) {
        return result;
    }
    if (decimal.length < n) {
        for (let i = 0; i < n - decimal.length; i += 1) {
            result += '0';
        }
        return result;
    }
    result = integer + '.' + decimal.substr(0, n);
    const last = decimal.substr(n, 1);

    if (parseInt(last, 10) >= 5) {
        const x = Math.pow(10, n);
        result = (Math.round((parseFloat(result) * x)) + 1) / x;
        result = result.toFixed(n);
    }

    return result;
};
### JavaScript 정밀 연산
var floatObj = function() {

    function isInteger(obj) {
        return Math.floor(obj) === obj
    }

    function toInteger(floatNum) {
        var ret = {times: 1, num: 0}
        var isNegative = floatNum < 0
        if (isInteger(floatNum)) {
            ret.num = floatNum
            return ret
        }
        var strfi  = floatNum + ''
        var dotPos = strfi.indexOf('.')
        var len    = strfi.substr(dotPos+1).length
        var times  = Math.pow(10, len)
        var intNum = parseInt(Math.abs(floatNum) * times + 0.5, 10)
        ret.times  = times
        if (isNegative) {
            intNum = -intNum
        }
        ret.num = intNum
        return ret
    }

    function operation(a, b, digits, op) {
        var o1 = toInteger(a)
        var o2 = toInteger(b)
        var n1 = o1.num
        var n2 = o2.num
        var t1 = o1.times
        var t2 = o2.times
        var max = t1 > t2 ? t1 : t2
        var result = null
        switch (op) {
            case 'add':
                if (t1 === t2) {
                    result = n1 + n2
                } else if (t1 > t2) {
                    result = n1 + n2 * (t1 / t2)
                } else {
                    result = n1 * (t2 / t1) + n2
                }
                return  (result / max).toFixed(digits);
            case 'subtract':
                if (t1 === t2) {
                    result = n1 - n2
                } else if (t1 > t2) {
                    result = n1 - n2 * (t1 / t2)
                } else {
                    result = n1 * (t2 / t1) - n2
                }
                return (result / max).toFixed(digits);
            case 'multiply':
                result = (n1 * n2) / (t1 * t2)
                return result.toFixed(digits);
            case 'divide':
                result = (n1 / n2) * (t2 / t1)
                return result.toFixed(digits);
        }
    }

    function add(a, b, digits) {
        let value = operation(a, b, digits, "add");
        return value == NaN || value == Infinity ? 0 : value;
    }
    function subtract(a, b, digits) {
        let value = operation(a, b, digits, "subtract");
        return value == NaN || value == Infinity ? 0 : value;
    }
    function multiply(a, b, digits) {
        let value = operation(a, b, digits, "multiply");
        return value == NaN || value == Infinity ? 0 : value;
    }
    function divide(a, b, digits) {
        let value = operation(a, b, digits, "divide");
        return value == NaN || value == Infinity ? 0 : value;
    }

    return { add, subtract, multiply, divide };
}();
### 마우스 휠 이벤트 바인딩
EventTarget.prototype.onMousewheel = function (fn, capture) {
    var type = document.mozFullScreen !== undefined ? "DOMMouseScroll" : "mousewheel";
    this.addEventListener(type, function (event) {
        event.delta = (event.wheelDelta) ? event.wheelDelta / 120 : -(event.detail || 0) / 3;
        fn.call(this, event);
    }, capture || false);
}
### 클릭 다운로드
function browserDownload(url) {
  var save_link = document.createElementNS("http://www.w3.org/1999/xhtml", "a");
  save_link.href = url;
  save_link.download = name;
  var ev = document.createEvent("MouseEvents");
  ev.initMouseEvent(
    "click",
    true,
    false,
    window,
    0,
    0,
    0,
    0,
    0,
    false,
    false,
    false,
    false,
    0,
    null
  );
  save_link.dispatchEvent(ev);
}
### 범위 내 랜덤 숫자 생성
function random(n, m){
    var rand = Math.floor(Math.random()*(m-n+1)+n);
    return rand;
}
### 단계별 랜덤 숫자 생성
function step_random(min, max, step) {
    var newMax = max / step;
    var randomNum = Math.floor(Math.random() * (newMax - min + 1) + min)
    var stepNum = randomNum * step
    return stepNum;
}
### 데이터 그룹화
function groupBy(array, valueKey) {
  let groups = {};
  let newArray = [];
  array.forEach(function(o) {
    groups[valueKey] = groups[group] || [];
    groups[valueKey].push(o);
  });
  for(const key in groups) {
     newArray = newArray.concat(groups[key]);
  }
  return newArray;
};
### 쿼리 파라미터 가져오기
function getQueryObject() {
  const search = window.location.href.split('?')[1]
  if (!search) {
    return {}
  }
  return JSON.parse(
    '{"' +
      decodeURIComponent(search)
        .replace(/"/g, '\\"')
        .replace(/&/g, '","')
        .replace(/=/g, '":"')
        .replace(/\+/g, ' ') +
      '"}'
  )
}

function getQueryObject(url) {
  url = url == null ? window.location.href : url;
  const search = url.substring(url.lastIndexOf("?") + 1);
  const obj = {};
  const reg = /([^?&=]+)=([^?&=]*)/g;
  search.replace(reg, (rs, $1, $2) => {
    const name = decodeURIComponent($1);
    let val = decodeURIComponent($2);
    val = String(val);
    obj[name] = val;
    return rs;
  });
  return obj;
}

태그: JavaScript 프로토타입 상속 깊은복사 함수커링

8월 8일 07:29에 게시됨