前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

ES6+

作者头像
ymktchic
发布2022-01-18 17:21:41
2270
发布2022-01-18 17:21:41
举报
文章被收录于专栏:ymktchicymktchic

ECMAScript 和 JavaScript 的关系

一个常见的问题是,ECMAScript 和 JavaScript 到底是什么关系?

要讲清楚这个问题,需要回顾历史。1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给标准化组织 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript,这个版本就是 1.0 版。

该标准从一开始就是针对 JavaScript 语言制定的,但是之所以不叫 JavaScript,有两个原因。一是商标,Java 是 Sun 公司的商标,根据授权协议,只有 Netscape 公司可以合法地使用 JavaScript 这个名字,且 JavaScript 本身也已经被 Netscape 公司注册为商标。二是想体现这门语言的制定者是 ECMA,不是 Netscape,这样有利于保证这门语言的开放性和中立性。

因此,ECMAScript 和 JavaScript 的关系是,前者是后者的规格,后者是前者的一种实现。

let特点

变量不能重复声明

代码语言:javascript
复制
let star = '罗志祥';
let star = '小猪';
image-20211210121526853
image-20211210121526853

块儿级作用域

代码语言:javascript
复制
{
    let girl = '周扬青';
}
console.log(girl);
   

在里面定义的变量外面找不到

不存在变量提升

代码语言:javascript
复制
console.log(song);
let song = 'lemon tree' //无效写法,无法作用于console.log

不影响作用域链

代码语言:javascript
复制
{
let school = 'ynnubs'
function fn(){
 console.log(school)
}
fn();
}

通俗来讲,就是在外面定义的变量里面找得到,反之,函数里面定义的变量外面就找不到。

案例

  1. 一定要赋初始值
  2. 一般常量使用大写。
  3. 常量的值不能修改
  4. 块级作用域
  5. 对于数组和对象的元素修改,不算做对常量的修改,不会报错。

变量解构赋值

代码语言:javascript
复制
const F4 = ['小沈阳','刘能','赵四','宋小宝'];
let [xiao, liu, zhao, song] = F4;
console.log(xiao);
console.log(liu);
console.log(zhao);
console.log(song);

对象的解构

代码语言:javascript
复制
const zhao = {
    name: '赵本山',
    age: '不详',
    xiaopin: function(){
        console.log("我可以演小品");
    }
};

let {name, age, xiaopin} = zhao;
console.log(name);
console.log(age);
console.log(xiaopin);
xiaopin();

/*let {xiaopin} = zhao;
xiaopin();  可以单独的解构*/

模板字符串

声明

代码语言:javascript
复制
   ES6 引入新的声明字符串的方式 『``』

let str = 我也是一个字符串哦!;console.log(str, typeof str);

内容中可以直接出现换行符

代码语言:javascript
复制
let str = `<ul>
            <li>沈腾</li>
            <li>玛丽</li>
            <li>魏翔</li>
            <li>艾伦</li>
            </ul>`;

变量拼接

代码语言:javascript
复制
let lovest = '魏翔';
let out = `${lovest}是我心目中最搞笑的演员!!`;
console.log(out);

简化对象写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

代码语言:javascript
复制
let name = 'aaa';
      let change = function(){
          console.log('我们可以改变你!!');
      }

      const school = {
          name,
          change,
          improve(){
              console.log("我们可以提高你的技能");
          }
      }

      console.log(school);

箭头函数

ES6 允许使用「箭头」(=>)定义函数。

代码语言:javascript
复制
let fn = (a,b) => {
    return a + b;
}

let result = fn(1, 2);
console.log(result);
代码语言:javascript
复制
//1. this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值
      function getName(){
          console.log(this.name);
      }
      let getName2 = () => {
          console.log(this.name);
      }

      //设置 window 对象的 name 属性
      window.name = 'aaa';
      const school = {
          name: "ATGUIGU"
      }

      //直接调用
      // getName();
      // getName2();

      //call 方法调用
      // getName.call(school);
      // getName2.call(school);

      //2. 不能作为构造实例化对象
      // let Person = (name, age) => {
      //     this.name = name;
      //     this.age = age;
      // }
      // let me = new Person('xiao',30);
      // console.log(me);

      //3. 不能使用 arguments 变量
      // let fn = () => {
      //     console.log(arguments);
      // }
      // fn(1,2,3);

      //4. 箭头函数的简写
          //1) 省略小括号, 当形参有且只有一个的时候
          // let add = n => {
          //     return n + n;
          // }
          // console.log(add(9));
          //2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略
          // 而且语句的执行结果就是函数的返回值
          let pow = n => n * n;
              
          console.log(pow(8));

扩展运算符

扩展运算符能将『数组』转换为逗号分隔的『参数序列』,也就是将数组转成了实参。

代码语言:javascript
复制
const tfboys = ['易烊千玺','王源','王俊凯'];
// => '易烊千玺','王源','王俊凯'

// 声明一个函数
function chunwan(){
    console.log(arguments);
}

chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')

拓展运算符应用

数组的合并

代码语言:javascript
复制
const kuaizi = ['王太利','肖央'];
const fenghuang = ['曾毅','玲花'];
// const zuixuanxiaopingguo = kuaizi.concat(fenghuang);
const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];
console.log(zuixuanxiaopingguo);

数组的克隆

代码语言:javascript
复制
const sanzhihua = ['E','G','M'];
const sanyecao = [...sanzhihua];//  ['E','G','M']
console.log(sanyecao);

将伪数组转为真正的数组

代码语言:javascript
复制
const divs = document.querySelectorAll('div');
const divArr = [...divs];
console.log(divArr);// arguments

symbol的基本使用

ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。

ES5 的对象属性名都是字符串,这容易造成属性名的冲突。比如,你使用了一个他人提供的对象,但又想为这个对象添加新的方法(mixin 模式),新方法的名字就有可能与现有方法产生冲突。如果有一种机制,保证每个属性的名字都是独一无二的就好了,这样就从根本上防止属性名的冲突。这就是 ES6 引入Symbol的原因。

Symbol 值通过Symbol函数生成。这就是说,对象的属性名现在可以有两种类型,一种是原来就有的字符串,另一种就是新增的 Symbol 类型。凡是属性名属于 Symbol 类型,就都是独一无二的,可以保证不会与其他属性名产生冲突。

代码语言:javascript
复制
let s = Symbol();

typeof s
// "symbol"

上面代码中,变量s就是一个独一无二的值。typeof运算符的结果,表明变量s是 Symbol 数据类型,而不是字符串之类的其他类型。

注意,Symbol函数前不能使用new命令,否则会报错。这是因为生成的 Symbol 是一个原始类型的值,不是对象。也就是说,由于 Symbol 值不是对象,所以不能添加属性。基本上,它是一种类似于字符串的数据类型。

Symbol函数可以接受一个字符串作为参数,表示对 Symbol 实例的描述,主要是为了在控制台显示,或者转为字符串时,比较容易区分。

代码语言:javascript
复制
let s1 = Symbol('foo');
let s2 = Symbol('bar');

s1 // Symbol(foo)
s2 // Symbol(bar)

s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"

上面代码中,s1s2是两个 Symbol 值。如果不加参数,它们在控制台的输出都是Symbol(),不利于区分。有了参数以后,就等于为它们加上了描述,输出的时候就能够分清,到底是哪一个值。

迭代器(遍历器)

JavaScript 原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6 又添加了MapSet。这样就有了四种数据集合,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是MapMap的成员是对象。这样就需要一种统一的接口机制,来处理所有不同的数据结构。

遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。

Iterator 的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of消费。

Iterator 的遍历过程是这样的。

(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

每一次调用next方法,都会返回数据结构的当前成员的信息。具体来说,就是返回一个包含valuedone两个属性的对象。其中,value属性是当前成员的值,done属性是一个布尔值,表示遍历是否结束。

下面是一个模拟next方法返回值的例子。

代码语言:javascript
复制
const banji = {
         name: "终极一班",
         stus: [
             'xiaoming',
             'xiaoning',
             'xiaotian',
             'knight'
         ],
         [Symbol.iterator]() {
             //索引变量
             let index = 0;
             //
             let _this = this;
             return {
                 next: function () {
                     if (index < _this.stus.length) {
                         const result = { value: _this.stus[index], done: false };
                         //下标自增
                         index++;
                         //返回结果
                         return result;
                     }else{
                         return {value: undefined, done: true};
                     }
                 }
             };
         }
     }

     //遍历这个对象 
     for (let v of banji) {
         console.log(v);
     }

参考作者:阮一峰

授权:署名-非商用许可证

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-12-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ECMAScript 和 JavaScript 的关系
  • let特点
    • 案例
    • 变量解构赋值
      • 对象的解构
      • 模板字符串
      • 简化对象写法
      • 箭头函数
      • 扩展运算符
        • 拓展运算符应用
        • symbol的基本使用
        • 迭代器(遍历器)
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档