饥人谷学习进阶第 18 天
一个很重要的概念:词法作用域暂存数据
封装一个Car对象
var Car = (function(){
var speed = 0;
function setSpeed(s){
speed = s
}
function get(){
return speed
}
function speedUp(){
speed++
}
function speedDown(){
speed--
}
return {
set: setSpeed,
get: get,
speedUp: speedUp,
speedDown: speedDown
}
})()
Car.set(30)
Car.get() //30
Car.speedUp()
Car.get() //31
Car.speedDown()
Car.get() //30
一个作用域暂存了一个变量
例题一
如下代码输出多少?如何连续输出 0,1,2,3,4
for (var i=0; i<5; i++) {
setTimeout(function(){
console.log('delayer:' + i)
}, 0)
}
// 连续输出 5个 delayer: 5
// setTimeout会将当前执行加入任务队列
// 设置了5个计时器并没有开始
// 当5个设置完毕之后,i === 5
// 此刻才去执行任务队列的一个个计时器
修改
for(var i=0; i<5; i++) {
(function(j){
setTimeout(function(){
console.log('delayer:' + j)
}, 0)
})(i)
}
// 上面的代码相当于 连续5个
function fni() {
var j = arguments[0]
setTimeout(function(){
console.log('delayer:' + j)
}, 0)
}
fni(i)
另一种
for(var i=0; i<5; i++) {
setTimeout((function(j){
// 相当于这里暂存了 j == i
return function() {
console.log('delayer:' + j)
}
})(i), 0)
}
例题二
function makeCounter() {
var count = 0
return function() {
return count++
};
}
var counter = makeCounter()
var counter2 = makeCounter();
console.log( counter() ) // 0
console.log( counter() ) // 1
console.log( counter2() ) // 0
console.log( counter2() ) // 1
// counter 和 counter2 位于不同的作用域下,二者独立
例题三
补全代码,实现数组按姓名、年纪、任意字段排序
var users = [
{ name: "John", age: 20, company: "Baidu" },
{ name: "Pete", age: 18, company: "Alibaba" },
{ name: "Ann", age: 19, company: "Tecent" }
]
users.sort(byName)
users.sort(byAge)
users.sort(byField('company'))
答案
function byName(user1, user2){
return user1.name > user2.name
}
function byAge (user1, user2){
return user1.age > user2.age
}
function byFeild(field){ // 闭包写法
return function(user1, user2){
return user1[field] > user2[field]
}
}
users.sort(byField('company'))
例题四
写一个 sum 函数,实现如下调用方式
console.log( sum(1)(2) ) // 3
console.log( sum(5)(-1) ) // 4
答案
function sum(a) {
// 暂存a
return function(b) {
// 暂存b
return a + b
}
}
函数柯里化 - 只传递给函数一部分参数来调用它,让它返回一个函数去处理剩下的参数。
网友评论