js部分

判斷this

如今咱們能夠根據優先級來判斷函數在某個調用位置應用的是哪條規則。能夠按照下面的 順序來進行判斷:數組

  1. 函數是否在new中調用(new綁定)?若是是的話this綁定的是新建立的對象。 var bar = new foo()
  2. 函數是否經過call、apply(顯式綁定)或者硬綁定調用?若是是的話,this綁定的是 指定的對象。 var bar = foo.call(obj2)
  3. 函數是否在某個上下文對象中調用(隱式綁定)?若是是的話,this綁定的是那個上 下文對象。 var bar = obj1.foo()
  4. 若是都不是的話,使用默認綁定。若是在嚴格模式下,就綁定到undefined,不然綁定到 全局對象。 var bar = foo() 就是這樣。對於正常的函數調用來講,理解了這些知識你就能夠明白 this 的綁定原理了。 不過......凡事總有例外。

做用域閉包

定義: 當函數能夠記住並訪問所在的詞法做用域時,就產生了閉包,即便函數是在當前詞法做用域以外執行。bash

原型

模板編譯函數

let tem = '我是{{obj.name}},我愛{{ obj.hobby?"singing":"dance"}}'
    let obj = {
        name: "gp",
        hobby: 0
    }

    compile(tem, obj) // 我是gp,我愛dance
    function compile(tem, obj){

        let reg = /\{\{(.*?)\}\}/g
        let strFun = '""'

        var strArr = tem.split(reg)
        var regArr = tem.match(reg)
        console.log(strArr) // ["我是", "obj.name", ",我愛", "obj.hobby?"singing":"dance"", ""]
        console.log(regArr) // ["{{obj.name}}", "{{obj.hobby?"singing":"dance"}}"]

        strArr.forEach((item, index)=>{
            if(item !== "" && regArr.toString().includes(item)){
                strFun += "+(" +  item +")"
            }else{
                strFun += "+"+ '"' + item +'"'
            }

        })
        console.log(strFun) // ""+"我是"+(obj.name)+",我愛"+(obj.hobby?"singing":"dance")+""
        var fun = new Function( 'return ' + strFun)
        return fun()
    }
複製代碼

判斷對象爲空

# 自身沒有可枚舉的
function isObjectEmpty(obj) {
  if (obj) {
    for (var prop in obj) {
      if (obj.hasOwnProperty(prop)) {
        return false;
      }
    }
  }
  return true;
}
複製代碼

判斷類數組

function isLength(value) {
      return typeof value == 'number' &&
        value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
    }
    
   function isArrayLike(value) {
      return value != null && isLength(value.length) && !isFunction(value);
    }
複製代碼

柯里化

const curry = func =>{
	 const g = (...allArgs) => allArgs.length >= func.length ?
		 func(...allArgs) :
		 (...args)=> g(...allArgs, ...args)

	return g
}

const foo = curry( (a,b,c,d) => {
	console.log(a, b, c, d)
})
複製代碼

全排列

function permutate(str) {

		var result=[];
		if(str.length==1){
			return [str]
		}else{

			var preResult=permutate(str.slice(1));
			for (var j = 0; j < preResult.length; j++) {
				for (var k = 0; k < preResult[j].length+1; k++) {
					var temp=preResult[j].slice(0,k)+ str[0]+ preResult[j].slice(k);
					result.push(temp);
				}
			}
			return result;

		}
	}

	console.log(permutate("abc"));
複製代碼

debounce

const debounce = (func, delay) => {
  let inDebounce
  return function() {
    const context = this
    const args = arguments
    clearTimeout(inDebounce)
    inDebounce = setTimeout(() => func.apply(context, args), delay)
  }
}
複製代碼

throttle

const throttle = (func, limit) => {
  let lastFunc
  let lastRan
  return function() {
    const context = this
    const args = arguments
    if (!lastRan) {
      func.apply(context, args)
      lastRan = Date.now()
    } else {
      clearTimeout(lastFunc)
      lastFunc = setTimeout(function() {
        if ((Date.now() - lastRan) >= limit) {
          func.apply(context, args)
          lastRan = Date.now()
        }
      }, limit - (Date.now() - lastRan))
    }
  }
}
複製代碼

bind

Function.prototype.bind = function(oThis) {
  if (typeof this !== 'function') {
    // closest thing possible to the ECMAScript 5
    // internal IsCallable function
    throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
  }

  var aArgs   = Array.prototype.slice.call(arguments, 1),
    fToBind = this,
    fNOP    = function() {},
    fBound  = function() {
      return fToBind.apply(this instanceof fNOP
        ? this
        : oThis,
        // 獲取調用時(fBound)的傳參.bind 返回的函數入參每每是這麼傳遞的
        aArgs.concat(Array.prototype.slice.call(arguments)));
    };

  // 維護原型關係
  if (this.prototype) {
    // Function.prototype doesn't have a prototype property fNOP.prototype = this.prototype; } fBound.prototype = new fNOP(); return fBound; }; 複製代碼

四捨五入-原生toFixed() 方法不許確

function toFixed(num, s) {
  var times = Math.pow(10, s);
  var des = num * times + 0.5;
  des = parseInt(des, 10) / times;
  return des + '';
}
複製代碼

小數相乘

function accMul(arg1, arg2) {
 let m = 0,
   s1 = arg1.toString(),
   s2 = arg2.toString()
 try {
   m += s1.split('.')[1].length
 } catch (e) {} // eslint-disable-line
 try {
   m += s2.split('.')[1].length
 } catch (e) {} // eslint-disable-line

 return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
}
複製代碼

使對象擁有 iterator

var myObject = { a: 2,
  b: 3 };
Object.defineProperty( myObject, Symbol.iterator, { enumerable: false,
  writable: false,
  configurable: true,
  value: function() { var o = this;
    var idx = 0;
    var ks = Object.keys( o ); return {
      next: function() { return {
        value: o[ks[idx++]],

        done: (idx > ks.length)
      };

      } };
  } } );
// 手動遍歷 myObject
var it = myObject[Symbol.iterator]();
it.next(); // { value:2, done:false } 
it.next(); // { value:3, done:false }
it.next(); // { value:unde ned, done:true }
// 用 for..of 遍歷 myObject 
for (var v of myObject) { console.log( v );
}
// 2 
// 3
複製代碼

待續。。。閉包

相關文章
相關標籤/搜索