10招打通你的js任督二脉
2015-11-19 11:46
651 查看
这段时间一直在看 亚里士朱德的文章,有一篇是我感触颇多,我跟着演示了几遍,也顺便 炒一下冷饭 ^_^
感兴趣的同学可以download下来 演示一下。
原文@ 亚里士朱德《十段代码打通js学习的任督二脉》
http://yalishizhude.github.io/2015/10/25/10/
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>十招打通js任督二脉</title> </head> <body> 打开控制台,咱们直接上代码。 <script type="text/javascript"> /*第一招:简单回调*/ //this指针指向当前函数对象 var simpleCallBack=(function(){ console.log('这是第一招:'); this.a="I'm an a"; function foo(){ console.log(this.a); } function doFoo(fn){ fn(); } function doFoo2(o){ o.foo(); } this.obj={ a:2, foo:foo }; doFoo(obj.foo); doFoo2(obj); })(); /*第二招:用apply改变函数作用域*/ //apply,call,bind都有个作用就是改变作用域,这里的apply将foo函数的作用域指向obj对象,同时传入参数。 //再简单分析一下bind函数内部的嵌套,执行bind函数的时候返回的是一个匿名函数,所以执行bar(3)的时候实际上是执行的bind内部的匿名函数,返回的是之前传入的foo函数的执行结果。 //函数没有返回值的情况下默认返回undefined。 var applyChangeScope=(function(){ console.log('这是第二招:'); function foo(something) { console.log(this.a,something); } function bind(fn,obj){ return function(){ return fn.apply(obj,arguments); } } this.obj={ a:2 } this.bar=bind(foo,obj); this.b=bar(3); console.log(b); })(); /*第三招:new关键字*/ //bind函数的一个参数为null代表作用域不变,后面的不定参数将会和函数本身的参数按次序绑定,绑定之后执行函数只能从未绑定的参数开始传值。 var theKeywordNew=(function(){ console.log('这是第三招:'); function foo(a,b){ this.val=a+b; } this.bar=foo.bind(null,'p1'); this.baz=new bar('p2'); console.log(baz.val); })(); /*第四招:自执行函数*/ //立即执行匿名函数可以避免污染全局空间,但很少有人去关注赋值语句执行之后会返回什么结果,其实就是返回当前值。 //也就是说当括号内执行完成赋值之后,返回的是o对象中的foo函数,函数的执行环境中有一个a对象。 var executeFunction=(function(){ console.log('这是第四招:'); function foo(){ console.log(this.a); } this.a=2; this.o={a:3,foo:foo}; this.p={a:4}; (p.foo=o.foo)(); })(); /*第五招:变量属性*/ //当一个变量被声明之后,扩充其属性并不会改变原数据类型 var variableAttribute=(function(){ console.log('这是第五招:'); this.a=[]; a[0]=1; a['foobar']=2; console.log(a.length); console.log(a.foobar); }); /*第六招:精度问题*/ //当操作小数时请小心,js的小数计算并不精确,所以下面的判断是false //字符串变量是常亮 var accuracyProblem=(function(){ console.log('这是第六招:'); this.a='foo'; a[1]='o'; console.log(0.1+0.2==0.3||a); })(); /*第七招:命名提升*/ //声明的变量和命名函数都会被提升到代码的最前面,只不过声明的额变量的赋值语句在代码的位置不变。所以下面的代码可以理解为: //var foo; //function foo(){ // console.log(1); //} //foo(); //foo=0; //foo=function(){ // console.log(2); //}; var naming1=(function(){ console.log('这是第七招:'); foo(); this.foo=0; function foo(){ console.log(1); } this.foo=function(){ console.log(2); }; })(); /*更诡异的变招*/ var naming2=(function(){ console.log('下面的这招能看懂就是理解第七招精髓了:'); foo(); this.foo=0; function foo(){ console.log(1); } /*下面就开始报错了(可以去掉注释看看) this.foo(); this.foo=function(){ console.log(2); }; this.foo(); */ })(); /*第八招:作用域*/ //javascript没有代码作用域,只有函数作用域 // 下面的代码可以理解为: // function foo(){ // console.log('a'); // } // function foo(){ // console.log('b'); // } // foo(); // var a=true; // if(a){}else{} var scope=(function(){ console.log('这是第八招:') foo(); this.a=true; if(this.a){ function foo(){ console.log('a'); } }else{ function foo(){ console.log('b'); } } })(); /*第九招:闭包陷阱*/ //闭包有个重要的作用就是,在内层函数引用外层函数定义的变量时,外层函数的变量不会被持久化。这里有个隐藏陷阱就是for循环结束之后i仍然自增了1 var closureTrap=(function(){ console.log('这是第九招:'); for(var i=1;i<=5;i++){ setTimeout(function(){ console.log(i); },i*1000); } })(); /*第十招:伪闭包*/ // 闭包是函数的嵌套定义,而不是函数的嵌套调用 var pseudoClosure1=(function(){ console.log('这是第十招:'); function foo(){ console.log(a); } function bar(){ var a=3; foo(); } this.a=2; bar(); })(); //那么问题来了,怎么输出3呢? var pseudoClosure1=(function(){ console.log('第十招变招:'); function bar(){ function foo(){ console.log(a); } var a=3; foo(); } this.a=2; bar(); })(); /* * @参考:亚里士朱德《十段代码打通js学习的任督二脉》 * http://yalishizhude.github.io/2015/10/25/10/ */ </script> </body> </html>
感兴趣的同学可以download下来 演示一下。
原文@ 亚里士朱德《十段代码打通js学习的任督二脉》
http://yalishizhude.github.io/2015/10/25/10/
相关文章推荐
- JSP语法概述
- JS——特效秀
- (转)[开发笔记]-js判断用户的浏览设备是移动设备还是PC
- composer.json手记
- javascript中的后退和刷新
- javascript实现二级级联菜单的简单制作
- JSP内置对象
- JSONP跨域访问在线代理API
- 认识PHP代码标识 想在页面中编写PHP代码非常容易,如下面代码: <?php echo "想学习php吗?来慕课网吧"; ?> 就像你可以编写JavaScript脚本语言需要写在<scri
- JS滚轮事件
- 个人整理的web开发中常用的表单验证的正则表达式JS
- qq第3方登录的JS实现方式记录
- JS 接口定义及实现的例子
- ResultSet转Json
- js 里的escape() 函数
- 简单分析一个通过 js 劫持进行案例
- 常规功能和模块自定义系统 (cfcmms)—017自定义grid方案(1)
- JS事件监听器
- 关于正则表达式 g,m 参数的总结
- JSON的parse()和stringfy()方法