ES6基础语法

常量

ES5中常量声明要通过Object.defineProperty函数来实现,要将常量绑定在某个控件上

// 声明一个常量属性,绑定在window上,命名PI2,值为3.1415926, 不可写
Object.defineProperty(window, "PI2", {
    value: 3.1415926,
    writable: false, 
})

ES6中,直接通过const关键字来定义常量

const PI = 3.1415
console.log(PI)

作用域

ES5中:for循环定义的var i 为全局变量

const callbacks = []
for (var i = 0; i <= 2; i++) {
    callbacks[i] = function() {
        return i * 2
    }
}

console.table([
    callbacks[0](),
    callbacks[1](),
    callbacks[2](),
])

输出结果为  6  6  6
console.log(i)输出是3
for循环中的var是一个全局变量,闭包调用方法时,因为i=3,利用i*2计算出的值也就全是6

ES6中:for循环定义的let j 为局部变量,作用域为 块{}

const callbacks2 = []
for (let j = 0; j <= 2; j++) {
    callbacks2[j] = function() {
        return j * 2
    }
}

console.table([
    callbacks2[0](),
    callbacks2[1](),
    callbacks2[2](),
])

输出结果为  0  2  4
console.log(j) 报错,j未定义
这里for循环中的 j 的作用域为 块作用域({}),每循环一次,进入一次{},变量j会保存一次
闭包调用时,会调用它的执行过程中的 j 的当时值

ES5及之前,没有块作用域的概念,如果想要声明一个只能在固定区域内使用的函数,只能通过将逻辑全部包装在一个立即执行函数中的方式:

(function() {
    const foo = function() {
        return 1
    }
    console.log("foo()===1", foo() === 1)// true
    // 开辟新的作用域
    ;((function() {
        const foo = function() {
            return 2
        }
        console.log("foo()===2", foo() === 2)// true
    })())
})()
此时foo函数只能在各自的function块内调用,程序不会报错,因为两个const foo函数是在不同的作用域内

ES6中:{}及代表一个块作用域

{
    function foo() {
        return 1
    }
    console.log("foo()===1", foo() === 1)// true
    // 开辟新的作用域
    {
        function foo() {
            return 2
        }

        console.log("foo()===2", foo() === 2)// true
    }
    console.log("foo()===1", foo() === 1)// true
}

箭头函数

语法类似于Java中的Lambda表达式,箭头函数中的this是指向定义时的this

ES3,ES5
{
  // ES3,ES5
  var factory = function() {
    this.a = 'a';
    this.b = 'b';
    this.c = {
      a: 'a+',
      b: function() {
        return this.a // 这里this发生变化,指向调用此function的对象
      }
    }
  }
  console.log(new factory().c.b());// c调用的b(),所以this指向的是c
}

此时控制台输出b方法的值为 "a+",因为function中的this指向的是调用它的对象
ES6{
  var factory = function() {
    this.a = 'a';
    this.b = 'b';
    this.c = {
      a: 'a+',
      b: () => {
        return this.a 
        // b 在定义这个箭头函数时,this指向factory,所以箭头函数中的this也指向factory
      }
    }
  }
  console.log(new factory().c.b());
}

此时控制台输出b方法的值为a,箭头函数中的this是指向定义时的this 

默认参数

ES6中的默认参数写法和C++相同

ES5\ES3 默认参数的写法,需要自己进行判断是否使用默认参数
{
  // ES5\ES3 默认参数的写法,需要自己进行判断是否使用默认参数
  function f(x, y, z) {
    if (y === undefined) {
      y = 7;
    }
    if (z === undefined) {
      z = 42
    }
    return x + y + z
  }
  console.log(f(1, 3));
}
ES6 可变参数
{
  // ES6 可变参数
  function checkParameter() {
    throw new Error('can\'t be empty')
  }
    // 可以通过默认参数赋函数的方式,对传值是否为空进行检验
  function f(x = checkParameter(), y = 7, z = 42) {
    return x + y + z
  }
  try {
    f() // 触发checkParameter
  } catch (e) {
    console.log(e);
  } finally {}
}

ES6中对可变参数的获取也变得简单,只需要使用扩展运算符(…)

ES3,ES5 可变参数
{
  // ES3,ES5 可变参数
  function f() {
    var a = Array.prototype.slice.call(arguments);// 这里arguments就是传入的参数
    var sum = 0;
    a.forEach(function(item) {
      sum += item * 1;
    })
    return sum
  }
  console.log(f(1, 2, 3, 6));
}

ES6 可变参数
{
  // ES6 可变参数
  function f(...a) { // 只需要申明扩展运算符(...),语义即为可变
    var sum = 0;
    a.forEach(item => {
      sum += item * 1
    });
    return sum
  }
  console.log(f(1, 2, 3, 6));
}

扩展运算符的其它用法
{
  // ES6 利用扩展运算符合并数组
  var params = ['hello', true, 7];
  var other = [
    1, 2, ...params
  ];
  console.log(other);
}
等价于
{
  // ES5 合并数组
  var params = ['hello', true, 7];
  var other = [1, 2].concat(params);
  console.log(other);
}

对象代理

对象代理用来解决没有私有变量的问题,对于一个变量只希望它在对象内部被使用。

ES3数据保护
{
  // ES3数据保护
  var Person = function() {
    var data = { // 通过类初始函数声明一个隐私的数据
      name: 'es3',
      sex: 'male',
      age: 15
    }
    // 声明getter、setter方法使外部对它操作
    this.get = function(key) {
      return data[key]
    }
    this.set = function(key, value) {
      if (key !== 'sex') { // 'sex'属性设置为只读
        data[key] = value
      }
    }
  }
}

ES5中可以采用声明常量绑定的方式
{
  // ES5中可以采用声明常量绑定的方式
  var Person = {
    name: 'es5',
    age: 15
  };
  // 声明属性,绑定在Person对象上,属性名为'sex',值为'male',不可写
  Object.defineProperty(Person, 'sex', {
    writable: false,
    value: 'male'
  });
}

ES6中使用对象代理的方式
{
  // ES6中使用对象代理的方式
  let Person = {
    name: 'es6',
    sex: 'male',
    age: 15
  };
  
  // 赋值一个代理类将原对象保护起来,代理对象为Person
  let person = new Proxy(Person, {
    get(target, key) {
      return target[key]
    },
    set(target,key,value){
      if(key!=='sex'){
        target[key]=value;
      }
    }
  });

  console.table({
    name:person.name,
    sex:person.sex,
    age:person.age
  });

  try {
    person.sex='female';
  } catch (e) {
    console.log(e);
  } finally {

  }

}

你可能感兴趣的:(前端)