ES6의 새로운 기능: const 및 let 변수, 템플릿 리터럴, 구조 분해, 향상된 객체 리터럴, for...of 루프, 확장 연산자(...), 나머지 매개변수(변수 매개변수), ES6 화살표 함수, 클래스 지원, 문자열 템플릿, 반복자, 생성기, 모듈, 기호 등
이 튜토리얼의 운영 환경: Windows 7 시스템, ECMAScript 버전 6, Dell G3 컴퓨터.
const 및 let 변수
var
사용으로 인해 발생한 문제: var
带来的麻烦:
function getClothing(isCold) { if (isCold) { var freezing = 'Grab a jacket!'; } else { var hot = 'It's a shorts kind of day.'; console.log(freezing); } }
运行getClothing(false)
后输出的是undefined
,这是因为执行function
函数之前,所有变量都会被提升
, 提升到函数作用域顶部.
let
与const
声明的变量解决了这种问题,因为他们是块级作用域, 在代码块(用{}
表示)中使用let
或const
声明变量, 该变量会陷入暂时性死区直到该变量的声明被处理.
function getClothing(isCold) { if (isCold) { const freezing = 'Grab a jacket!'; } else { const hot = 'It's a shorts kind of day.'; console.log(freezing); } }
运行getClothing(false)
后输出的是ReferenceError: freezing is not defined
,因为 freezing
没有在 else
语句、函数作用域或全局作用域内声明,所以抛出 ReferenceError
。
关于使用let
与const
规则:
- 使用
let
声明的变量可以重新赋值,但是不能在同一作用域内重新声明 - 使用
const
声明的变量必须赋值初始化,但是不能在同一作用域类重新声明也无法重新赋值.
【相关推荐:JavaScript视频教程】
模板字面量
在ES6之前,将字符串连接到一起的方法是+
或者concat()
方法,如
const student = { name: 'Richard Kalehoff', guardian: 'Mr. Kalehoff' }; const teacher = { name: 'Mrs. Wilson', room: 'N231' } let message = student.name + ' please see ' + teacher.name + ' in ' + teacher.room + ' to pick up your report card.';
模板字面量本质上是包含嵌入式表达式的字符串字面量.
模板字面量用倒引号 ( `` )
(而不是单引号 ( '' )
或双引号( "" )
)表示,可以包含用 ${expression}
表示的占位符
let message = `${student.name} please see ${teacher.name} in ${teacher.room} to pick up your report card.`;
解构
在ES6中,可以使用解构从数组和对象提取值并赋值给独特的变量
解构数组的值:
const point = [10, 25, -34]; const [x, y, z] = point; console.log(x, y, z);
Prints: 10 25 -34
[]
表示被解构的数组, x
,y
,z
表示要将数组中的值存储在其中的变量, 在解构数组是, 还可以忽略值, 例如const[x,,z]=point
,忽略y
坐标.
解构对象中的值:
const gemstone = { type: 'quartz', color: 'rose', karat: 21.29 }; const {type, color, karat} = gemstone; console.log(type, color, karat);
花括号 { }
表示被解构的对象,type
、color
和 karat
表示要将对象中的属性存储到其中的变量
对象字面量简写法
let type = 'quartz'; let color = 'rose'; let carat = 21.29; const gemstone = { type: type, color: color, carat: carat }; console.log(gemstone);
使用和所分配的变量名称相同的名称初始化对象时如果属性名称和所分配的变量名称一样,那么就可以从对象属性中删掉这些重复的变量名称。
let type = 'quartz'; let color = 'rose'; let carat = 21.29; const gemstone = {type,color,carat}; console.log(gemstone);
简写方法的名称:
const gemstone = { type, color, carat, calculateWorth: function() { // 将根据类型(type),颜色(color)和克拉(carat)计算宝石(gemstone)的价值 } };
匿名函数被分配给属性 calculateWorth,但是真的需要 function 关键字吗?在 ES6 中不需要!
let gemstone = { type, color, carat, calculateWorth() { ... } };
for...of循环
for...of
循环是最新添加到 JavaScript 循环系列中的循环。
它结合了其兄弟循环形式 for
循环和 for...in
循环的优势,可以循环任何可迭代(也就是遵守可迭代协议)类型的数据。默认情况下,包含以下数据类型:String
、Array
、Map
和 Set
,注意不包含 Object
数据类型(即 {}
)。默认情况下,对象不可迭代。
for循环
const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for (let i = 0; i <p><code>for</code> 循环的最大缺点是需要跟踪计数器和退出条件。<br> 虽然 <code>for</code> 循环在循环数组时的确具有优势,但是某些数据结构不是数组,因此并非始终适合使用 loop 循环。</p><p>for...in循环</p><pre class="brush:php;toolbar:false">const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for (const index in digits) { console.log(digits[index]); }
依然需要使用 index 来访问数组的值
当你需要向数组中添加额外的方法(或另一个对象)时,for...in
循环会带来很大的麻烦。因为 for...in
Array.prototype.decimalfy = function() { for (let i = 0; i <strong> <code>getClothing(false)</code> 실행 후 출력이 <code>정의되지 않음</code>입니다. , 이는 <code>function</code> 함수를 실행하기 전에 모든 변수가 </strong><strong><code>let</code> 및 <code>의 최상위로 <code>승격</code>되기 때문입니다. >const</code>로 선언된 변수는 </strong>code 블록 내에서 <code>let</code>(<code>{}</code>로 표시됨) > 또는 <code>const</code>가 변수를 선언하면 변수 선언이 처리될 때까지 해당 변수는 🎜임시 데드존🎜에 빠지게 됩니다.🎜<pre class="brush:php;toolbar:false">const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for (const digit of digits) { console.log(digit); }🎜
getClothing(false)
실행 후 출력은 ReferenceError: 고정이 정의되지 않았습니다. else
문, 함수 범위 또는 전역 범위 내에서 freezing
이 선언되지 않았기 때문에 에 ReferenceError가 발생합니다.
. 🎜🎜let
및 const
사용 규칙 정보: 🎜
-
let
를 사용하여 선언된 변수는 재할당될 수 있지만 범위 내에서 동일한 재선언 -
const
를 사용하여 선언된 변수는 할당 및 초기화되어야 하지만 동일한 범위 클래스에서 다시 선언하거나 재할당될 수 없습니다. - li>


for (const digit of digits) { if (digit % 2 === 0) { continue; } console.log(digit); }🎜와 같은
+
또는 concat()
메서드입니다. 템플릿 리터럴은 본질적으로 내장된 표현식을 포함하는 문자열 리터럴입니다.템플릿 리터럴은 다음과 같습니다. 역따옴표
( `` )
(작은따옴표 ( '' )
또는 큰따옴표 ( "" )
대신)로 표시할 수 있습니다. ${expression}
🎜Array.prototype.decimalfy = function() { for (i = 0; i 🎜🎜Destructuring🎜🎜🎜으로 표시되는 자리 표시자를 포함합니다. ES6에서는 🎜Destructuring🎜을 사용하여 배열과 객체에서 값을 추출하고 이를 고유 변수에 할당할 수 있습니다🎜🎜Destructuring 배열의 값: 🎜<pre class="brush:php;toolbar:false">const books = ["Don Quixote", "The Hobbit", "Alice in Wonderland", "Tale of Two Cities"]; console.log(...books);🎜🎜Prints: 10 25 -34🎜🎜🎜
[]
는 구조 해제된 배열, x
,y
를 나타냅니다. , z
는 배열의 값이 저장될 변수를 나타냅니다. 배열을 분해할 때 값을 무시할 수도 있습니다(예: const[x,,z]=). point
, y
좌표를 무시합니다.🎜🎜해체된 개체의 값:🎜const fruits = ["apples", "bananas", "pears"]; const vegetables = ["corn", "potatoes", "carrots"]; const produce = fruits.concat(vegetables); console.log(produce);🎜중괄호
{ }
는 해체된 개체, type을 나타냅니다.
, color
및 karat
는 객체의 속성이 저장될 변수를 나타냅니다. 🎜🎜🎜객체 리터럴 약어 🎜🎜const fruits = ["apples", "bananas", "pears"]; const vegetables = ["corn", "potatoes", "carrots"]; const produce = [...fruits,...vegetables]; console.log(produce);🎜🎜 할당된 변수 이름과 동일한 이름 Object 🎜속성 이름이 할당된 변수 이름과 동일한 경우 중복된 변수 이름은 개체 속성에서 삭제될 수 있습니다. 🎜
const order = [20.17, 18.67, 1.50, "cheese", "eggs", "milk", "bread"]; const [total, subtotal, tax, ...items] = order; console.log(total, subtotal, tax, items);🎜 단축 메서드 이름: 🎜
function sum() { let total = 0; for(const argument of arguments) { total += argument; } return total; }🎜 익명 함수는 계산Worth 속성에 할당되지만 함수 키워드가 정말 필요한가요? ES6에서는 필요하지 않습니다! 🎜
function sum(...nums) { let total = 0; for(const num of nums) { total += num; } return total; }🎜🎜for...of 루프🎜🎜🎜
for...of
루프는 JavaScript 루프 제품군에 최근 추가된 기능입니다. 형제 루프 형식인
for
루프와 for...in
루프의 장점을 결합하고 모든 반복 가능한 항목에 대해 루프를 반복할 수 있습니다(즉, 반복 가능한 프로토콜) 유형의 데이터를 준수합니다. 기본적으로 String
, Array
, Map
및 Set
과 같은 데이터 유형이 포함됩니다. >객체 데이터 유형(예: {}
). 🎜기본적으로 객체는 반복 가능하지 않습니다🎜. 🎜🎜for loop🎜const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map(function(name) { return name.toUpperCase(); });🎜
for
루프의 가장 큰 단점은 카운터와 종료 조건을 추적해야 한다는 것입니다. for
루프는 배열을 반복할 때 이점이 있지만 일부 데이터 구조는 배열이 아니므로 루프를 사용하는 것이 항상 적절한 것은 아닙니다. 🎜🎜for...in 루프🎜const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map( name => name.toUpperCase() );🎜🎜배열의 값에 액세스하려면 여전히 인덱스를 사용해야 합니다🎜🎜🎜배열에 추가 메소드(또는 다른 개체)를 추가해야 할 경우
for...
에서 루프는 많은 문제를 일으킬 수 있습니다. for...in
루프는 모든 🎜열거 가능한 속성🎜을 반복하므로 배열의 🎜프로토타입에 다른 속성🎜을 추가하면 해당 속성도 루프에 나타납니다. 🎜Array.prototype.decimalfy = function() { for (let i = 0; i <blockquote><p>forEach 循环 是另一种形式的 JavaScript 循环。但是,forEach() 实际上是数组方法,因此只能用在数组中。也无法停止或退出 forEach 循环。如果希望你的循环中出现这种行为,则需要使用基本的 for 循环。</p></blockquote><p>for...of循环<br><code>for...of</code> 循环用于循环访问任何可迭代的数据类型。<br><code>for...of</code> 循环的编写方式和 <code>for...in</code> 循环的基本一样,只是将 <code>in</code> 替换为 <code>of</code>,可以忽略索引。</p><pre class="brush:php;toolbar:false">const digits = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; for (const digit of digits) { console.log(digit); }
建议使用复数对象名称来表示多个值的集合。这样,循环该集合时,可以使用名称的单数版本来表示集合中的单个值。例如,
for (const button of buttons) {…}
。
for...of
循环还具有其他优势,解决了 for 和 for...in 循环的不足之处。你可以随时停止或退出 for...of 循环。
for (const digit of digits) { if (digit % 2 === 0) { continue; } console.log(digit); }
不用担心向对象中添加新的属性。for...of 循环将只循环访问对象中的值。
Array.prototype.decimalfy = function() { for (i = 0; i <h3 id="strong-展开运算符-strong"><strong>展开运算符</strong></h3><p><strong>展开运算符</strong>(用三个连续的点 (<code>...</code>) 表示)是 ES6 中的新概念,使你能够将字面量对象展开为多个元素</p><pre class="brush:php;toolbar:false">const books = ["Don Quixote", "The Hobbit", "Alice in Wonderland", "Tale of Two Cities"]; console.log(...books);
Prints: Don Quixote The Hobbit Alice in Wonderland Tale of Two Cities
展开运算符的一个用途是结合数组。
如果你需要结合多个数组,在有展开运算符之前,必须使用 Array
的 concat()
方法。
const fruits = ["apples", "bananas", "pears"]; const vegetables = ["corn", "potatoes", "carrots"]; const produce = fruits.concat(vegetables); console.log(produce);
Prints: ["apples", "bananas", "pears", "corn", "potatoes", "carrots"]
使用展开符来结合数组
const fruits = ["apples", "bananas", "pears"]; const vegetables = ["corn", "potatoes", "carrots"]; const produce = [...fruits,...vegetables]; console.log(produce);
剩余参数(可变参数)
使用展开运算符将数组展开为多个元素, 使用剩余参数可以将多个元素绑定到一个数组中.
剩余参数也用三个连续的点 ( ...
) 表示,使你能够将不定数量的元素表示为数组.
用途1: 将变量赋数组值时:
const order = [20.17, 18.67, 1.50, "cheese", "eggs", "milk", "bread"]; const [total, subtotal, tax, ...items] = order; console.log(total, subtotal, tax, items);
用途2: 可变参数函数
对于参数不固定的函数,ES6之前是使用参数对象(arguments)处理:
function sum() { let total = 0; for(const argument of arguments) { total += argument; } return total; }
在ES6中使用剩余参数运算符则更为简洁,可读性提高:
function sum(...nums) { let total = 0; for(const num of nums) { total += num; } return total; }
ES6箭头函数
ES6之前,使用普通函数把其中每个名字转换为大写形式:
const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map(function(name) { return name.toUpperCase(); });
箭头函数表示:
const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map( name => name.toUpperCase() );
普通函数可以是函数声明或者函数表达式, 但是箭头函数始终都是表达式, 全程是箭头函数表达式, 因此因此仅在表达式有效时才能使用,包括:
- 存储在变量中,
- 当做参数传递给函数,
- 存储在对象的属性中。
const greet = name => `Hello ${name}!`;
可以如下调用:
greet('Asser');
如果函数的参数只有一个,不需要使用()
包起来,但是只有一个或者多个, 则必须需要将参数列表放在圆括号内:
// 空参数列表需要括号 const sayHi = () => console.log('Hello Udacity Student!'); // 多个参数需要括号 const orderIceCream = (flavor, cone) => console.log(`Here's your ${flavor} ice cream in a ${cone} cone.`); orderIceCream('chocolate', 'waffle');
一般箭头函数都只有一个表达式作为函数主题:
const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map( name => name.toUpperCase() );
这种函数表达式形式称为简写主体语法:
- 在函数主体周围没有花括号,
- 自动返回表达式
但是如果箭头函数的主体内需要多行代码, 则需要使用常规主体语法:
- 它将函数主体放在花括号内
- 需要使用 return 语句来返回内容。
const upperizedNames = ['Farrin', 'Kagure', 'Asser'].map( name => { name = name.toUpperCase(); return `${name} has ${name.length} characters in their name`; });
javascript标准函数this
1、new 对象
const mySundae = new Sundae('Chocolate', ['Sprinkles', 'Hot Fudge']);
sundae
这个构造函数内的this
的值是实例对象, 因为他使用new被调用.
2、指定的对象
const result = obj1.printName.call(obj2);
函数使用call/apply
被调用,this的值指向指定的obj2,因为call()
第一个参数明确设置this
的指向
3、上下`文对象
data.teleport();
函数是对象的方法, this指向就是那个对象,此处this就是指向data.
4、全局对象或 undefined
teleport();
此处是this指向全局对象,在严格模式下,指向undefined.
javascript中this是很复杂的概念, 要详细判断this,请参考this豁然开朗
箭头函数和this
对于普通函数, this的值基于函数如何被调用, 对于箭头函数,this的值基于函数周围的上下文, 换句话说,this的值和函数外面的this的值是一样的.
function IceCream() { this.scoops = 0; } // 为 IceCream 添加 addScoop 方法 IceCream.prototype.addScoop = function() { setTimeout(function() { this.scoops++; console.log('scoop added!'); console.log(this.scoops); // undefined+1=NaN console.log(dessert.scoops); //0 }, 500); };
标题
const dessert = new IceCream();
dessert.addScoop();
传递给 setTimeout()
的函数被调用时没用到 new
、call()
或 apply()
,也没用到上下文对象
。意味着函数内的 this
的值是全局对象,不是 dessert
对象。实际上发生的情况是,创建了新的 scoops 变量(默认值为 undefined
),然后递增(undefined + 1
结果为 NaN
);
解决此问题的方式之一是使用闭包(closure):
// 构造函数 function IceCream() { this.scoops = 0; } // 为 IceCream 添加 addScoop 方法 IceCream.prototype.addScoop = function() { const cone = this; // 设置 `this` 给 `cone`变量 setTimeout(function() { cone.scoops++; // 引用`cone`变量 console.log('scoop added!'); console.log(dessert.scoops);//1 }, 0.5); }; const dessert = new IceCream(); dessert.addScoop();
箭头函数的作用正是如此, 将setTimeOut()
的函数改为剪头函数:
// 构造函数 function IceCream() { this.scoops = 0; } // 为 IceCream 添加 addScoop 方法 IceCream.prototype.addScoop = function() { setTimeout(() => { // 一个箭头函数被传递给setTimeout this.scoops++; console.log('scoop added!'); console.log(dessert.scoops);//1 }, 0.5); }; const dessert = new IceCream(); dessert.addScoop();
默认参数函数
function greet(name, greeting) { name = (typeof name !== 'undefined') ? name : 'Student'; greeting = (typeof greeting !== 'undefined') ? greeting : 'Welcome'; return `${greeting} ${name}!`; } greet(); // Welcome Student! greet('James'); // Welcome James! greet('Richard', 'Howdy'); // Howdy Richard!
greet() 函数中混乱的前两行的作用是什么?它们的作用是当所需的参数未提供时,为函数提供默认的值。但是看起来很麻烦, ES6引入一种新的方式创建默认值, 他叫默认函数参数:
function greet(name = 'Student', greeting = 'Welcome') { return `${greeting} ${name}!`; } greet(); // Welcome Student! greet('James'); // Welcome James! greet('Richard', 'Howdy'); // Howdy Richard!
默认值与解构
1、默认值与解构数组
function createGrid([width = 5, height = 5]) { return `Generates a ${width} x ${height} grid`; }
createGrid([]); // Generates a 5 x 5 grid
createGrid([2]); // Generates a 2 x 5 grid
createGrid([2, 3]); // Generates a 2 x 3 grid
createGrid([undefined, 3]); // Generates a 5 x 3 grid
createGrid()
函数预期传入的是数组。它通过解构将数组中的第一项设为 width,第二项设为 height。如果数组为空,或者只有一项,那么就会使用默认参数,并将缺失的参数设为默认值 5。
但是存在一个问题:
createGrid(); // throws an error
Uncaught TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined
出现错误,因为 createGrid()
预期传入的是数组,然后对其进行解构。因为函数被调用时没有传入数组,所以出现问题。但是,我们可以使用默认的函数参数!
function createGrid([width = 5, height = 5] = []) { return `Generating a grid of ${width} by ${height}`; } createGrid(); // Generates a 5 x 5 grid
Returns: Generates a 5 x 5 grid
2、默认值与解构函数
就像使用数组默认值解构数组一样,函数可以让对象成为一个默认参数,并使用对象解构:
function createSundae({scoops = 1, toppings = ['Hot Fudge']}={}) { const scoopText = scoops === 1 ? 'scoop' : 'scoops'; return `Your sundae has ${scoops} ${scoopText} with ${toppings.join(' and ')} toppings.`; } createSundae({}); // Your sundae has 1 scoop with Hot Fudge toppings. createSundae({scoops: 2}); // Your sundae has 2 scoops with Hot Fudge toppings. createSundae({scoops: 2, toppings: ['Sprinkles']}); // Your sundae has 2 scoops with Sprinkles toppings. createSundae({toppings: ['Cookie Dough']}); // Your sundae has 1 scoop with Cookie Dough toppings. createSundae(); // Your sundae has 1 scoop with Hot Fudge toppings.
3、数组默认值与对象默认值
默认函数参数只是个简单的添加内容,但是却带来很多便利!与数组默认值相比,对象默认值具备的一个优势是能够处理跳过的选项。看看下面的代码:
function createSundae({scoops = 1, toppings = ['Hot Fudge']} = {}) { … }
在 createSundae()
函数使用对象默认值进行解构时,如果你想使用 scoops
的默认值,但是更改 toppings
,那么只需使用 toppings 传入一个对象:
createSundae({toppings: ['Hot Fudge', 'Sprinkles', 'Caramel']});
将上述示例与使用数组默认值进行解构的同一函数相对比。
function createSundae([scoops = 1, toppings = ['Hot Fudge']] = []) { … }
对于这个函数,如果想使用 scoops 的默认数量,但是更改 toppings,则必须以这种奇怪的方式调用你的函数:
createSundae([undefined, ['Hot Fudge', 'Sprinkles', 'Caramel']]);
因为数组是基于位置的,我们需要传入 undefined 以跳过第一个参数(并使用默认值)来到达第二个参数。
Javascript类
ES5创建类:
function Plane(numEngines) { this.numEngines = numEngines; this.enginesActive = false; } // 由所有实例 "继承" 的方法 Plane.prototype.startEngines = function () { console.log('starting engines...'); this.enginesActive = true; };
ES6类只是一个语法糖,原型继续实际上在底层隐藏起来, 与传统类机制语言有些区别.
class Plane { //constructor方法虽然在类中,但不是原型上的方法,只是用来生成实例的. constructor(numEngines) { this.numEngines = numEngines; this.enginesActive = false; } //原型上的方法, 由所有实例对象共享. startEngines() { console.log('starting engines…'); this.enginesActive = true; } } console.log(typeof Plane); //function
javascript中类其实只是function, 方法之间不能使用,
,不用逗号区分属性和方法.
静态方法
要添加静态方法,请在方法名称前面加上关键字 static
class Plane { constructor(numEngines) { this.numEngines = numEngines; this.enginesActive = false; } static badWeather(planes) { for (plane of planes) { plane.enginesActive = false; } } startEngines() { console.log('starting engines…'); this.enginesActive = true; } }
- 关键字class带来其他基于类的语言的很多思想,但是没有向javascript中添加此功能
- javascript类实际上还是原型继承
- 创建javascript类的新实例时必须使用new关键字
super 和 extends
使用新的super和extends关键字扩展类:
class Tree { constructor(size = '10', leaves = {spring: 'green', summer: 'green', fall: 'orange', winter: null}) { this.size = size; this.leaves = leaves; this.leafColor = null; } changeSeason(season) { this.leafColor = this.leaves[season]; if (season === 'spring') { this.size += 1; } } } class Maple extends Tree { constructor(syrupQty = 15, size, leaves) { super(size, leaves); //super用作函数 this.syrupQty = syrupQty; } changeSeason(season) { super.changeSeason(season);//super用作对象 if (season === 'spring') { this.syrupQty += 1; } } gatherSyrup() { this.syrupQty -= 3; } }
使用ES5编写同样功能的类:
function Tree(size, leaves) { this.size = size || 10; this.leaves = leaves || {spring: 'green', summer: 'green', fall: 'orange', winter: null}; this.leafColor; } Tree.prototype.changeSeason = function(season) { this.leafColor = this.leaves[season]; if (season === 'spring') { this.size += 1; } } function Maple (syrupQty, size, leaves) { Tree.call(this, size, leaves); this.syrupQty = syrupQty || 15; } Maple.prototype = Object.create(Tree.prototype); Maple.prototype.constructor = Maple; Maple.prototype.changeSeason = function(season) { Tree.prototype.changeSeason.call(this, season); if (season === 'spring') { this.syrupQty += 1; } } Maple.prototype.gatherSyrup = function() { this.syrupQty -= 3; }
super 必须在 this 之前被调用
在子类构造函数中,在使用 this 之前,必须先调用超级类。
class Apple {} class GrannySmith extends Apple { constructor(tartnessLevel, energy) { this.tartnessLevel = tartnessLevel; // 在 'super' 之前会抛出一个错误! super(energy); } }
字符串模板
字符串模板相对简单易懂些。ES6中允许使用反引号 ` 来创建字符串,此种方法创建的字符串里面可以包含由美元符号加花括号包裹的变量${vraible}。如果你使用过像C#等后端强类型语言的话,对此功能应该不会陌生。
//产生一个随机数 var num=Math.random(); //将这个数字输出到console console.log(`your num is ${num}`);
iterator, generator
这一部分的内容有点生涩,详情可以参见这里。以下是些基本概念。
- iterator:它是这么一个对象,拥有一个next方法,这个方法返回一个对象{done,value},这个对象包含两个属性,一个布尔类型的done和包含任意值的value
- iterable: 这是这么一个对象,拥有一个obj[@@iterator]方法,这个方法返回一个iterator
- generator: 它是一种特殊的iterator。反的next方法可以接收一个参数并且返回值取决与它的构造函数(generator function)。generator同时拥有一个throw方法
- generator 函数: 即generator的构造函数。此函数内可以使用yield关键字。在yield出现的地方可以通过generator的next或throw方法向外界传递值。generator 函数是通过function*来声明的
- yield 关键字:它可以暂停函数的执行,随后可以再进进入函数继续执行
模块
在ES6标准中,JavaScript原生支持module了。这种将JS代码分割成不同功能的小块进行模块化的概念是在一些三方规范中流行起来的,比如CommonJS和AMD模式。
将不同功能的代码分别写在不同文件中,各模块只需导出公共接口部分,然后通过模块的导入的方式可以在其他地方使用。下面的例子来自tutsplus:
// point.js module "point" { export class Point { constructor (x, y) { public x = x; public y = y; } } } // myapp.js //声明引用的模块 module point from "/point.js"; //这里可以看出,尽管声明了引用的模块,还是可以通过指定需要的部分进行导入 import Point from "point"; var origin = new Point(0, 0); console.log(origin);
Map,Set 和 WeakMap,WeakSet
这些是新加的集合类型,提供了更加方便的获取属性值的方法,不用像以前一样用hasOwnProperty来检查某个属性是属于原型链上的呢还是当前对象的。同时,在进行属性值添加与获取时有专门的get,set 方法。
下方代码来自es6feature
// Sets var s = new Set(); s.add("hello").add("goodbye").add("hello"); s.size === 2; s.has("hello") === true; // Maps var m = new Map(); m.set("hello", 42); m.set(s, 34); m.get(s) == 34;
有时候我们会把对象作为一个对象的键用来存放属性值,普通集合类型比如简单对象会阻止垃圾回收器对这些作为属性键存在的对象的回收,有造成内存泄漏的危险。而WeakMap,WeakSet则更加安全些,这些作为属性键的对象如果没有别的变量在引用它们,则会被回收释放掉,具体还看下面的例子。
正文代码来自es6feature
// Weak Maps var wm = new WeakMap(); wm.set(s, { extra: 42 }); wm.size === undefined // Weak Sets var ws = new WeakSet(); ws.add({ data: 42 });//因为添加到ws的这个临时对象没有其他变量引用它,所以ws不会保存它的值,也就是说这次添加其实没有意思
Proxies
Proxy可以监听对象身上发生了什么事情,并在这些事情发生后执行一些相应的操作。一下子让我们对一个对象有了很强的追踪能力,同时在数据绑定方面也很有用处。
以下例子借用自这里。
//定义被侦听的目标对象 var engineer = { name: 'Joe Sixpack', salary: 50 }; //定义处理程序 var interceptor = { set: function (receiver, property, value) { console.log(property, 'is changed to', value); receiver[property] = value; } }; //创建代理以进行侦听 engineer = Proxy(engineer, interceptor); //做一些改动来触发代理 engineer.salary = 60;//控制台输出:salary is changed to 60
上面代码我已加了注释,这里进一步解释。对于处理程序,是在被侦听的对象身上发生了相应事件之后,处理程序里面的方法就会被调用,上面例子中我们设置了set的处理函数,表明,如果我们侦听的对象的属性被更改,也就是被set了,那这个处理程序就会被调用,同时通过参数能够得知是哪个属性被更改,更改为了什么值。
Symbols
我们知道对象其实是键值对的集合,而键通常来说是字符串。而现在除了字符串外,我们还可以用symbol这种值来做为对象的键。Symbol是一种基本类型,像数字,字符串还有布尔一样,它不是一个对象。Symbol 通过调用symbol函数产生,它接收一个可选的名字参数,该函数返回的symbol是唯一的。之后就可以用这个返回值做为对象的键了。Symbol还可以用来创建私有属性,外部无法直接访问由symbol做为键的属性值。
以下例子来自es6features
(function() { // 创建symbol var key = Symbol("key"); function MyClass(privateData) { this[key] = privateData; } MyClass.prototype = { doStuff: function() { ... this[key] ... } }; })(); var c = new MyClass("hello") c["key"] === undefined//无法访问该属性,因为是私有的
Math,Number,String,Object 的新API
对Math,Number,String还有Object等添加了许多新的API。下面代码同样来自es6features,对这些新API进行了简单展示。
Number.EPSILON Number.isInteger(Infinity) // false Number.isNaN("NaN") // false Math.acosh(3) // 1.762747174039086 Math.hypot(3, 4) // 5 Math.imul(Math.pow(2, 32) - 1, Math.pow(2, 32) - 2) // 2 "abcde".contains("cd") // true "abc".repeat(3) // "abcabcabc" Array.from(document.querySelectorAll('*')) // Returns a real Array Array.of(1, 2, 3) // Similar to new Array(...), but without special one-arg behavior [0, 0, 0].fill(7, 1) // [0,7,7] [1,2,3].findIndex(x => x == 2) // 1 ["a", "b", "c"].entries() // iterator [0, "a"], [1,"b"], [2,"c"] ["a", "b", "c"].keys() // iterator 0, 1, 2 ["a", "b", "c"].values() // iterator "a", "b", "c" Object.assign(Point, { origin: new Point(0,0) })
Promises
Promises是处理异步操作的一种模式,之前在很多三方库中有实现,比如jQuery的deferred 对象。当你发起一个异步请求,并绑定了.when(), .done()等事件处理程序时,其实就是在应用promise模式。
//创建promise var promise = new Promise(function(resolve, reject) { // 进行一些异步或耗时操作 if ( /*如果成功 */ ) { resolve("Stuff worked!"); } else { reject(Error("It broke")); } }); //绑定处理程序 promise.then(function(result) { //promise成功的话会执行这里 console.log(result); // "Stuff worked!" }, function(err) { //promise失败会执行这里 console.log(err); // Error: "It broke" });
更多编程相关知识,请访问:编程视频!!
위 내용은 es6의 새로운 기능은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

C/C에서 JavaScript로 전환하려면 동적 타이핑, 쓰레기 수집 및 비동기 프로그래밍으로 적응해야합니다. 1) C/C는 수동 메모리 관리가 필요한 정적으로 입력 한 언어이며 JavaScript는 동적으로 입력하고 쓰레기 수집이 자동으로 처리됩니다. 2) C/C를 기계 코드로 컴파일 해야하는 반면 JavaScript는 해석 된 언어입니다. 3) JavaScript는 폐쇄, 프로토 타입 체인 및 약속과 같은 개념을 소개하여 유연성과 비동기 프로그래밍 기능을 향상시킵니다.

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

실제 세계에서 JavaScript의 응용 프로그램에는 서버 측 프로그래밍, 모바일 애플리케이션 개발 및 사물 인터넷 제어가 포함됩니다. 1. 서버 측 프로그래밍은 Node.js를 통해 실현되며 동시 요청 처리에 적합합니다. 2. 모바일 애플리케이션 개발은 재교육을 통해 수행되며 크로스 플랫폼 배포를 지원합니다. 3. Johnny-Five 라이브러리를 통한 IoT 장치 제어에 사용되며 하드웨어 상호 작용에 적합합니다.

일상적인 기술 도구를 사용하여 기능적 다중 테넌트 SaaS 응용 프로그램 (Edtech 앱)을 구축했으며 동일한 작업을 수행 할 수 있습니다. 먼저, 다중 테넌트 SaaS 응용 프로그램은 무엇입니까? 멀티 테넌트 SAAS 응용 프로그램은 노래에서 여러 고객에게 서비스를 제공 할 수 있습니다.

이 기사에서는 Contrim에 의해 확보 된 백엔드와의 프론트 엔드 통합을 보여 주며 Next.js를 사용하여 기능적인 Edtech SaaS 응용 프로그램을 구축합니다. Frontend는 UI 가시성을 제어하기 위해 사용자 권한을 가져오고 API가 역할 기반을 준수하도록합니다.

JavaScript는 현대 웹 개발의 핵심 언어이며 다양성과 유연성에 널리 사용됩니다. 1) 프론트 엔드 개발 : DOM 운영 및 최신 프레임 워크 (예 : React, Vue.js, Angular)를 통해 동적 웹 페이지 및 단일 페이지 응용 프로그램을 구축합니다. 2) 서버 측 개발 : Node.js는 비 차단 I/O 모델을 사용하여 높은 동시성 및 실시간 응용 프로그램을 처리합니다. 3) 모바일 및 데스크탑 애플리케이션 개발 : 크로스 플랫폼 개발은 개발 효율을 향상시키기 위해 반응 및 전자를 통해 실현됩니다.

JavaScript의 최신 트렌드에는 Typescript의 Rise, 현대 프레임 워크 및 라이브러리의 인기 및 WebAssembly의 적용이 포함됩니다. 향후 전망은보다 강력한 유형 시스템, 서버 측 JavaScript 개발, 인공 지능 및 기계 학습의 확장, IoT 및 Edge 컴퓨팅의 잠재력을 포함합니다.

JavaScript는 현대 웹 개발의 초석이며 주요 기능에는 이벤트 중심 프로그래밍, 동적 컨텐츠 생성 및 비동기 프로그래밍이 포함됩니다. 1) 이벤트 중심 프로그래밍을 사용하면 사용자 작업에 따라 웹 페이지가 동적으로 변경 될 수 있습니다. 2) 동적 컨텐츠 생성을 사용하면 조건에 따라 페이지 컨텐츠를 조정할 수 있습니다. 3) 비동기 프로그래밍은 사용자 인터페이스가 차단되지 않도록합니다. JavaScript는 웹 상호 작용, 단일 페이지 응용 프로그램 및 서버 측 개발에 널리 사용되며 사용자 경험 및 크로스 플랫폼 개발의 유연성을 크게 향상시킵니다.


핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

안전한 시험 브라우저
안전한 시험 브라우저는 온라인 시험을 안전하게 치르기 위한 보안 브라우저 환경입니다. 이 소프트웨어는 모든 컴퓨터를 안전한 워크스테이션으로 바꿔줍니다. 이는 모든 유틸리티에 대한 액세스를 제어하고 학생들이 승인되지 않은 리소스를 사용하는 것을 방지합니다.

MinGW - Windows용 미니멀리스트 GNU
이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.

SecList
SecLists는 최고의 보안 테스터의 동반자입니다. 보안 평가 시 자주 사용되는 다양한 유형의 목록을 한 곳에 모아 놓은 것입니다. SecLists는 보안 테스터에게 필요할 수 있는 모든 목록을 편리하게 제공하여 보안 테스트를 더욱 효율적이고 생산적으로 만드는 데 도움이 됩니다. 목록 유형에는 사용자 이름, 비밀번호, URL, 퍼징 페이로드, 민감한 데이터 패턴, 웹 셸 등이 포함됩니다. 테스터는 이 저장소를 새로운 테스트 시스템으로 간단히 가져올 수 있으며 필요한 모든 유형의 목록에 액세스할 수 있습니다.

WebStorm Mac 버전
유용한 JavaScript 개발 도구

드림위버 CS6
시각적 웹 개발 도구
