作用域和闭包
现有声明后有赋值
声明在编译时会提升位置,提升时函数会优先变量,如果是同名函数顺序排在后面的会覆盖前面的函数
函数表达式:
立即执行的函数表达式
1 2 3 4 5 | var a = 2; ( function IIFE(global) { var a = 3; console.log(a) //3 })(window); |
块作用域和闭包
闭包:
1 2 3 4 5 6 7 8 9 10 | function foo(){ var a = 3; function bar() { console.log(a); } return bar } var baz = foo(); baz() // 3 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | for ( var i = 0; i< 5; i++){ setTimeout( function timer(){ console.log(i); },i*1000) } // 5 // 5 // 5 // 5 // 5 // 不是期待的结果,因为他们要找i的话就要取的同一个i 解决方式 闭包: for ( var i = 0; i< 5; i++){ ( function (j){ setTimeout( function timer(){ console.log(j); },i*1000) })(i) } 块作用域: for ( let i = 0; i< 5; i++){ setTimeout( function timer(){ console.log(i); },i*1000) } |
es6之前模块化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | var foo = ( function Greeting() { function goodMorning(){ console.log( "goodMorning" ); } function goodAfternoon(){ console.log( "goodAfternoon" ); } function goodEvening(){ console.log( "goodEvening" ); } return { goodMorning:goodMorning, goodAfternoon:goodAfternoon, goodEvening:goodEvening } })() |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | var MyMoudles = ( function Manager() { var modules = {}; function define(name,deps,impl){ for ( var i=0;i<deps.length;i++){ deps[i]= modules[deps[i]]; } modules[name]= impl.apply(impl,deps); } function get(name){ return modules[name]; } return { define:define, get:get } })() // 添加例子 MyMoudles.define( "bar" ,[], function (){ function hello(who){ console.log( "hello!" +who); } }) var bar = MyModules.get( "bar" ); bar.hello( "xiao jie jie" ); |
es6模块化:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | //bar.js function hello(who){ console.log( "hello!" +who); } export hello; //main.js // import bar from "bar" module bar from "bar" bar.hello( "xiao jie jie" ); // import 是将一个模块中的一个或者多个api倒入当前作用域中 // module是将整个模块的api导入并绑定到一个变量上 |
this与词法作用域
this指向问题:
1 2 3 4 5 6 7 8 9 | var obj = { id = "awesome" , cool: function coolFn() { console.log( this .id); } } var id = "not awesome" ; obj.cool(); // awesome setTimeout(obj.cool,100); //not awesome |
解决方法:
第一种
1 2 3 4 5 6 7 8 9 10 11 12 13 | var obj = { count: 0, cool: function coolFn() { var self = this ; if (self.count < 1){ setTimeout( function timer(){ self.count++; console.log( "awesome" ); },100) } } } obj.cool(); // awesome |
第二种
1 2 3 4 5 6 7 8 9 10 11 12 | var obj = { count: 0, cool: function coolFn() { if ( this .count < 1){ setTimeout( function timer(){ this .count++; console.log( "awesome" ); }.bind( this ),100) } } } obj.cool(); // awesome |
第三种
1 2 3 4 5 6 7 8 9 10 11 12 | var obj = { count: 0, cool: function coolFn() { if ( this .count < 1){ setTimeout(()=>{ this .count++; console.log( "awesome" ); },100) } } } obj.cool(); // awesome |
分类:
JavaScript
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 2025成都.NET开发者Connect圆满结束
· 后端思维之高并发处理方案
· 千万级大表的优化技巧
· 在 VS Code 中,一键安装 MCP Server!
· 10年+ .NET Coder 心语 ── 继承的思维:从思维模式到架构设计的深度解析