执行结果为:10
因为此处的i使用var去声明且这个循环体未处于一个函数当中,所以此处声明的i为全局作用域中的i,而console.log(i)里面的i指向的也是全局作用域中的i。当循环体执行完毕后全局作用域的i累加到10并保持不变,所以当调用a[6]时会输出结果10,且a[0]~a[9]调用时输出的结果都为10
执行结果为:报错,提示不能在声明前使用这个变量
这段代码中存在一个全局变量tmp,但是在块级作用域里又用let声明了一个局部变量tmp,导致后者绑定这个块级作用域,所以在let声明前输出这个tmp的值会报错
var arr = [12,34,32,89,4]
最小值为:Math.min(...arr)
let的用法与var相同,但是通过let声明的变量只能在所声明的代码块中被访问到,外部无法访问且var声明的变量会提升,而let声明不会
const用于声明一个只读的常量,在let的基础上多了只读的特性,且const声明的同时需要设置一个初始值,设置初始值后const声明的常量的内存地址便不可再次修改,但可修改常量中的属性成员
执行结果为:20
因为fn为一个普通的函数,所以他的this的指向由调用它的obj决定,而定时器中的函数为一个箭头函数,所以他的this由他声明时所在的作用域决定,他声明时所在的作用域为fn函数的作用域,所以箭头函数中的console.log(this.a)中的this继承fn中的this,所以this.a实际上就是obj中a的值,输出结果为20
Symbol类型主要的用途就是为对象添加独一无二的属性名,解决对象属性名冲突的问题
Symbol也可以用来定义一个迭代器和定义对象的toString结果
浅拷贝:浅拷贝指的是只拷贝对象中的数据,拷贝出来的对象和源对象的引用地址相同
深拷贝:会克隆出一个对象,数据相同,但引用地址不同
异步编程是为了解决js单线程机制所带来的一些问题,在异步过程中,工作线程在异步操作完成后需要通知主线程,通知机制是通过消息队列和事件循环来实现的
而Event Loop便是事件循环,事件循环就是主线程重复从消息队列中取出消息然后执行的过程,取出一个消息并执行的过程叫做一次循环
宏任务:在浏览器端,一个宏任务执行完成后,下一个宏任务执行开始前浏览器可以进行页面渲染,能触发宏任务的有以下几个操作
- script(整体代码)
- setTimeout,setInterval,setImmediate
- I/O,UI交互事件
- postMessage,MessageChannel
微任务:通常在一个宏任务执行完成之后立即执行的任务,能触发微任务的有以下几个操作
- Promise.then
- MutationObserver
- Process.nextTick(Node环境)
new Promise(function(resolve,reject){
var a = "hello"
resolve(a)
}).then(function(res){
var b = "lagou"
return res + b
}).then(function(res){
var c = "I ❤ U"
console.log(res + c)
})
TypeScript是基于JavasScript之上的编程语言,是JavaScript的超集合/扩展集
TypeScript在JavaScript的基础之上多出一些扩展特性,如类型系统和对EMCAScript新特性的支持
TypeScript在最终运行时会被编译成JavaScript
优点:
- 强大的类型系统,可以避免在开发过程中有可能会出现的类型一次,从而提高编码效率和代码的可靠程度
- 增加了代码的可读性和可维护性
- 对于ECMAScript的新特性的支持非常友好
- TypeScript最低可编译成ES3的代码,兼容性非常好
- 功能强大,生态健全、完善,社区活跃
缺点:
- 语言本身有很多的概念,学习成本高
- 对于周期比较短的项目,项目初期会增加项目的开发成本