ES6语法基础

变量
ES6中,增加了let和const两个关键字声明变量。
建议大家放弃var声明变量的模式。var的特性与现代语言差异过大,非常容易造成bug
1,let
let声明变量非常简单,如下代码:

let name = 'Tom';
console.log(name);

let a = 1;
let b = 2;
let sum = a+b;

在声明变量中,变量名为驼峰命名法。例如:let myName = ‘Tom’;
变量一定要先申明,在使用,例如:

console.log(name);//错误,找不到name
let name = 'Tom';

2,const
const声明的变量,其值不能改变,代码如下:

const age = 10;
age = 11;//error,const 声明的变量,其值不能改变

但大家一定注意一点,const声明的变量值不能变,但如果该变量为对象,其对象属性值可变。

const person={
    name:'Tom',
    age:10,
};

person.name = 'Jhon';//没问题

person = {
    name:'TT',
    age:11
}//error,错误,不能改变person的值

3,变量作用域

let和const声明的变量,以大括号为作用域边界,只有在变量作用域内,才可以使用该变量,超过变量作用域再使用该变量,报错。例如:

{
    const name = 'Tom';
    console.log(name);//正确
}
console.log(name);//错误!name作用域再上面大括号内,超过无法使用

在有多层作用域嵌套的情况下,如果有同名变量,内层变量会屏蔽外面变量作用域,例如:

{
    const name = 'Tom';
    {
        const name = 'Jim';
        console.log(name);//打印为Jim
    }
    console.log(name);//打印为Tom
}

在多层作用域嵌套下,如没有同名变量,作用域范围不变。例如:

{
    const name = 'Tom';
    {
        console.log(name);//打印为Tom
    }
    console.log(name);//打印为Tom
}

注意,在多层作用域嵌套下,内层如有声明同名变量,内层变量声明之前,变量不能使用。例如:

{
    const name = 'Tom';
    {
        console.log(name);//错误!找不到name变量!
        const name = 'Jim';

    }
    console.log(name);//打印为Tom
}

字符串
JavaScript的字符串就是用”或”“括起来的字符表示。
如果’本身也是一个字符,那就可以用”“括起来,比如”I’m OK”包含的字符是I,’,m,空格,O,K这6个字符。
如果字符串内部既包含’又包含”怎么办?可以用转义字符\来标识,比如:

'I\'m \"OK\"!';

表示的字符串内容是:

I'm "OK"!

1,字符串模板
要把多个字符串连接起来,可以用+号连接:

const name = 'Tom';
const age = 10;
const message = 'Hello, ' + name + ', your age is' + age;
console.log(message);

如果有很多变量需要连接,用+号就比较麻烦。ES6新增了一种模板字符串,表示方法和上面的多行字符串一样,但是它会自动替换字符串中的变量:

const name = 'Tom';
const age = 10;
const message = `Hello, ${name}, your age is ${age}`JavaScript为字符串提供了一些常用方法,注意,调用这些方法本身不会改变原有字符串的内容,而是返回一个新字符串

注意包裹字符串的字符为反引号,esc按键下方的字符,英文状态下输入。

2,多行字符串
由于多行字符串用\n写起来比较费事,所以最新的ES6标准新增了一种多行字符串的表示方法,用反引号包裹。

`Hello
World`//这是一个多行字符串

3,操作字符串

获取字符串长度

const s = 'Hello, world!';
s.length; // 13

要获取字符串某个指定位置的字符,使用类似Array的下标操作,索引号从0开始:

const s = 'Hello, world!';

s[0]; // 'H'
s[6]; // ' '
s[7]; // 'w'
s[12]; // '!'
s[13]; // undefined 超出范围的索引不会报错,但一律返回undefined

注意:字符串是不可变的,如果对字符串的某个索引赋值,不会有任何错误,但是,也没有任何效果

const s = 'Test';
s[0] = 'X';
console.log(s); // s仍然为'Test'·

JavaScript为字符串提供了一些常用方法,注意,调用这些方法本身不会改变原有字符串的内容,而是返回一个新字符串。
indexOf,会搜索指定字符串出现的位置:

const s = 'hello, world';
s.indexOf('world'); // 返回7
s.indexOf('World'); // 没有找到指定的子串,返回-1

substring,返回指定索引区间的子串:

const s = 'hello, world'
s.substring(0, 5); // 从索引0开始到5(不包括5),返回'hello'
s.substring(7); // 从索引7开始到结束,返回'world'

更多JavaScript 字符串操作,可参见 W3School教程

数组

JavaScript的Array可以包含任意数据类型,并通过索引来访问每个元素。通过length可以访问数组长度。
1,通过索引访问数组元素

//通过索引读取数组中的元素
const item = array[0];
console.log(item);//输出0

注意:JavaScript中对数组越界操作没有异常处理

const array = [1,2,3,4];
console.log(array[5]);//不报错,打印undefined

2, 通过数组索引,可以修改数组中元素值

const array = [1,2,3,4];
array[0] = 5;
console.log(array[0]);//输出为5

注意:对越界修改数组的值,会改变数组长度,且为赋值的元素值为undefined。不建议此操作

const array = [1,2,3,4];
array[5] = 6;
console.log(array);//打印结果为[1,2,3,4,undefined,6]

3,push和pop

//push()向数组末尾添加元素
const array = [1,2,3,4];
array.push(5);
console.log(array);//打印结果[1,2,3,4,5]

//pop()从数组末尾删除元素
const array = [1,2,3,4];
array.pop();
console.log(array);//打印结果为[1,2,3];

4,splice

该方法可以操作数组在制定位置添加或删除元素

//删除指定元素
//splice(index,length)从index位置开始删除长度为length
const array = [1,2,3,4];
array.splice(1,1);//从下标1开始删除一个元素,即把2删除
console.log(array);//输出结果[1,3,4]
//添加制定元素
//splice(index,0,item1,item2,...),表示从index位置开始添加各元素,其他元素后移
const array = [1,2,3,4];
array.splice(1,0,5);
console.log(array);//输出结果[1,5,2,3,4]
//混合操作,添加删除
const array = [1,2,3,4];
array.splice(1,1,5);
console.log(array);//输出结果[1,5,3,4]

其他Array操作方法,详见W3SchoolArray教程

对象
JavaScript的对象是一种无序的集合数据类型,它由若干键值对组成。
键值对是有键和值组成的,一般称为key-value。键和值直接用冒号分割,键只能为字符串,值可以为任何类型。
在对象中,多个键值对之前没有顺序概念,之间用逗号const obj = {
name:’Tom’,
age:10,
‘a:b’:’xx’,
}符串,默认可以不加单引号,但如果字符串本身不加单引号有歧义
比如,上方第三个键值对中的键,为a:b一个字符串,如不加单引号,会有歧义,所以需要加。
通过对象的键可以对其对应的值进行读写操作。

const obj = {
    name:'Tom',
    age:10,
    'a:b':'xxx',
}

//通过 . 读取对象属性值
console.log(obj.name);//输出Tom
obj.name = 'XXX';
console.log(obj.name);//输出XXX

//通过 [] 读取对象属性值,中括号内需要填字符串
console.log(obj.['age']);
obj['age'] = 11;
console.log(obj['age']);

//有歧义的键,只能用[]号方式访问
console.log(obj.['a:b']);

//使用变量作为键时,只能使用[]方式访问
const key = 'name';
console.log(obj.[key]);

函数

JavaScript中提供函数的定义和调用方式
1,基本语法

{
  return x + y;
}

const sum = add(1,2);
console.log(sum);//结果为3

2,参数默认值

function add(x = 1,y = 2){
    return x+y;
}

const sum1 = add();
console.log(sum1);//结果为3

const sum2 = add(2);
console.log(sum2);//结果为4

const sum3 =  add(2,3);
console.log(sum3);//结果为5

3,箭头函数

ES6增加箭头函数特性

(x,y)=>{
    return x + y;
}

箭头函数没有函数名,只描述了参数列表和函数体。
通常情况下,箭头函数一般作为值进行传递。

const aFunc = ()=>{
    console.log('xxx');
}//将箭头函数赋值给aFunc变量

const bFunc = aFunc;//通过aFunc变量为bFunc变量赋值

箭头函数无法直接被调用,只能借助存放箭头函数值的变量进行调用,调用方法与调用普通函数一样

const add = (x,y)=>{
    return x+y;
}
const sum = add(1,2);
console.log(sum);//结果为3

箭头函数也经常作为函数的参数,为函数形参赋值

function Test(func){
    func();
}

const f1 = ()=>{
    console.log('a');
}

const f2 = ()=>{
    console.log('b');
}

Test(f1);//输出结果为a
Test(f2);//输出结果为b

4,高阶函数

高阶函数本质为能够接收其他函数作为参数传入的函数。也就是说,高阶函数本身也是一种函数,只不过它的参数可以为其他函数,一般我们用箭头函数作为高阶函数的参数。

例如我们上文中提到的Test()函数,可以称为一个高阶函数。

我们对高阶函数的要求为,会使用,不要求会编写。这是基于我们当前开发技术提出的要求。在ReactNative开发中,我们会遇到很多写好的高阶函数,供我们使用,来完成更复杂的功能。但我们并不需要自己编写一个高阶函数。

所以本节重点是研究如何使用高阶函数。

首先我们需要先明确一个概念:函数的类型。

函数类型由其输入参数和返回值决定,输入和返回值相同的函数,我们称之为同一类型函数。例如:

(x,y)=>{
    return x+y;
}

(a,b)=>{
    return a-b;
}

这两个为同类型函数,因输入参数和返回值类型相同。
我们来看第一个例子,首先我给出一个写好的高阶函数,同学们不用纠结高阶函数如何实现。

//func1的参数是一个f,f的类型为无输入参数,无返回值。
//func1为一个高阶函数
function func1(f){
    f();
}

有了func1这个高阶函数,所有无输入参数,无返回值的函数,都可以作为参数出入该高阶函数。例如:

f1 = ()=>{
    console.log('hello');
}

func1(f1);//输出hello

读到这里,大家可能会有一个疑问。使用了高阶函数,执行操作也仅仅是打印一个hello字符串。这样做的意义是什么。接下来我们便进行讨论,解释高阶函数的意义。
5,高阶函数的意义

在讨论这个问题之前,我们先明确两个概念,在上文中提到的,

func1:我们称之为高阶函数。

f1:是高阶函数的参数,也是一个函数。我们一般称之为这个函数为功能函数

高阶函数+功能函数的组合,才能实现完整的功能。其中高阶函数一般为框架提供,功能函数一般由使用框架的开发者自己编写。

为什么要是这样的组合呢?

是因为,我们做应用开发,尤其是App开发,如果代码从零开始写,那成本是非常高的。所以,我们在开发的时候,都是在各种框架下进行二次开发,这样可以非常有效的提升开发效率,避免大量重复基础的工作。我们可以认为,如果一个App的开发工作是100,那么一个优秀的框架可以帮助我们完成其中的70-80的工作量。我们只需要完成20-30的工作量便可开发一个App并发布。

所以,开发效率的核心是框架。

那框架是如何被开发出来的呢?

这个问题比较复杂,在此我们举一个简单的例子,方便大家理解,并不做深入探讨。
比如我们书中提供一个计算框架共大家使用。

计算这个功能不止包含法则,还包含数据的存储和验证。我们平时写的1+2,仅仅是通过运算符对计算法则的描述。

function compute(x,y,f){
   return f(x,y);
}

上面代码中的compute便是我给大家的一个计算框架,我们可以想计算框架中传入两个计算变量一个计算规则,计算规则通过函数来描述。
我们先用计算框架做一个简单的加法计算:

//准备计算数据
const p = 1;
const q = 2;

//先用函数描述一个加法计算规则
const f1 = (a,b)=>{
    return a+b;
}

//调用计算框架进行计算
const sum = compute(p,q,f1);
console.log(sum);//打印结果为3

计算框架使用我们传入的计算数据和计算法则,计算出我们的结果。这个计算框架就是高阶函数。

到这里,大家可能还是不能够理解,我简单的a+b也能完成这样的操作,为什么要用计算框架这个高阶函数。这是因为,我们的问题不足够复杂,没法提现计算框架的优势。下面我们在构造一个更复杂的计算。

我们规定,计算法则为:两个输入参数之和如果为奇数就相乘,如果之和为偶数结果为0。

这样稍微复杂的计算规则,普通的处理方式就没法进行了,这时候就体现出计算框架的功能了。

//构造计算规则
const f2 = (x,y)=>{
    const s = x+y;
    if(s%2 == 0){
        return 0;
    }
    return x*y;
}

const result1 = compute(2,2,f2);
console.log(result1);//结果为0;

const result2 = compute(1,2,f2);
console.log(result2);//结果为2

通过计算框架,我们不需要关系具体计算过程,我们只需要描述特定的业务即可。
这便是高阶函数的意义:提供了一种使用框架的方法,让我们开发更加高效。
6,高阶函数的应用

这一节我们举两个例子,说明高阶函数的使用场景

  • 提供操作基础
  • 提供事件回调

一般来说,高阶函数无法独自使用,必须配合我们写的功能函数才能起作用。
案例1,数组的遍历

//一般我们使用for循环进行数组的遍历
const array = [1,2,3,4];
for(let i = 0; i < array.length; i++){
    const value = array[i];
    console.log(value);
}

此种方式,我们需要手写一个for循环来进行,但是大家思考一下,所有的数组遍历模式都差不多,那么有没有框架将for循环这种重复的基础操作封装,只让我们写遍历规则呢。

答案是肯定的,JavaScript语言本身的Array对象中,包含了一个map()方法,该方法便是一个高阶函数,其参数需要传入一个函数,函数类型为:两个输入参数,一个返回值。

第一个输入参数为数组中某一个元素的值

第二个输入参数为该元素在数组中的索引

map方法会用返回值组成一个新的数组并返回

const array = [1,2,3,4];
array.map((value,index)=>{
    console.log(value);
})//依次打印数组中每一个值

const arr1 = [1,2,3,4];
const arr2 = arr1.map((value,index)=>{
    return value * 2;
});
console.log(arr2);//结果为[2,4,6,8];

通过使用框架提供的高阶函数map,我们无需关注如果遍历数组,只需要关注遍历规则即可。

案例2,Timer事件回调

Timer是JavaScript中定时器,可以进行周期性操作,例如每隔1秒钟打印一个字符串。实现这样周期性操作,同样使用的高阶函数

//setInterval(func,msecond)
//该函数有两个输入参数,第一个输入参数为一个函数,类型为无输入参数,无返回值。第二个输入参数为间隔时间,单位毫秒

//我们通过函数描述周期性需要完成的任务,例如是一个打印任务
const task = ()=>{
    console.log('hello');
};

//只需要将此任务传入高阶函数,并设置好间隔时间,该任务便会安装计划运行,
setInterval(task,1000);//每1秒钟打印一个hello

高阶函数的应用场景很多,我们经常用的就是以上两种类型。

对于高阶函数,是区分程序员能力的标杆,后续的案例,我们会接触越来越多的高阶函数。使大家对高阶函数的引用有更加深刻的认识。

JSON

JSON是JavaScript Object Notation的缩写,它是一种数据交换格式。

在JSON中,一共就一下几种数据类型:

  • number:和JavaScript的 number完全一致;
  • boolean:就是JavaScript的true或false;
  • string:就是JavaScript的string;
  • null:就是JavaScript的null;
  • array:就是JavaScript的Array表示方式——[];
  • object:就是JavaScript的{ … }表示方式。

上面的数据可以任意嵌套和组合。

由于JSON非常简单,很快就风靡Web世界,并且成为ECMA标准。几乎所有编程语言都有解析JSON的库,而在JavaScript中,我们可以直接使用JSON,因为JavaScript内置了JSON的解析。

把任何JavaScript对象变成JSON,就是把这个对象序列化成一个JSON格式的字符串,这样才能够通过网络传递给其他计算机。

如果我们收到一个JSON格式的字符串,只需要把它反序列化成一个JavaScript对象,就可以在JavaScript中直接使用这个对象了。
1,序列化

JSON序列化是指,将JavaScript中的对象转换为JSON格式的字符串。

例如我们在数据库中查询到了一个人的信息,需要把这个信息通过网络传递到前台的App进行显示,这时,我们需要将此对象进行JSON序列化,转换成JSON字符串才能进行传输。

const person = {
    name:'Tom',
    age:10,
    tel:'18612341234'
}

//JSON序列化使用JavaScript语言中自带的JSON解析器的stringify方法
const jsonData = JSON.stringify(person);
console.log(jsonData);//字符串:'{"name":"Tom","age":11,"tel":'1861234123'}'

2,反序列化

JSON反序列化也叫JSON解析。

拿到一个JSON格式的字符串,我们直接用JSON.parse()把它变成一个JavaScript对象。

一般来说,JSON格式的字符串都是通过网络请求获取

在此,我们为了测试JSON反序列化的功能,手写一个本地的JSON格式字符串。

const jsonData = '{"name":"Tom","age":11,"tel":18612341234}';
const person = JSON.parse(jsonData);
console.log(person.name);//结果为Tom

Class

ES6新增了class关键字,对面向对象编程有了更好的支持。
1,基本语法

class Point {
    constructor(x,y){
        this.x = x;
        this.y = y;
    }

    toString(){
        return `x is ${this.x}, y is ${this.y}`;
    }
}

const p = new Point(1,2);
const s = p1.toString();
console.log(s);//输出结果为x is 1, y is 2;

上面代码演示了ES6中的class的基本用法。

  • 使用class定义一个类
  • constructor为类的构造方法,当使用类实例化一个对象是,该方法会调用,并接受实例化时传入的参数
  • 类的属性不需要提前声明,可以直接使用,为定义的属性值为null
  • 声明类的方法时,不需要写function

2,this对象

this对象表示该类创建的对象,可以简单理解为自身。

this有两种使用场景:

  • 访问自身属性
  • 调用自身方法
class Point {
  constructor\(x,y\){  
      this.x = x;  
      this.y = y;  
  }

  toString(){
      //通过this访问自身属性
      return `x is ${this.x}, y is ${this.y}`;
  }
}

class Point {
  constructor\(x,y\){  
      this.x = x;  
      this.y = y;  
  }

  toString(){
      //通过this访问自身属性
      return `x is ${this.x}, y is ${this.y}`;
  }

  logSelf(){
      //通过this调用自身方法
      const s = this.toString();
      console.log(s)
  }
}

const p1 = new Point(1,2);
p1.logSelf();

3,手动绑定this对象

在特定情况下,类中的方法在调用时,会产生this为undefined的情况。这些情况较为复杂,后续章节会详细说明,在此不展开讲解。

例如,如下代码,变无法正常运行:

class Timer {
    constructor(x){
        this.x = x;
    }

    start(){
        setInterval(this.event,1000);
    }

    event(){
        console.log('a');
        console.log(this.x);
    }
}

const t = new Timer(1);
t.start();

上述代码的运行结果为,每秒钟,打印一个a字符,本应该一起打印的属性x的值,无法输出。

原因为,在此种情况下,event方法中的this对象为undefined,所以无法通过this对象访问属性x的值。

我们在学习初期,无法区分哪些情况this对象会丢失,所以我们采用一个统一的保守方案来修改此bug。

只要是自己写的方法且方法中用到了this对象,我们都统一在constructor方法中,手动对其绑定this对象,避免this对象丢失的情况发生。

class Timer {
    constructor(x){
        this.x = x;
        //手动绑定this
        this.event = this.event.bind(this);
    }
    start(){
        setInterval(this.event,1000);
    }
    event(){
        console.log('x');    
        console.log(this.x);
    }
}

const t = new Timer(1);
t.start();

通过手动绑定this对象之后,this对象丢失的情况便不会发生。

4,类的继承

在ES6中,提供的extends关键字用来实现类的继承关系。

class Base {
    say(){
        console.log('this is Base');
    }
}

class Sub extends Base {
    sayHello(){
        console.log('this is Sub');
    }
}

const s = new Sub();
s.say();//输出结果为this is Base
s.sayHello();//输出结果为 this is Sub

Sub类通过继承获得say方法,所有通过Sub实例化的对象也同样可以使用该方法。

如果子类的方法与父类方法同名,那么子类的方法会覆盖父类的方法。

class Base {
  say(){
    console.log('this is Base');
  }
}

class Sub extends Base {
  say(){
    console.log('this is Sub');
  }
}

const s = new Sub();
s.say();//输出结果为this is Sub

5,super对象

super对象和this对象类似。this对象表示对象本身,super对象表示本身对象的父类对象。
super对象的使用场景两个:

  • 调用与子类同名的父类方法
  • 调用父类的constructor
class Base {
  say(){
    console.log('this is Base');
  }
}

class Sub extends Base {
  say(){
    //调用父类的say方法
    super.say();
    console.log('this is Sub');
  }
}

const s = new Sub();
s.say();
//输出结果为
this is Base
this is Sub
class Point {
    constructor(x,y){
        this.x = x;
        this.y = y;
    }
}

class Point3D extends Point {
    constructor(x,y,z){
        //调用父类的constructor构造函数
        super(x,y);
        this.z = z;
    }

    logSelf(){
        console.log(`x:${this.x},y:${this.y},z:${this.z}`);
    }
}

const p = new Point3D(1,2,3);
p.logSelf();//输出结果x:1,y:2,z:3

Module模块系统

ES6提供了语言级别的模块系统解决方案,是模块化编程更加简单和清晰。

我们将一个JavaScript文件看做一个js模块,在模块内部的变量和表达式,只要在相同的作用域中,不需要额外的引入操作变可以直接使用。

但在不同模块之前的变量或者表达式无法直接使用,需要使用Module系统进行暴露和导入操作,才可以使用。

在编写代码时,我们通常在一个js模块中编写一个类,方面后期的维护和阅读。当在另一个js模块中需要使用这个类时,我们需要进行以下两步操作

  • 在编写类的js模块中,暴露该类的定义
  • 在使用类的js模块中,引入该类的定义

在完成以上两步操作之后,便可以在新的模块中使用已经写好的类的代码。
1,暴露模块接口

在ES6中,使用export关键字对模块内的定义进行暴露。
一般我们暴露三种接口:

  • 变量接口
  • 函数接口
  • Class接口

暴露接口方法有两种形式,分别为暴露定义和通过大括号暴露名称。直接暴露名称为错误方法!

注意:export命令,只能写在模块的顶层作用域(注意,不是顶部)。顶层作用域的意思是不能再任何一个大括号内写export

//变量接口

//正确1,暴露定义
export const a = 1;
export const b = 2;

//正确2
const x = 1;
const y = 1
//通过大括号暴露名称
export { 
    x,
    y,
};

//错误!!!
cosnt x = 1;
export x;
//函数接口

//正确1
export function f1(){
    console.log(1);
}
export function f2(){
    console.log(2);
}

//正确2
function f1(){
    console.log(1);
}
function f2(){
    console.log(2);
}

export {
   f1,
   f2,
}
//class接口

//正确1
export class AClass {
}
export class BClass {
}

//正确2
class AClass {
}
class BClass {
}

export {
    AClass,
    BClass,
}

2,引入模块接口

引入模块使用import关键字进行。使用方法如下

import { 接口名 } from '相对路径'

例如,我们首先在a.js文件中暴露一个变量,

//a.js

export const name = 'Tom';

如果我们想在b.js文件中使用这个变量,我们需要引入该变量接口。

我们假定a.js和b.js在同级目录下。

import { name } from './a.js';

console.log(name);//输出结果为Tom

在import命令中,如引入文件为.js,那么其拓展名可以省略,其他类型文件不可以省略

import { name } from './a';与上午中代码等效,日常开发经常省略.js

在引入中一定注意,暴露的变量名和引入的变量名,一定要一致,如果不一致,将引入失败。
3,默认暴露

在上述讲解中,暴露和引入都必须使用相同的接口名,如果不相同便会出错。这样的要求在实际使用中不是很方便,在使用其他人的模块是,还需要阅读其源码才能完成正确引入。

在ES6通过这样的暴露引入机制同时,为了方面开发者更加方便的使用模块,增加了一个默认暴露引入机制。

该机制通过export default关键字进行暴露,且同一模块中,只能使用一次export default ,同时可以使用传统的export进行暴露

//a.js
export default const name = 'Tom';

当引入默认暴露的接口是,接口名称可以自定义,无需和暴露名一致。同时也不需要大括号

import XXX from './a';

console.log(XXX);//输出结果为Tom

默认暴露和普通暴露机制可以同时使用:

//a.js

export default const name = 'Tom';

export const age = 10;
import Name , { age } from './a';

console.log(Name);
console.log(age);

4, as重命名

在除了默认暴露以外的情况,暴露和引入的接口名必须一致。但有时模块内部有自己的命名规则,对外暴露是命名规则可能过于繁琐,我们便可以使用 as 关键字做暴露或者引入重命名,方面后面编码使用该接口。

暴露重命名

//a.js

const xxx_name = 'Tom';

export {
    xxx_name as name,
}
import { name } from './a';

console.log(name)

引入重命名

//a.js

export const name = 'Tom';
import { name as xxx_name } from './a'

console.log(xxx_name);
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值