《前端之路》之 高级技巧、高阶函数(一) (2)

很多JavaScript库实现了一个可以将函数绑定到指定环境的函数,这个函数一般都叫做bind()。一个简单的bind()函数接受一个函数和一个环境,并返回一个给的环境中调用给定函数的函数,并且将所有参数原封不动传递过去。这个函数返回的是一个闭包。

上面的语言描述总是很虚无飘渺,我们来直接上Demo:

1-4-1 Demo var obj1 = { name: 'zhang', getName: function() { console.log(arguments[0][2], 'obj1') return this.name } } var obj2 = { name: 'lisi', getName: function() { console.log(arguments, 'obj2') return this.name } } function Bind(fn, context) { return fn.call(context, arguments) } Bind(obj1.getName,obj2,'xxxxx') // Arguments [Arguments(3), callee: ƒ, Symbol(Symbol.iterator): ƒ] "obj1" // 'lisi' // 这里我们对于 arguments 的 理解和操作来说都是比较陌生,那么下面 我们再来介绍下 // arguments 具体是什么。 1-4-2 arguments

类数组 (Array-like)

可以用下标访问每个元素

有 length 属性

arguments 的数据类型为 object

可以使用 for 和 for-in 方法

不具备 Array 原生方法

Demo

var test = function() { console.log(arguments) console.log(arguments[0]) console.log(arguments.length) console.log(typeof arguments) for(var i = 0; i<arguments.length; i++) { var ele = arguments[i] console.log(ele) } for(x in arguments) { console.log(arguments[x]) } // arguments.split(' ') // Uncaught TypeError: arguments.split is not a function } test(1,2,3,4) // Arguments(4) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ] // 1 // 4 // object // 1 2 3 4 // 1 2 3 4

将类数组 转化为 数组

方法一 :

var test = function() { console.log(arguments) var arrArg = Array.prototype.slice.call(arguments) console.log(arrArg) } test(1,2,3,4) // [1, 2, 3, 4]

方法二 :

var test = function() { console.log(arguments) var arrArg = Array.from(arguments) console.log(arrArg) } test(1,2,3,4) // [1, 2, 3, 4] 1-4-3 ES5 中原生 bind() 方法 详解

文字解释起来还是比较吃力,那么我们还是 showCode~
Demo:

var obj = { a: 1, b: 2, getCount: function(c, d) { return this.a + this.b + c + d } } console.log(obj.getCount(3,4)) // 10 window.a = window.b = 0 var funcs = obj.getCount funcs(3,4) // 7

bind是function的一个函数扩展方法, bind 以后代码重新绑定了 func 内部的 this 指向(obj)
兼容 IE9 +
Demo:

var obj = { a: 1, b: 2, getCount: function(c, d) { return this.a + this.b + c + d } } console.log(obj.getCount(3,4)) // 10 window.a = window.b = 100 var funcs = obj.getCount.bind(obj) funcs(3,4) // 10 // var funcs = obj.getCount.bind(window) // funcs(3,4) // 207 1-5 函数柯里化

又称部分求值。柯里化其实本身是固定一个可以预期的参数,并返回一个特定的函数,处理批特定的需求。
这增加了函数的适用性,但同时也降低了函数的适用范围。
文字的定义始终让人难以接受,还是 showCode 吧
Demo:假设你要写一个 记账的工具,然后记录每天的数据,最后统计整个星期的数据。
how ?

let weekCost = 0 const cost = function(num) { weekCost += num } cost(100) // 100 cost(200) // 300 cost(300) // 600 这个时候每天都会进行一次 总账,这个是我不想看到的,因为不想每天都被这个总账看着心痛,毕竟工资不够花是常态。我就希望每个星期给我来一次总账刺激。 const currying = function(fn) { let args = [] return function() { if (arguments.length == 0) { return fn.apply(this, args) } else { let test = [].push.apply(args,arguments) // return fn.call(this, arguments) } } } const costs = (function() { let money = 0 return function() { money = 0 for(let i = 0; i<arguments.length; i++) { money += arguments[i] } return money } })() let cost = currying(costs) cost(100) cost(100) cost(100) cost(100) cost(100) console.log(cost()) // 500 cost(100) cost(100) console.log(cost()) // 700

小结一:

上面的 dmeo 中,当调用 cost() 时,如果明确带上参数,表明此时并不进行真正的求值计算,而是把这些参数保存起来,此时让 cost() 函数返回另外一个函数。只有当我们以不带参数的形式执行 cost() 时,才利用前面保存的所有参数,真正开始求值计算。这是一个具象的函数颗粒化的方法。那么我们想把函数颗粒化抽象出来又需要怎么来概括呐?

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypwdd.html