1.Js的变量特点
1.1变量声明的提升
先看一道面试题
console.log(v1);
var v1 = 100;
function foo() {
console.log(v1);
var v1 = 200;
console.log(v1);
}
foo();
console.log(v1);
var声明变量时会提升到它所在作用域的顶端去执行,到我们代码所在的位置来赋值。
1.2函数的提升
函数的两种声明:
//函数声明式
function bar () {}
//函数字面量式 , 合普通变量提升的机制一样
var foo = function () {}
函数声明式的提升现象和变量提升略有不同:
console.log(bar);
function bar () {
console.log(1);
}
//打印结果:ƒ bar () {
// console.log(1);
//}
函数提升是整个代码块提升到它所在的作用域的最开始执行,上述代码执行顺序相当于
function bar () {
console.log(1);
}
console.log(bar);
思考下面的代码,这就是函数优先规则。
foo(); //3
var foo;
function foo () {
console.log(1);
}
function foo () {
console.log(3);
}
foo = function () {
console.log(2);
}
下面这段代码,在低版本的浏览器中,函数提升不会被条件判断所控制,输出2;但是在高版本的浏览器中会报错,所以应该尽可能避免在块内部声明函数
foo(); //低版本:2 //高版本: Uncaught TypeError: foo is not a function
var a = true;
if(a){
function foo () { console.log(1); }
}else{
function foo () { console.log(2); }
}
2.ES6的块级作用域绑定
2.1 let声明
- let声明不会被提升
- 禁止同一作用域的重复声明
- 块级作用域内有效
2.2 const 声明
- 声明的值是常量,一旦被设定后不可更改和重新赋值。
- 必须初始化。
- 块级作用域内有效
用const声明对象
const person = {
name: 'changchang'
}
//可以修改对象属性的值
person.name = 'zhangchangchang';
//抛出语法错误
person = {name: 'es6'}
2.3 循环中的块作用域绑定
for (let i = 0; i < 10; i++){
process(items[i]);
}
// i在这里不可访问,抛出错误
console.log(i);
2.4 循环中的函数
var funcs = [];
for (var i = 0; i < 10; i++){
funcs.push(function() {
console.log(i);
})
}
funcs.forEach((ele)=>{
ele(); //输出10次数字10
})
//循环离的每次迭代同时共享着变量i,循环内部创建的函数全部保留了相对变量的引用。循环结束时变量i的值为10,所以forEach时每次都会输出10。
//用forEach来console.log(ele)得出ƒ (){console.log(i)},而此时i=10,所以输出10次10
循环中的立即执行函数(IIFE)
var funcs = [];
for (var i = 0; i < 10; i++){
funcs.push((function(value) {
return function(){
console.log(value);
}
}(i))); //把当前的i存放到形参value里
}
funcs.forEach((ele)=>{
ele(); //输出0 1 2...
})
//如果console.log(ele),得出ƒ (){console.log(value);}
循环中的let声明
var funcs = [];
for (let i = 0; i < 10; i++){
funcs.push(function() {
console.log(i);
})
}
funcs.forEach((ele)=>{
ele(); //输出0 1 2 ...
})
//let在每次迭代循环都会创建一个新变量
对于for-in合for-of也是一样的
var funcs = [];
var object = {a: true, b:true, c: true};
for (let key in object){
funcs.push(function(){
console.log(key);
});
}
funcs.forEach((ele)=>{
ele(); //输出a b c ...
})
循环中的const声明
// 报错
for (const i = 0; i < 10; i++){
...
}
var object = {a: true, b:true, c: true};
// 可以正常输出,因为每次迭代都会创建一个新绑定
for (const key in object){
console.log(key);
}
参考文章:
《深入理解ES6》
https://blog.csdn.net/qq_3971...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。