块作用域
if(true){
var a = 5;
}
console.log(a); // 5
if (true) {
let b = 5;
}
console.log(b); // ReferenceError: b is not defined
总结:
-
在过去 JS 是没有块级作用域这个概念的,只有函数作用域,因为使用var定义的变量都会被提升到最上面(如果var定义在函数里面也会被提升到函数的最上面)
-
但是好在ES6推出了let和const关键字,让JS也拥有了块级作用域
变量提升的细节
a = 2;
var a;
console.log( a );
// 编译后的代码
var a;
a = 2;
console.log( a ); // 答案是2
console.log( a );
var a = 2;//浏览器解析到这里 编译器会将这段代码编译成 var a; a = 2; var a会被提到最前面
// 最终经过编译的最终代码是
var a
console.log( a ); // undefined 因为 a只是定义还没有赋值 所以是 undefined
a = 2
foo(); // 不是 ReferenceError, 而是 TypeError!
var foo = function bar() { // … }; // 这里不是函数声明 而是函数表达式
// 编译器处理后
var foo
foo() // TypeError 类型错误 还没声明 foo是函数就使用函数的调用方法
foo = function bar(){}
foo(); // 1
var foo;
function foo() { console.log( 1 ); } // 函数会被提升到最前面,换句话说,函数最先提升
foo = function() { console.log( 2 ); };
总结:
-
只有声明本身会被提升,赋值和其他的逻辑会留在原地
-
var 和 函数声明都会提升
-
函数声明会被提升,但是函数表达式却不会被提升
-
函数会首先被提升,然后才是变量
闭包
function setupBot(name, selector) {
$( selector ).click( function activator() {
console.log( "Activating: " + name );
} );
}
setupBot( “Closure Bot 1”, “#bot_1” );
setupBot( “Closure Bot 2”, “#bot_2” );
// 以上的函数就是一个闭包
function foo() {
var a = 2;
function bar() {
console.log( a );
}
return bar;
}
var baz = foo(); baz(); // 2 —— 朋友,这就是闭包的效果。
总结:
-
函数是在它本身的词法作用域以外执行。
-
只要使用了回调函数,实际上就是在使用闭包!
循环和闭包
for (var i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
// 结果: 输出5次6
// 因为setTimeout()是一个异步的函数,for循环结束了才会执行setTimeout,而for循环结束的时候 i是等于6的 所以最终会输出5次6
// 因为我们试图在每次循环的时候都能保存下一个i的副本,但是实际上因为作用域,每次都是同一个i,最终i被赋值成了6,所以输出了5次6
解决方案:
for (var i=1; i<=5; i++) {
(function(j) {
setTimeout( function timer() {
console.log( j );
}, j*1000 );
})( i );
}
// 这样就可以解决了, 每次运行的时候都将i存进一个立即执行函数里面,立即执行函数又作用域又可以防治变量污染,就可以解决这个问题了
最优方案:
for (let i=1; i<=5; i++) {
setTimeout( function timer() {
console.log( i );
}, i*1000 );
}
// let 声明,可以用来劫 持块作用域,并且在这个块作用域中声明一个变量
函数的this绑定
this绑定如果分类的话可以分为四类:默认绑定、显示绑定、隐式绑定、new绑定
- 默认绑定
function demo(){
cconsole.log(this.a)
}
var a = 2
demo() // 2
// demo 等于是自己运行自己,这里相当于是 window.demo() this指向的window,所以最终指向了全局的那个等于2的a
// 注意 如果是严格模式下这个 this指向的就是 undefined 因为 严格模式下的是不能将变量挂载在全局的
- 隐式绑定
function foo() {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V:vip1024c 备注前端获取(资料价值较高,非无偿)
结尾
学习html5、css、javascript这些基础知识,学习的渠道很多,就不多说了,例如,一些其他的优秀博客。但是本人觉得看书也很必要,可以节省很多时间,常见的javascript的书,例如:javascript的高级程序设计,是每位前端工程师必不可少的一本书,边看边用,了解js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。
开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】
料价值较高,非无偿)**
[外链图片转存中…(img-KqLqee8i-1711606530288)]
结尾
学习html5、css、javascript这些基础知识,学习的渠道很多,就不多说了,例如,一些其他的优秀博客。但是本人觉得看书也很必要,可以节省很多时间,常见的javascript的书,例如:javascript的高级程序设计,是每位前端工程师必不可少的一本书,边看边用,了解js的一些基本知识,基本上很全面了,如果有时间可以读一些,js性能相关的书籍,以及设计者模式,在实践中都会用的到。