1.判断数据类型时,我们最经常用typeof判断某一数据类型,缺点不能很好判断null,数组,正则,函数,因为这几个都是返回object,而Object.prototype.toString().call(value)很好解决了这个问题

  

var array = [1,2,3],
    nullobj = null,
    fn = function () {alert(1)},
    reg = /^[1-4]$/;
console.log(Object.prototype.toString.call(array)) // '[object Array]'
console.log(Object.prototype.toString.call(nullobj)) // '[object Null]'
console.log(Object.prototype.toString.call(fn)) // '[object Function]'
console.log(Object.prototype.toString.call(reg)) // '[object RegExp]'

  

2.函数绑定

例子2.1:

var btn = document.getElementById('btn')
var handler = {
    color:'red',
    handleclick: function () {
     	console.log(this.color)
   }
}
btn.onclick = handler.handleclick // undefined,执行时this指的是DOM按钮

上面例子2.1中,this指向DOM按钮,要想this指向handler,可用闭包解决,如下例子2.2:

例子2.2:

var btn = document.getElementById('btn')
var handler = {
    color:'red',
    handleclick: function () {
     	console.log(this.color)
   }
}
btn.onclick = function () {
     handler.handleclick() // red,执行时this指的是handler
}

 

此外,还可以写一个bind函数,可以将函数绑定到某个环境中,如下例子2.3

例子2.3:

var btn = document.getElementById('btn')
var handler = {
     color:'red',
     handleclick: function (ev) {
     	console.log(ev.type)
     	console.log(this.color)
     }
}
     		
function bind(fn, context) {
     return function() {
     	return fn.apply(context,arguments) // 注意这里的arguments指的是内部函数的arguments,不是bind的
    }
}

btn.onclick = bind(handler.handleclick,handler) // 输出click和red    

原生的bind与上面方法类似,都需要传入作为this的对象 

3.函数柯里化

  函数柯里化指的是将能够接收多个参数的函数转化为接收单一参数的函数,并且返回接收余下参数且返回结果的新函数的技术。主要作用和特点就是参数复用、提前返回和延迟执行

  创建函数柯里化的通用方式如下例子3.1

  例子3.1:  

function carry(fn) {
     // 获取第一个参数后的所有参数
     var args = Array.prototype.slice.call(arguments,1)
     return function () {
     	// 获取里面函数的所有参数
     	var innerargs = Array.prototype.slice.call(arguments,0)
     	// 合并参数
     	var totalargs = args.concat(innerargs)
     	return fn.apply(null,totalargs)
     }
}

例子3.2:典型应用,bind的实现

Function.prototype.bind1 = function (context) {
     var args = Array.prototype.slice.call(arguments, 1)
     var that = this
     return function () {
     	var innerargs = Array.prototype.slice.call(arguments, 0)
     	var totalargs = args.concat(innerargs)
     	that.apply(context, totalargs)
    }
}

var myobj = {
     color: 'red',
     getColor: function (msg) {
     	console.log(msg+':'+this.color)
     }
}
var btn = document.getElementById('btn')
btn.onclick = myobj.getColor.bind1(myobj,'hello')

 例子3.3:经典面试,实现add(1, 2, 3, 4)=10,add(1)(2)(3)(4)(5)=15,add(1, 2, 3, 4)(5)(6)=21

function add() {
    // args用来收集所有的参数
    var args = Array.prototype.slice.call(arguments,0)
    function inner() {
        Array.prototype.push.apply(args, arguments)
        return inner
    }
    // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
    inner.toString = function () {
        return args.reduce(function (prev, now) {
            return prev + now
        })
    }
    return inner
}