一起来啃犀牛书:你懂LOL,也可以懂函数

《javascript权威指南》这本书就像是js界的圣经,对于大神和新手都应该是必读书。但是这本近千页的书已经厚到让人望而生畏,要通读它不仅要时间也需要毅力。为了提升自己在js语言上的深度,所以抱着工匠精神开始研读,此文包含书中实用性较强的一些知识点和代码,算做读书笔记吧~

英雄请留步

其实我不会打LOL(作者是不是要标题党了?囧~),不过我打过DOTA和DOTA2啊~游戏大同小异。今天索性把js中的函数当成游戏中的英雄来学习,说不定更容易理解~好吧,那就让我们先来了解一下这个叫“函数”的英雄。

技能介绍

先说说普通攻击,也就是函数最常见的调用方式,声明之后直接调用。不过要注意的是 非严格模式this指向window,严格模式为undefined

1
2
function fun(){//...}
fun();

  • 增益技能——方法。obj.fun = function(){//技能效果...},瞬间给obj加了一个fun的buff。不过这里已经将this改为了obj,同时这个buff可以叠加,叠加的方式很简单:函数执行后返回this实现链式调用。
  • 召唤技能——构造函数。这个技能就牛X了,召唤很多个小弟,小弟还带有英雄的技能。召唤方法也很简单

    1
    2
    3
    4
    function Fun(){}
    var f = new Fun();
    //或 var f = new Fun;
    //this 将指向f
  • 位移技能——apply()/call()。将英雄瞬间移动到其他位置。也就是改变作用域,让一些不具备该属性的对象也能调用该方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var obj = {
    id:1,
    show: function(){
    return this.id;
    }
    };
    var zdl = {
    id:2
    };
    obj.show.call(zdl);//2
  • 终极技能——函数式编程。首先这个技能是可以叠加的,伤害值无上限。

    1
    2
    3
    4
    5
    //实现勾股定理
    var square = function(x){return x*x;};
    var add = function(x,y){return x+y;};
    //将函数作为参数传入
    var pyth = add(square(3),square(4));//25

还可以从不同的方向施放。

1
2
3
4
5
6
7
8
9
//从右到左绑定参数,与bind正好相反
function partialRight(fun){
var args = arguments;
return function(){
var a = array(arguments);
a = a.concat(arguments);
return fun.apply(this,a);
};
}

对目标单位造成冰冻效果。

1
2
3
4
5
6
7
8
9
10
11
//一个记忆函数,可以缓存函数的执行结果,对于递归函数比较好用
function memorize(f){
var cache = {};
return functin(){
//根据参数和参数长度来缓存。
//为什么不直接用参数缓存?答案很简单,参数有可能为空~
var key = arguments.length + Array.prototype.join.call(arguments, ",");
if (key in cache) return cache[key];
else return cache[key] = f.apply(this, arguments);
}
}

英雄天赋

  • 显示隐形单位——length。显示函数形参个数

    1
    2
    function zdl(a,b){};
    zdl.length;//2
  • 增加三维——prototype。有了这个天赋,新创建的对象将会继承这个属性。

    1
    2
    3
    4
    function Fun(){};
    Fun.prototype.id = 1;
    var f = new Fun();
    f.id;//1
  • 分身——bind()。创建一个带有装备的分身。

    1
    2
    3
    4
    5
    6
    7
    //加法函数
    function add(x,y){
    return x + y;
    }
    //自增函数
    var inc = add.bind(this, 1);
    inc(2);//3
  • 镜像——Function(),伪函数。为什么叫它们为镜像呢?因为它们和真正的函数有区别。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    /*Function的区别
    * 每次执行都将创建新的函数对象,在循环中使用会出现性能问题
    * 不使用词法作用域,没有闭包特性,作用域为全局对象
    */
    //用于动态创建函数
    new Function("x", "y", "return x+y;");
    //等价于
    function(x,y){return x+y;}
    //等价于
    eval("function(x,y){return x+y;}");
1
2
3
4
5
6
7
8
9
/* 伪函数的区别
* 能被调用但不属于函数,如IE8这些浏览器不属于函数,如:
* window.alert()
* RegExp()
* 判断真伪函数的方法如下
*/
function (x){
return Object.prototype.toString.call(x) === '[object Function]';
}

团队定位

  • 肉——命名空间。当用作命名空间的时候就相当于是肉,抗住所有伤害

    1
    2
    3
    (function(){
    //...
    }());
  • ganker——闭包。ganker最喜欢的是什么?钻树林钻草丛。闭包也喜欢隐蔽,自带隐身技能,可以把变量隐藏起来私有化。闭包是指函数对象可以通过作用域链互相关联起来,函数体内部的变量都可以保存在函数作用域内。其原理就是当嵌套函数存储在对象或属性时,由于有外部引用指向它,所以不会被垃圾回收。

  • DPS——嵌套。如fun1(fun2())。值得注意的是函数和其它对象一样可以添加属性.
    1
    2
    3
    4
    uniqueInteger.counter = 0;
    function uniqueInteger(){
    return uniqueInteger.counter++;
    }

推荐装备

  • 第一件装备叫形参。

    1
    2
    3
    4
    function fun(a,b,c){
    //a,b,c都是形参,c未传入为undefined
    }
    fun(1,2);
  • 第二件是实参。arguments对象,伪数组,指向实参列表,通常用Array.prototype.slice(arguments)让其具有数组属性和方法。

两件装备?坑爹么?!淡定,这些只是出门装~

进阶攻略

可能有也可能没有,等我看完下一章“类与模块”再做定夺。

打怪升级

  • 写出函数执行结果
1
2
3
4
5
6
7
8
9
var scope = 'global scope';
function checkscope(){
var scope = 'local scope';
function f() {
return scope;
}
return f();
}
checkscope();
1
2
3
4
5
6
7
8
9
var scope = 'global scope';
function checkscope(){
var scope = 'local scope';
function f() {
return scope;
}
return f;
}
checkscope()();
1
2
3
4
5
6
7
8
9
function zdl(){
var funcs = [];
for(var i=0;i<10;i++){
funcs[i] = function(){return i;}
}
return funcs;
}
var funcs = zdl();
funcs[5]();
  • 利用闭包实现私有属性存取的方法

答案及百度脑图下载地址:http://yalishizhude.github.io/subscribe/

彩蛋

活动宣传(这个是免费的,当然想交费也可以)

由w3ctech组织发起的前端技术分享会将于4月16日在长沙卡瑞尔大厦1806举行,到时候我将抛砖引玉扒一扒关于用node.js实现前后端分离的那些事,同时还有移动端混合应用专家和某知名传媒公司技术大牛分享移动端开发的经验。欢迎有时间有兴趣的同学报名参加~

玩个游戏(这个是收费的,当然不想交费也可以)

游戏介绍

最近一边忙着申请慕课网讲师,一边准备长沙地区的前端技术分享会,又一边看犀牛书做总结,时间精力不够用但又想写一些干货分享给大家。为了满足自己的愿望,决定玩一个游戏。

游戏规则

下面有两篇文章的选题,同时有对应投票的链接(说白了就是一个微信付款方式,第一个是1元,第二个是2元)。一周后统计投票人数,支持人数多的文章在两周后发表。

游戏目的

  1. 了解大家究竟喜欢阅读哪方面的内容,做个调查,用钱投票应该算是最真实的反应吧。
  2. 督促自己,怕自己拖延症发作~因为如果付了钱文章又没写,信誉没了,还会被人指责骗子,担心自律不够的时候靠“他律”~哈哈~

游戏内容

  1. 一篇读书分享。最近朋友给我分享了一本很有意义的书,这本书网上也可以看到,关于人生观的,很有启发。内容比较杂,其中有一点提到用软件开发的思维来看待个人价值,让生为开发者都没想到的我十分惊叹和羞愧。人生本来是无意义的,而你自己却可以让其变得有意义。所以这篇读书分享写给那些想让自己人生变得有意义的、追求自我成长的读者。
  2. 讲一段关于我的故事。工作的第5个年头接近尾声了,环境上从几千号人的大企业到几十号人的小公司,知识上从一无所知到写文章录视频分享经验,过程中有积累经验和教训,也有对世事的感慨和唏嘘。所以这篇文章就是关于我个人成长经历、工作心得的一些分享(包括工作方面但可能不限于工作)。

投票链接


一部由众多技术专家推荐, 帮你成为具有全面能力和全局视野工程师的进阶利器—— 《了不起的JavaScript工程师》出版了! 点击下方链接即刻踏上进阶之路!


亚里士朱德 wechat
更多WEB技术分享请订阅微信公众号“WEB学习社”