ホームページ  >  記事  >  ウェブフロントエンド  >  vue で使用される es6 の機能は何ですか?

vue で使用される es6 の機能は何ですか?

青灯夜游
青灯夜游オリジナル
2023-01-11 18:58:591471ブラウズ

特徴: 1. Let および const キーワードは変数の宣言に使用されます; 2. "for...of" ループ、反復可能なデータ; 3. Iterable、反復可能なプロトコルを実装するオブジェクト; 4.ジェネレータ ; 5. デフォルトパラメータ; 6. オブジェクト/配列から属性/値を削除できる代入構文の構造化; 7. 残り/拡張されたパラメータ; 8. アロー関数; 9. オブジェクトリテラル; 10. クラス; 11. マップ/ Set/WeakMap/WeakSet データ構造; 12. お約束。

vue で使用される es6 の機能は何ですか?

#このチュートリアルの動作環境: Windows7 システム、vue3 バージョン、DELL G3 コンピューター。


ECMAScript 6.0 (以下、ES6) は、2015 年 6 月に正式にリリースされた Javascript 言語の次世代標準です。その目標は、JavaScript 言語を使用して複雑な大規模アプリケーションを作成できるようにし、エンタープライズ レベルの開発言語になることです。

ECMAScript 6 (いわゆる最新の Javascript) には、

ブロック スコープ、クラス、アロー関数、ジェネレーター、その他多くの便利な機能などの強力な機能が付属しています。

プログラミング エクスペリエンスを向上させ、開発効率とコード品質を向上させるために、Vue アプリケーション開発で使用されるすべての必要な関数。

Vue CLIBabel または core-js 統合を通じて、開発中のコードを構成仕様に厳密に従って反復できるため、チームにとって役立ちますコラボレーション。この記事では、Vue アプリケーション開発で一般的に使用されるいくつかの ES6 機能を紹介します。

let/const

ES6 の最も基本的な関数:

letconst

letvar に似ていますが、let を使用して宣言された変数のスコープは、変数が宣言されているブロック内になります。 (ブロックとは、条件ブロック、for ループ ブロックなどを指します。)

たとえば、条件ブロックで

let を使用すると、ブロック内の変数のスコープが設定され、ブロック外では利用できません。

if (true) {
    let foo = "word";
}

console.log(foo); // error

ここで、エラーは生産プロセス中に発生する可能性のあるエラーを防ぐため、良いものです。

上記の例で (従来の Javascript コードで行うように)

let の代わりに var を使用すると、エラーは発生しません。

const は、変数を宣言するために使用されるもう 1 つの ES6 キーワードです。違いは、const で作成された変数は宣言後に変更できないことです。この機能により、BUG の発生を効果的に回避できます。そのため、コードを記述するときは、純粋な関数を次のように記述することをお勧めします。可能な限り (純粋な関数とは、関数への固定入力が与えられると、出力結果が固定され、関数外の変数などの影響を受けないことを意味します)。

例:

const a = 2021
a = 2020 // error

変数を作成するにはいくつかの方法がありますが、どれを使用すればよいですか?

最良の方法は、可能な限り

const## を使用することです。 #。 let は、for ループなど、後で変更する必要がある変数が必要な場合にのみ使用してください。

for…of

ループと言えば、

let を使用せずに ES6 構文で

for ループを記述する簡単な方法があります。 たとえば、従来の

for

ループは次のようになります: <pre class="brush:js;toolbar:false;">const arr = [1, 2, 3]; for (let i = 0; i &lt; arr.length; i++) { const item = arr[i]; console.log(item); }</pre> ES6 では、非常に単純です:

const arr = [1, 2, 3];

for (const item of arr) {
    console.log(item);
}

## は使用しないでください。 #for ..in

構文の混乱; これらはまったく別のものです。

for..in は配列/オブジェクト内のプロパティを取得し、for..of は反復処理する実際のデータを取得します。 Iterable

反復可能オブジェクトとは、反復可能プロトコルを実装する任意のオブジェクトです。 (プロトコルとは、オブジェクト内の特定の名前を持つ特定のメソッドを使用することによって満たされる必要がある要件を単に指します)。

たとえば、

iterable

プロトコルを実装するオブジェクトは次のとおりです:

const twice = {
    [Symbol.iterator]() {
        let i = 0;
        const iterator = {
            next() {
                if (i < 2) {
                    return { value: i++, done: false };
                } else {
                    return { value: undefined, done: true };
                }
            },
        };
        return iterator;
    },
};
これで、この ## を for..of## で使用できるようになります。 # ループ #twice

Object:

for(const x of twice){
  console.log(x)
}
これは、twice オブジェクトを 2 回ループし、それぞれ 0

1 を取得します。 反復可能オブジェクトを作成するために、iterable プロトコルと iterator

プロトコルという 2 つのプロトコルが実際に実装されます。

反復可能オブジェクトであるという要件を満たすには、[Symbol.iterator] という名前のメソッドが必要です。

const twice = {
  [Symbol.iterator]() {
    ...
  }
}

2 つの新しい ES6 トリックがメソッド名に適用されています。

まず、Symbol.iterator

は組み込みシンボル値であり、

Symbol

は ES6 で一意のタグ/識別子を作成するために使用される基本型です。

2 番目に、プロパティ キーを角かっこで囲むことで、動的に計算されるキーになります。ここで重要なのは式の表記です。イテレータは次のように評価されますが、通常は実際の評価が何であるかは関係ありません。この重要でない詳細は抽象化されています。 これは反復可能なプロトコルです。イテレータは [Symbol.iterator]

関数から返される必要があるため、イテレータ プロトコルを処理して反復可能オブジェクトを作成する必要があります。

イテレータ プロトコルの方が簡単です。必要なのは、

valuedone

という 2 つのキーを持つオブジェクトを返す

next メソッドを持つオブジェクトだけです。反復を停止したい場合は、オブジェクト {値: 未定義、完了: true} を返すだけです。 これは例の反復子です:

const iterator = {
    next() {
        if (i < 2) {
            return { value: i++, done: false };
        } else {
            return { value: undefined, done: true };
        }
    },
};
つまり、反復可能プロトコルと反復子プロトコルの両方を満たすオブジェクトが存在します。次のコードのような:
const twice = {
    [Symbol.iterator]() {
        let i = 0;
        const iterator = {
            next() {
                if (i < 2) {
                    return { value: i++, done: false };
                } else {
                    return { value: undefined, done: true };
                }
            },
        };
        return iterator;
    },
};

数组和字符串可以使用for..of,进行迭代。这意味着这些内置类型包含与上面的类似的[Symbol.iterator]方法。

Generator:生成器

与迭代相关的另一个功能是生成器。

上面的可迭代代码依靠闭包来存储 i 变量。使用 generator 时,不必担心自己构造闭包:

function* twiceGen() {
    let i = 0;
    while (i < 2) {
        yield i;
        i++;
    }
}

const twice = twiceGen();

该代码实现了与可迭代示例相同的行为,但更为简单。

可以与for..of完全相同地使用它:

for(const item of twice){
  console.log(item)
}

如你所见,它是一个带有星号(*)声明的函数。它使用yield关键字逐个抽取值,就像迭代器的next方法一样。

生成器是一种多功能工具,基本上,它是一种允许暂停/恢复功能的机制。不必在for..of中使用上述twice对象。可以调用它的next方法。

function* twiceGen() {
    const i = 0;
    while (i < 2) {
        yield i;
    }
}

const twice = twiceGen();

twice.next().value; // 0

此时,twiceGen函数在第一次运行while循环后暂停。如果再次运行相同的操作,它将恢复并播放循环的第二次运行。

twice.next().value; // 1

生成器的妙处在于它还创建了一个可迭代的迭代器对象。这就是为什么我们能够使用for..of(可迭代特权)迭代两次并直接调用其next方法(迭代器特权)的原因。

Default Parameter:默认参数

可能不会立即创建自己的迭代器、生成器,所以让我们来看看其他一些ES6的独创性,它们可以立即使你的代码更加友好。

就像许多其他编程语言一样,现在可以为函数参数设置默认值。

过去是这样实现默认值的:

function addOne(num) {
    if (num === undefined) {
        num = 0;
    }
    return num + 1;
}

addOne();

现在可以这样:

function addOne(num = 0) {
    return num + 1;
}

addOne();

Destructuring Syntax:解构语法

解构赋值语法是一种 Javascript 表达式。通过解构赋值, 可以将属性/值从对象/数组中取出,赋值给其他变量。

如果要将对象传递给函数,则可以轻松选择对象的属性,然后使用ES6分解语法将它们放在单独的变量中:

function foo({ a, b }) {
    console.log(a, b); // 1, 2
}

foo({ a: 1, b: 2 });

这种解构语法的好处是可以避免创建带有附加代码行的变量。因此不需要像下面这样:

function foo(obj) {
    const a = obj.a;
    const b = obj.b;
    console.log(a, b); // 1, 2
}

同样,还可以在解构语法中设置默认值:

function foo({ a = 0, b }) {
    console.log(a, b); // 0, 2
}

foo({ b: 2 });

解构语法也适用于赋值:

function foo(obj) {
    const { a, b } = obj;
    console.log(a, b); // 1, 2
}

当从参数以外的地方获取对象时,这也很有用。

function getObj() {
    return { a: 1, b: 2 };
}

function foo() {
    const { a, b } = getObj();
    console.log(a, b); // 1, 2
}

解构技巧同样也适用数组。

解构参数:

function foo([a, b]) {
    console.log(a, b); // 1, 2
}

foo([1, 2, 3]);

解构赋值:

function foo(arr) {
    const [a, b] = arr;
    console.log(a, b); // 1, 2
}

Rest / Spread :剩余 / 展开参数

在解构数组时,可以使用 ... 语法来获取数组中的所有其他项。

function foo([a, b, ...c]) {
    console.log(c); // [3, 4, 5]
}

foo([1, 2, 3, 4, 5]);

c现在是一个包含自己的数组,包含了其余的元素:345。这里的操作就是Rest操作。

这个语法同样适用于赋值:

function foo(arr) {
    const [a, b, ...c] = arr;
    console.log(c); // [3, 4, 5]
}

foo([1, 2, 3, 4, 5]);

rest操作符也可以单独使用,无需解构:

function foo(...nums) {
    console.log(nums); // [1, 2, 3, 4, 5]
}

foo(1, 2, 3, 4, 5);

在这里,我们将数字作为独立参数传递,而不是作为单个数组传递。但是在函数内部,使用rest运算符将数字作为单个数组收集。当遍历这些参数时,这很有用。

rest语法 ... 与另一个ES6特性操作符扩展完全相同。

例如,如果要将两个数组合并为一个:

const a = [1, 2];
const b = [3, 4];
const c = [...a, ...b];
console.log(c); // [1, 2, 3, 4]

spread操作符用于将所有项展开,并将它们放入不同的数组中。

spread也适用于对象:

const obj = { a: 1, b: 2 };
const obj2 = { ...obj, c: 3 };
console.log(obj2); // { a: 1, b: 2, c: 3 }

现在,第二个对象除了其自身的属性外,还应包含第一个对象的所有内容。

Arrow Function:箭头函数

ES6提供了创建函数,对象和类的更简单方法。

箭头函数表达式的语法比函数表达式更简洁,并且没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数

使用箭头语法来创建更简洁的函数:

const addOne = (num) => {
    return num + 1;
};

箭头语法对于创建单行函数更加简洁友好。

const addOne = (num) => num + 1;

此函数将自动返回表达式num +1的求值作为返回值,不需要显式的使用return关键字。

如果函数仅接受一个参数,甚至可以省略括号(但是在严格语法上还是建议加上括号):

const addOne = num => num + 1;

但是如果没有任何参数,仍然需要一对空括号:

const getNum = () => 1;

但是,此语法有一个警告,如果我们返回的是对象字面量,则无法使用,会报错:

const getObj = () => { a: 1, b: 2 } // error

这将产生语法错误,因为解析器将假定花括号用于函数块,而不是对象字面量。

为了避免这个错误,必须将对象字面量包装在一对括号中:

const getObj = () => ({ a: 1, b: 2 });

另一件需要记住的事情是,this关键字不能在箭头函数中使用。它不会出现错误;相反,它只会从周围的范围提供相同的this引用。

function thatOrThis() {
    const that = this;
    const compare = () => {
        console.log(that === this); // true
    };
    compare();
}

thatOrThis();

以上代码给出的值则为:true

Object literal extensions:对象字面量的扩展

ES6也提供了一种更简单的方法来创建对象字面量。

如果在一个对象中放入两个项目,它们的属性键与变量相同,可以用传统的Javascript做这样的事情:

const a = 1;
const b = 2;
const obj = {
    a: a,
    b: b,
};

但是在ES6中,语法可以更简单:

const a = 1;const b = 2;const obj = { a, b };

如果把方法放到对象字面量中,可以这样做:

const a = 1;
const b = 2;
const obj = {
    a,
    b,
    getA() {
        return this.a;
    },
    getB() {
        return this.b;
    },
};

基本上,没有function关键字和冒号。

Class:类

ES6提供了类似于其他面向对象语言的类构造。现在不必依赖于混淆构造函数和原型方式。

class Person {
    constructor(name, hobby) {
        this.name = name;
        this.hobby = hobby;
    }

    introduce() {
        console.log(`大家好,我的名字叫:${this.name},我喜欢${this.hobby}。`);
    }
}

const devpoint = new Person("DevPoint", "coding");
devpoint.introduce();

附带说明,introduce方法中的字符串称为模板字符串,它是使用反引号而不是引号创建的。这样可以使用美元符号和大括号将表达式插入字符串。

与常规字符串拼接相比,模板字符串的好处是它可以跨越多行:

const str = `line 1
line 2
line 3
`;
console.log(str);

它被称为模板字符串,因为它对实现模板很有用。

function pStr(text) {
    return `<p>${text}</p>`;
}

pStr("Hello world"); // <p>Hello world</p>

一个类可以从另一个类继承(重用现有类的代码):

class Person {
    constructor(name, hobby) {
        this.name = name;
        this.hobby = hobby;
    }

    introduce() {
        console.log(`大家好,我的名字叫:${this.name},我喜欢${this.hobby}。`);
    }
}

class ProfessionalPerson extends Person {
    constructor(name, hobby, profession) {
        super(name, hobby); // 执行 Person 的构造函数
        this.profession = profession;
    }

    introduce() {
        super.introduce(); // 调用 Person 类的方法
        console.log(`我的职业是 ${this.profession}。`);
    }
}

const devpoint = new ProfessionalPerson("DevPoint", "coding", "程序员");
devpoint.introduce();

这里使用extends关键字在两个类之间创建继承关系,其中Person为父类。代码中用了两次super关键字,第一次是在构造函数中调用父类的构造函数,第二次,像使用对象一样使用它来调用父类的introduce方法。super关键字的行为会因使用的位置而异。

在构造函数中使用时,super关键字将单独出现,并且必须在使用this关键字之前使用。如下代码就是有异常的。

class ProfessionalPerson extends Person {
    constructor(name, hobby, profession) {
        this.profession = profession;    // 这里会出现异常
        super(name, hobby); // 执行 Person 的构造函数
    }

    introduce() {
        super.introduce(); // 调用 Person 类的方法
        console.log(`我的职业是 ${this.profession}。`);
    }
}

Map / Set / WeakMap / WeakSet

ES6新增了两种数据结构:MapSet

Map键-值对的集合,并且能够记住键的原始插入顺序。

const mapPerson = new Map();
mapPerson.set("name", "DevPoint");
mapPerson.set("profession", "Coding");
const myName = mapPerson.get("name");
console.log(myName); // DevPoint

Map对象可以使用任何对象类型作为键。看起来是不有点像Object,下面我们可以看看他们的比较:


Map Object
意外的键 Map 默认情况不包含任何键,只包含显式插入的键。 一个 Object 有一个原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
键的类型 Map 的键可以是任意值,包括函数、对象或任意基本类型。 一个 Object 的键必须是一个 String 或是 Symbol
键的顺序 Map 中的 key 是有序的。因此,当迭代的时候,一个 Map 对象以插入的顺序返回键值。 一个 Object 的键是无序的
Size Map 的键值对个数可以轻易地通过 size 属性获取 Object 的键值对个数只能手动计算,需要自己构建方法
迭代 Map 是 iterable 的,所以可以直接被迭代。 迭代一个 Object 需要以某种方式获取它的键然后才能迭代。
性能 在频繁增删键值对的场景下表现更好 在频繁添加和删除键值对的场景下未作出优化

Set对象就像一个数组,但是仅包含唯一项。Set对象是值的集合,可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。

const numbers = new Set();
numbers.add(1);
numbers.add(1);
console.log(numbers); // Set { 1 }

尽管两次add是同样的值,程序本身不会出现任何异常,但该集合仍然只包含一项。

让谈谈来学习一点更复杂的知识,WeakMapWeakSet。它们分别是MapSet的弱引用版本。

WeakMap其键必须是Object,而值可以是任意的。

WeakSet 对象是一些对象值的集合, 并且其中的每个对象值都只能出现一次,在WeakSet的集合中是唯一的。

它和 Set 对象的区别有两点:

  • Set相比,WeakSet 只能是对象的集合,而不能是任何类型的任意值。
  • WeakSet持弱引用:集合中对象的引用为弱引用。 如果没有其他的对WeakSet中对象的引用,那么这些对象会被当成垃圾回收掉。 这也意味着WeakSet中没有存储当前对象的列表。 正因为这样,WeakSet 是不可枚举的。

一旦不再引用WeakMap的键,便会对其进行垃圾回收(由Javascript运行时从内存中删除)。

let key1 = {};
const key2 = {};
const wm = new WeakMap();
wm.set(key1, 1);
wm.set(key2, 2);
key1 = null; // 取消引用

key1被取消引用之后,它的对应值将被垃圾回收,意味着它将在未来的某个时间点消失。

同样,如果将一个对象添加到WeakSet中,然后再取消引用它,它也将被垃圾回收。

let item1 = {};
const item2 = {};
const ws = new WeakSet();
ws.add(item1);
ws.add(item2);
item1 = null; // 取消引用

Promise

Promise 对象用于表示一个异步操作的最终完成 (或失败)及其结果值。是ES6的一个常用功能,它是对传统函数回调模式的改进。

一个 Promise 必然处于以下几种状态之一:

  • 待定(pending): 初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled): 意味着操作成功完成。
  • 已拒绝(rejected): 意味着操作失败。

例如,这是使用传统回调的方式:

setTimeout(function () {
    const currentTime = new Date();
    console.log(currentTime);
}, 1000);

这是一个计时器,显示一秒钟后的时间。

这是一个使用相同setTimeout逻辑的Promise对象:

const afterOneSecond = new Promise(function (resolve, reject) {
    setTimeout(function () {
        const currentTime = new Date();
        resolve(currentTime);
    }, 1000);
});

它接受带有两个参数的函数:resolvereject。这两个都是当有返回值时可以调用的函数。调用resolve函数返回一个值,可以调用reject函数返回一个错误。

然后,可以使用then语法将回调函数附加到这个afteronessecond对象上:

afterOneSecond.then((t) => console.log(t));

promise相对于传统回调的好处是promise对象可以被传递。因此,在设置promise之后,可以自由地将它发送到其他地方,以处理计时器解析后要做的事情。

另一个很酷的事情是,promise可以与多个then子句链接在一起,即promise的链式调用。

afterOneSecond.then((t) => t.getTime())
              .then((time) => console.log(time));

每个then子句将其值作为参数返回到下一个then子句。

实用方法

下面就来介绍在VUE中,比较实用的ES6的方法或属性。

Object.assign()

Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。提供了一种简单的方法来浅克隆现有对象

const obj1 = { a: 1 }
const obj2 = Object.assign({}, obj1)

String.prototype.repeat()

构造并返回一个新字符串,该字符串包含被连接在一起的指定数量的字符串的副本。

const str = "DevPoint ".repeat(3);console.log(str); // DevPoint DevPoint DevPoint

String.prototype.startsWith()

用来判断当前字符串是否以另外一个给定的子字符串开头(区分大小写),并根据判断结果返回 truefalse

const str = "DevPoint".startsWith("D");
const str2 = "DevPoint".startsWith("d");
console.log(str); // true
console.log(str2); // false

String.prototype.endsWith()

用来判断当前字符串是否是以另外一个给定的子字符串“结尾”的,根据判断结果返回 truefalse

const str = "DevPoint".endsWith("t"); 
console.log(str); // true

String.prototype.includes()

用于判断一个字符串是否包含在另一个字符串中,根据情况返回 truefalse

const str = "DevPoint".includes("P");
console.log(str); // true

Array.prototype.find()

返回数组中满足提供的过滤函数的第一个元素的值,否则返回 undefined

const arrNumbers = [5, 12, 8, 130, 44];
const foundNumbers = arrNumbers.find((number) => number > 10);
console.log(foundNumbers);   // 12是数组第一个大于10的数

Function.name

这不是方法而是属性,返回函数实例的名称,每个函数都有一个name属性,该属性提供字符串形式的函数名称

// setTimeout.name; // "setTimeout"

const weather = () => {
    console.log("今天天气真好!");
};
const devpoint = () => {};

// 限制回到函数的名称
const enter = (callback) => {
    const accessName = ["weather"];
    if (accessName.includes(callback.name)) {
        callback();
    }
};
enter(devpoint);
enter(weather);

上述代码只执行了函数 weather

总结

ES6的新特征,某种程度上代表的Javascript在未来的态度,这些新的特征让我迫不及待应用到项目中,不断接受新挑战,提升自己技能。

(学习视频分享:vuejs入门教程编程基础视频

以上がvue で使用される es6 の機能は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。