ES6语法(常用)

ES6语法

块级作用域

  1. 变量声明
    增加了 letconst

    • 区别
      • 不存在变量提升
        • var会出现变量提升,在变量声明之前使用,值为 undefined
        • letconst则没有变量提升功能,必须先定义才能使用。
      • 不允许重复声明
      • 作用域
        • var的作用域是以函数为界限
        • letconst的作用域是块作用域,块作用域值{}内的范围
        • var可以定义全局变量和局部变量,letconst只能定义局部变量
        • const的声明常量不能被修改,但对于引用类型来说,堆内存的值可以被改变
  2. 暂时性死区

    定义:块级作用域存在let命令时,所声明的变量就“绑定”这个区域,不再受外部的影响。

    {
        // let a 之前的区域成为暂时性死区,调用a会报错
        let a = "hello";
    }
    
  3. for循环中的作用域问题

    • 设置循环变量的部分是父级作用域,而循环体内部是一个单独的子作用域。

    • ES6 中引用变量采用就近原则。在 JavaScript 中,for 循环中的作用域问题是一个常见的疑惑点。对于传统的 for 循环,循环变量的声明部分是在父级作用域中,而循环体内部是一个单独的子作用域。

      这意味着,在 for 循环中声明的循环变量会被绑定到父级作用域中,而不是循环体的作用域中。这使得在循环体内访问循环变量时可能会出现一些问题。

      例如:

      javascriptCopy Codefor (var i = 0; i < 3; i++) {
        setTimeout(function() {
          console.log(i);
        }, 1000);
      }
      

      在上面的代码中,我们使用 for 循环创建了三个 setTimeout 函数,并在每个函数内部打印变量 i 的值。然而,由于 setTimeout 是异步的,当这些函数执行时,循环已经结束,i 的值被修改为 3。因此,不管我们期望的是打印 0、1、2,实际上会打印三次 3。

      解决这个问题的常见方法是使用闭包来捕获当前循环变量的值。例如:

      javascriptCopy Codefor (var i = 0; i < 3; i++) {
        (function(index) {
          setTimeout(function() {
            console.log(index);
          }, 1000);
        })(i);
      }
      

      在这个例子中,我们使用一个立即执行的函数表达式创建了一个闭包,并将当前循环变量的值作为参数传递给该函数。这样,在每个 setTimeout 函数内部,都会捕获到对应的循环变量值。

      另一种解决方法是使用 let 关键字来声明循环变量。let 具有块级作用域,每次循环都会创建一个新的变量实例。因此,我们可以像下面这样修改代码:

      javascriptCopy Codefor (let i = 0; i < 3; i++) {
        setTimeout(function() {
          console.log(i);
        }, 1000);
      }
      

      在这个例子中,每次循环都会创建一个新的 i 变量,而不是共享同一个变量。因此,每个 setTimeout 函数都能正确地访问到对应的 i 值。

      总结起来,for 循环中的作用域问题可以通过使用闭包或 let 关键字来解决。这样可以确保在循环体内部能够正确地访问到循环变量的值。

解构赋值

  1. 数组结构赋值
// 基本语法
let [a, b] = [1, 2];
console.log(a); // log --> 1
console.log(b); // log --> 2

// 可以忽略某些元素
let [c, , d] = [3, 4, 5];
console.log(c); // log --> 3
console.log(d); // log --> 5
  1. 对象解构赋值
// 基本语法
let { foo, bar } = { foo: "hello", bar: "world" };
console.log(foo); // log --> "hello"
console.log(bar); // log --> "world"

// 可以重命名变量名
let { x: newX, y: newY } = { x:100, y:200 };
console.log(newX); // log --> 100
console.log(newY); // log --> 200

// 默认值
let { a = 10, b = 20 } = { a: 30 };
console.log(a); // log --> 30
console.log(b); // log --> 20
  1. 函数参数结构赋值
// 在函数参数中使用结构赋值
function f([x, y]) {
    console.log(x);
    console.log(y);
}
f([1, 2]); // 输出 1,2

function g({name, age}) {
    console.log(name);
    console.log(age);
}
g({name: 'Jack', age: 25}); // 输出 Jack和25

箭头函数

箭头函数是一种更简洁的函数定义方式,有着更符合直觉的this绑定机制,它本身没有自己的this值,会从定义时的外层作用域继承this值。箭头函数不适用于需要动态this的场景,如对象的方法、构造函数等。

// eg:
const arrowFunctionExample = (x, y) => {
    return x + y;
};
console.log(arrowFunctionExample(2,3)); // log --> 5
箭头函数补充
// 对象的方法中使用箭头函数
const person = {
    name: 'Alice',
    sayHello: () => {
        console.log(`Hello, my name is ${this.name}.`);
    }
}

person.sayHello();  // 输出: Hello, my name is undefind.

// 构造函数中使用箭头函数
function Person(name) {
    this.name = name;
    this.sayHello = () => {
        console.log(`Hello, my name is ${this.name}.`)
    }
}

const person1 = new Preson('Alice');
person1.sayHello(); // 输出:Hello, my name is Alice.


/!!!!!/ 
// 箭头函数无法正确地获取到对象的属性 name 或 构造函数的 this 值。相反,常规的函数声明或函数表达式,则可以正确地获取到预期的值:
// 在对象中使用函数声明
const person = {
    name: 'Alice',
    sayHello: function() {
        console.log(`Hello, my name is ${this.name}.`);
    }
}
person.sayHello(); // 输出: Hello, my name is Alice.

// 构造函数中使用函数声明
function Person(name) {
    this.name = name;
    this.sayHello = function() {
        console.log(`Hello, my name is ${this.name}.`);
    }
}
const person1 = new Person('Alice');
person1.sayHello(); // 输出: Hello, my name is Alice.

默认参数

在函数定义时为参数指定默认值,这样在调用函数是如果为传入对应参数,则会使用默认值。

默认参数可以是任何表达式,包括函数调用、引用之前的参数等,默认值仅在函数执行时计算一次。

// eg:
function greet(name = "World") {
    console.log(`Hello,${name}!`);
}

greet(); // log --> Hello, World!
greet("Alice"); // log --> Hello, Alice!

模板字符串

使用反引号创建字符串模板,通过${}插入变量和表达式,这样可以更方便地拼接字符串和表达复杂逻辑。可以在模板字符串中使用普通字符串和特殊字符串(如转义字符)。

// eg: 
let name = "World";
let greeting = `Hello,${name}!`;
console.log(greeting); // 输出 "Hello,World!"

类和继承

ES6引入了class关键字,可以更方便地定义类,并实现类之间的继承关系。

  • 使用class关键字定义类,通过constructor方法设置实例属性。
  • 类可以有实力方法和静态方法,通过prototypestatic关键字定义。
  • 使用extends关键字实现继承,子类可以重写父类的方法。
  • 在子类的构造函数中必须先调用super(),才能使用this关键字。
// eg: 
class Animal {
    constructor(name) {
        this.name = name;
    }
    
    speak() {
        console.log(`${this.name} makes a sound.`)
    }
}

class Dog extends Animal {
    constructor(name) {
        super(name);
    }
    
    speak() {
        console.log(`${this.name} barks.`)
    }
}

const dog = new Dog("Buddy");
dog.speak();  // log --> Buddy barks;

模块化

使用importexport关键字导入和导出模块,使得代码可以分割多个独立的文件管理。

// eg: module1.js 、 module2.js

// module1.js
export const greeting = "Hello";

export function sayHello(name) {
    console.log(`${greeting}, ${name}!`)
}

// module2.js
import { greeting, sayHello } from "./module1.js";

sayHello("Alice"); // log --> Hello, Alice!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尤山海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值