【es6】块级作用域和函数声明

块级作用域和函数

es6明确规定,可以在块级作用域中声明,即使在严格模式下也不会报错

//首先在全局作用域中声明f函数
function f() {
    
     console.log('I am outside!'); }

(function () {
    
    
  if (false) {
    
    
    // 重复声明一次函数f
    //在es5中执行时,下面的函数定义会被提升到if外面,因为if不是块级作用域
    //在es6执行时,if是块级作用域,里面声明的函数f对外面没有影响,if false 里面不会执行,变量也不会提升,
    function f() {
    
     console.log('I am inside!'); }
  }
//es5最终输出inside
//es6最终输出outside,
  f();
}());

块级作用域中声明函数,es6会默认当作let声明,但是一些浏览器会将es6块级函数声明当作var声明,会将声明提升到作用域最前面,但是函数体无法提升,所以可能会导致未定义

// ES6的浏览器环境
function f() {
    
     console.log('I am outside!'); }
(function () {
    
    
  var f = undefined;
  if (false) {
    
    
    function f() {
    
     console.log('I am inside!'); }
  }

  f();
}());
// Uncaught TypeError: f is not a function

所以在块级作用域声明函数时,最好使用函数表达式,不会提升函数声明,在任何坏境下结果都是一样的

// 函数声明语句
{
    
    
  let a = 'secret';
  function f() {
    
    
    return a;
  }
}

// 函数表达式
{
    
    
  let a = 'secret';
  let f = function () {
    
    
    return a;
  };
}

const命令

const一旦声明就必须初始化,并且以后不可改变值
const声明对象,只能保证对象的地址不变,但是不能保证对象的值不变,

const foo = {
    
    };
foo.prop = 123;

foo.prop
// 123

foo = {
    
    }; // TypeError: "foo" is read-only
const a = [];
a.push('Hello'); // 可执行
a.length = 0;    // 可执行
a = ['Dave'];    // 报错
//彻底冻结对象,包括对象的属性
var constantize = (obj) => {
    
    
  Object.freeze(obj);
  //获取属性名,如果属性值是对象,就递归继续冻结该对象
  Object.keys(obj).forEach( (key, value) => {
    
    
    if ( typeof obj[key] === 'object' ) {
    
    
      constantize( obj[key] );
    }
  });
};

es6声明变量的方法:var let const function class import

es6规定,var和function声明的全局变量是全局对象的属性,但是新增加的不是,全局对象,浏览器值window,node.js是global

解构赋值

数组和对象解构,提取值,赋值给其他变量

以下是数组模式匹配赋值,只要模式相同就可以赋值

var [a, b, c] = [1, 2, 3];
//表示从数组中提取值,一一对应赋值给新的数组变量
//模式完全匹配赋值
let [foo, [[bar], baz]] = [1, [[2], 3]];
foo // 1
bar // 2
baz // 3
//省略前面参数赋值
let [ , , third] = ["foo", "bar", "baz"];
third // "baz"
//省略中间参数赋值
let [x, , y] = [1, 2, 3];
x // 1
y // 3
//省略末尾参数,使用点语法解构赋值
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]
//点语法使用一个数组接收参数
let [x, y, ...z] = ['a'];
x // "a"
y // undefined
z // []

不完全结构

//多余的参数无法匹配,忽略掉
let [x, y] = [1, 2, 3];
x // 1
y // 2

let [a, [b], d] = [1, [2, 3], 4];
a // 1
b // 2
d // 4

不可遍历的对象无法解构

let [foo] = 1;
let [foo] = false;
let [foo] = NaN;
let [foo] = undefined;
let [foo] = null;
let [foo] = {
    
    };

只要有iterator,就可以解构赋值

let [x, y, z] = new Set(["a", "b", "c"]);
x // "a"

猜你喜欢

转载自blog.csdn.net/weixin_43124546/article/details/110914882