This article brings you an introduction to the usage of core features in ES6 (with examples). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Although ES6 provides many new features, they are not used frequently in our actual work. According to the 28-20 rule, we should use 80% of our energy and time to do a good job Specializing in these 20% of core features will yield miraculous results with twice the result with half the effort!
##1. Development environment configuration
This part focuses on Introduction: babel compiles ES6 syntax and how to use webpack to achieve modularity.1.babel
Why do you need babel? ES6 provides many new features, but not all browsers can fully support them. The figure below is a list of ES6 compatibility of various browsers (taking export as an example)As can be seen from the above figure, some browsers are not compatible with ES6 It is very friendly. In response to the compatibility issue of ES6, many teams have developed a variety of grammar parsing and conversion tools (such as babel, jsx, traceur, etc.), which can convert the ES6 grammar we wrote into ES5, which is equivalent to ES6 and browser He served as a translator between the devices. Babel is a widely used transcoder that can convert ES6 code into ES5 code so that it can be executed in the existing environment. How to configure babel?
·首先要先安装node.js,运行npm init,然后会生成package.json文件 ·npm install --save-dev babel-core babel-preset-es2015 babel-preset-latest ·创建并配置.babelrc文件//存放在项目的根目录下,与node_modules同级 ·npm install -g babel-cli ·babel-version
//.babelrc文件 { "presets": ["es2015", "latest"], "plugins": [] }
·创建./src/index.js ·内容:[1,2,3].map(item=>item+1); ·运行babel./src/index.js
"use strict"; [1, 2, 3].map(function (item) { return item + 1; });
Why use WebPack?
Many web pages today can actually be regarded as feature-rich applications. They have complex JavaScript codes and a lot of dependency packages, and rapid modeling tools have emerged. Among them, the webpack function Powerful and loved by people.
The way Webpack works is: treat your project as a whole, through a given main file (such as: index.js), Webpack will find all the dependent files of your project starting from this file, and use loaders to process it They are finally packaged into one (or more) JavaScript files that can be recognized by the browser.How to configure webpack?
·npm install webpack babel-loader --save-dev
·创建并配置 webpack.config.js//webpack.config.js文件与package.json同级
·配置 package.json中的scripts
·运行 npm start
//配置 webpack.config.js 针对.js结尾的文件除了node_modules都用babel解析
module.exports = {
entry: './src/index.js',
output: {
path: __dirname,
filename: './build/bundle.js'
},
module: {
rules: [{
test: /\.js?$/,
exclude: /(node_modules)/,
loader: 'babel-loader'
}]
}
}
//配置 package.json中的scripts
"scripts": {
"start": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
}
ES5 only has global scope and function scope (for example, we must wrap the code in a function to limit scope), which leads to many problems:
Case 1: Inner variables cover outer variablesvar tmp = new Date();
function f() {
console.log(tmp); //undefined
if (false) {
var tmp = "hello world";
}
}
var s = 'hello';
for (var i = 0; i
In ES5, we need to construct an immediately executed function expression to ensure that we do not pollute the global scope. In ES6, we can use simpler braces ({}) and then use const or let instead of var to achieve the same effect.
2. Closures in the loop body no longer have problemsIn ES5, if a closure is generated in the loop body and variables outside the closure are accessed, Will cause problems. In ES6, you can use "let" to avoid problems.
3. Prevent repeated declaration of variables
ES6 does not allow using let or in the same scope const Repeated declaration of variables with the same name. This is very helpful to prevent duplicate declarations of function expressions in different js libraries.
3. Array expansion1. Array.from(): Convert a pseudo array object or a traversable object into a real array
If all the key names of an object are positive integers or zero and have a length attribute, then the object looks like an array and is called a pseudo array. Typical pseudo-arrays are function arguments objects, most sets of DOM elements, and strings.
... <button>测试1</button> <br> <button>测试2</button> <br> <button>测试3</button> <br> <script> let btns = document.getElementsByTagName("button") console.log("btns",btns);//得到一个伪数组 btns.forEach(item=>console.log(item)) Uncaught TypeError: btns.forEach is not a function </script>
For pseudo arrays, there is no general method for arrays, and direct traversal will cause errors. ES6 adds the Array.from() method to provide a clear and clear way to solve this need.
Array.from(btns).forEach(item=>console.log(item))将伪数组转换为数组
当调用 new Array( )构造器时,根据传入参数的类型与数量的不同,实际上会导致一些不同的结果, 例如: 当使用单个数值参数来调用 Array 构造器时,数组的长度属性会被设置为该参数。 如果使用多个参数(无论是否为数值类型)来调用,这些参数也会成为目标数组的项。数组的这种行为既混乱又有风险,因为有时可能不会留意所传参数的类型。 ES6 引入了Array.of( )方法来解决这个问题。该方法的作用非常类似Array构造器,但在使用单个数值参数的时候并不会导致特殊结果。Array.of( )方法总会创建一个包含所有传入参数的数组,而不管参数的数量与类型: Array.of基本上可以用来替代Array()或newArray(),并且不存在由于参数不同而导致的重载,而且他们的行为非常统一。 3.数组实例的 find() 和 findIndex() 数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。 4.数组实例的includes() Array.prototype.includes方法返回一个布尔值,表示某个数组是否包含给定的值。该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。 没有该方法之前,我们通常使用数组的indexOf方法,检查是否包含某个值。indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。 5.数组实例的 entries(),keys() 和 values() ES6 提供entries(),keys()和values(),用于遍历数组。它们都返回一个遍历器对象,可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。 四、箭头函数 ES6 允许使用“箭头”(=>)定义函数。它主要有两个作用:缩减代码和改变this指向,接下来我们详细介绍: 1. 缩减代码 多个参数记得加括号 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。 由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。 此外还有个好处就是简化回调函数 2. 改变this指向 长期以来,JavaScript 语言的this对象一直是一个令人头痛的问题,在对象方法中使用this,必须非常小心。箭头函数”绑定”this,很大程度上解决了这个困扰。我们不妨先看一个例子: teamSummary函数里面又嵌了个函数,这导致内部的this的指向发生了错乱。 方法一、let self = this 方法二、bind函数 方法三、 箭头函数 3.使用注意点 (1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。 (2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。 (3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。 (4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。 五、rest 参数 ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。 rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。 传统写法: ES6写法: 也可以与解构赋值组合使用 rest 参数还可以与箭头函数结合 注意:①每个函数最多只能声明一个rest参数,而且 rest参数必须是最后一个参数,否则报错。 ②rest参数不能用于对象字面量setter之中 六、展开运算符 与剩余参数关联最密切的就是扩展运算符。剩余参数允许你把多个独立的参数合并到一个数组中;而扩展运算符则允许将一个数组分割,并将各个项作为分离的参数传给函数。 当用在字符串或数组前面时称为扩展运算符,个人觉得可以理解为rest参数的逆运算,用于将数组或字符串进行拆解。有些时候,函数不允许传入数组,此时使用展开运算符就很方便,不信的话,咱们看个例子:Math.max()方法,它接受任意数量的参数,并会返回其中的最大值。 但若想处理数组中的值,此时该如何找到最大值?Math.max()方法并不允许你传入一个数组。其实你可以像使用rest参数那样在该数组前添加...,并直接将其传递给 Math.max() 扩展运算符还可以与其他参数混用 扩展运算符拆解字符串与数组 还可以实现拼接 七、解构赋值----更方便的数据访问 ES6 新增了解构,这是将一个数据结构分解为更小的部分的过程。 1.解构为何有用? 在ES5及更早版本中,从对象或数组中获取信息、并将特定数据存入本地变量,需要书写许多并且相似的代码。例如: 此代码提取了expense对象的type与amount值,并将其存在同名的本地变量上。虽然 这段代码看起来简单,但想象一下若有大量变量需要处理,你就必须逐个为其赋值;并且若有一个嵌套的数据结构需要遍历以寻找信息,你可能会为了一点数据而挖掘整个结构。 这就是ES6为何要给对象与数组添加解构。当把数据结构分解为更小的部分时,从中提取你要的数据会变得容易许多。 2.对象 上个例子中如果采用对象解构的方法,就很容易获取expense对象的type与amount值。 我们再来看个例子: 注意:你必须用圆括号包裹解构赋值语句,这是因为暴露的花括号会被解析为代码块语句,而块语句不允许在赋值操作符(即等号)左侧出现。圆括号标示了里面的花括号并不是块语句、而应该被解释为表达式,从而允许完成赋值操作。 默认值: 嵌套对象解构: 本例中的解构模式使用了花括号,表示应当下行到node对象的loc属性内部去寻找start属性。 必须传值的解构参数 在此函数内,name与value参数是必需的,而secure、path、domain与expires则不是。默认情况下调用函数时未给参数解构传值会抛出错误。像上例中如果setCookie不传第三个参数,就会报错。若解构参数是可选的,可以给解构的参数提供默认值来处理这种错误。 3.数组 用{}解构返回数组个数 数组解构也可以用于赋值上下文,但不需要用小括号包裹表达式。这点跟对象解构的约定不同。 默认值:数组解构赋值同样允许在数组任意位置指定默认值。当指定位置的项不存在、或其值为undefined,那么该默认值就会被使用。 与rest参数搭配 在ES5中常常使用concat()方法来克隆数组,例如: 在ES6中,你可以使用剩余项的语法来达到同样效果 接下我们看个例子:如何将数组转化为对象 混合解构 当使用解构来配合var、let、const来声明变量时,必须提供初始化程序(即等号右边的值)。下面的代码都会因为缺失初始化程序而抛出语法错误: 八、模板字符串(template string) 模板字符串是增强版的字符串,用反引号(`)标识。**它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。
再举个例子,工作中常用到ElementUI库,在自定义一个弹出框时,使用模板字符串就很方便: 九、Class 和传统构造函数有何区别 从概念上讲,在 ES6 之前的 JS
中并没有和其他面向对象语言那样的“类”的概念。长时间里,人们把使用 new 关键字通过函数(也叫构造器)构造对象当做“类”来使用。由于 JS
不支持原生的类,而只是通过原型来模拟,各种模拟类的方式相对于传统的面向对象方式来说非常混乱,尤其是处理当子类继承父类、子类要调用父类的方法等等需求时。 对比在传统构造函数和 ES6 中分别如何实现类: 这两者有什么联系?其实这两者本质是一样的,只不过是语法糖写法上有区别。所谓语法糖是指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。比如这里class语法糖让程序更加简洁,有更高的可读性。 Class之间可以通过extends关键字实现继承,这比ES5的通过修改原型链实现继承,要清晰和方便很多。 Class 在语法上更加贴合面向对象的写法 Class 实现继承更加易读、易理解,对初学者更加友好 本质还是语法糖,使用prototype 十、Promise的基本使用和原理 在JavaScript的世界中,所有代码都是单线程执行的。由于这个“缺陷”,导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行。Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大。
ES6中的promise的出现给我们很好的解决了回调地狱的问题,所谓的回调地狱是指当太多的异步步骤需要一步一步执行,或者一个函数里有太多的异步操作,这时候就会产生大量嵌套的回调,使代码嵌套太深而难以阅读和维护。ES6认识到了这点问题,现在promise的使用,完美解决了这个问题。 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。promise 对象初始化状态为 pending ;当调用resolve(成功),会由pending => fulfilled ;当调用reject(失败),会由pending => rejected。具体流程见下图:
new Promise一个实例,而且要 return new Promise 时要传入函数,函数有resolve reject 两个参数 成功时执行 resolve,失败时执行reject then 监听结果 promise会让代码变得更容易维护,像写同步代码一样写异步代码,同时业务逻辑也更易懂。 十一、Iterator 和 for...of 循环 JavaScript
原有的表示“集合”的数据结构,主要是数组(Array)和对象(Object),ES6
又添加了Map和Set。这样就需要一种统一的接口机制,来处理所有不同的数据结构。遍历器(Iterator)就是这样一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作(即依次处理该数据结构的所有成员)。 1.Iterator的作用: 为各种数据结构,提供一个统一的、简便的访问接口; 使得数据结构的成员能够按某种次序排列 ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。 2.原生具备iterator接口的数据(可用for of遍历) Array set容器 map容器 String 函数的 arguments 对象 NodeList 对象 3.几种遍历方式比较 for of 循环不仅支持数组、大多数伪数组对象,也支持字符串遍历,此外还支持 Map 和 Set 对象遍历。 for in循环可以遍历字符串、对象、数组,不能遍历Set/Map forEach 循环不能遍历字符串、对象,可以遍历Set/Map 十二、ES6模块化 ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,旨在成为浏览器和服务器通用的模块解决方案。其模块功能主要由两个命令构成:export和import。export命令用于规定模块的对外接口,import命令用于输入其他模块提供的功能。 如上例所示,使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。 上面代码是一个模块文件export-default.js,它的默认输出是一个函数。 上面代码的import命令,可以用任意名称指向export-default.js输出的方法,这时就不需要知道原模块输出的函数名。需要注意的是,这时import命令后面,不使用大括号。 let items = new Array(2) ;
console.log(items.length) ; // 2
console.log(items[0]) ; // undefined
console.log(items[1]) ;
let items = new Array(1, 2) ;
console.log(items.length) ; // 2
console.log(items[0]) ; // 1
console.log(items[1]) ; // 2
let items = Array.of(1, 2);
console.log(items.length); // 2
console.log(items[0]); // 1
console.log(items[1]); // 2
items = Array.of(2);
console.log(items.length); // 1
console.log(items[0]); // 2
[1, 4, -5, 10].find((n) => n <p>数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1。</p><pre class="brush:php;toolbar:false">[1, 5, 10, 15].findIndex(function(value, index, arr) {
return value > 9;
}) // 2
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(3, -1); // true
[1, 2, 3, 5, 1].includes(1, 2); // true
[NaN].indexOf(NaN) // -1
[NaN].includes(NaN) // true
for (let index of ['a', 'b'].keys()) {
console.log(index);
}
// 0
// 1
for (let elem of ['a', 'b'].values()) {
console.log(elem);
}
// 'a'
// 'b'
for (let [index, elem] of ['a', 'b'].entries()) {
console.log(index, elem);
}
// 0 "a"
// 1 "b"
const double1 = function(number){
return number * 2; //ES5写法
}
const double2 = (number) => {
return number * 2; //ES6写法
}
const double4 = number => number * 2; //可以进一步简化
const double6 = (number,number2) => number + number2;
const double = (number,number2) => {
sum = number + number2
return sum;
}
// 报错
let getTempItem = id => { id: id, name: "Temp" };
// 不报
let getTempItem = id => ({ id: id, name: "Temp" });
// 正常函数写法
[1,2,3].map(function (x) {
return x * x;
});
// 箭头函数写法
[1,2,3].map(x => x * x);//[1, 4, 9]
const team = {
members:["Henry","Elyse"],
teamName:"es6",
teamSummary:function(){
return this.members.map(function(member){
return `${member}隶属于${this.teamName}小组`; // this不知道该指向谁了
})
}
}
console.log(team.teamSummary());//["Henry隶属于undefined小组", "Elyse隶属于undefined小组"]
那如何修改:const team = {
members:["Henry","Elyse"],
teamName:"es6",
teamSummary:function(){
let self = this;
return this.members.map(function(member){
return `${member}隶属于${self.teamName}小组`;
})
}
}
console.log(team.teamSummary());//["Henry隶属于es6小组", "Elyse隶属于es6小组"]
const team = {
members:["Henry","Elyse"],
teamName:"es6",
teamSummary:function(){
return this.members.map(function(member){
// this不知道该指向谁了
return `${member}隶属于${this.teamName}小组`;
}.bind(this))
}
}
console.log(team.teamSummary());//["Henry隶属于es6小组", "Elyse隶属于es6小组"]
const team = {
members:["Henry","Elyse"],
teamName:"es6",
teamSummary:function(){
return this.members.map((member) => {
// this指向的就是team对象
return `${member}隶属于${this.teamName}小组`;
})
}
}
console.log(team.teamSummary());//["Henry隶属于es6小组", "Elyse隶属于es6小组"]
我们举个例子:如何实现一个求和函数?function addNumbers(a,b,c,d,e){
var numbers = [a,b,c,d,e];
return numbers.reduce((sum,number) => {
return sum + number;
},0)
}
console.log(addNumbers(1,2,3,4,5));//15
function addNumbers(...numbers){
return numbers.reduce((sum,number) => {
return sum + number;
},0)
}
console.log(addNumbers(1,2,3,4,5));//15
var array = [1,2,3,4,5,6];
var [a,b,...c] = array;
console.log(a);//1
console.log(b);//2
console.log(c);//[3, 4, 5, 6]
const numbers = (...nums) => nums;
numbers(1, 2, 3, 4, 5)// [1,2,3,4,5]
let object = {
set name(...value){ //报错
//执行一些逻辑
}
}
let value1 = 25,
let value2 = 50;
console.log(Math.max(value1, value2)); // 50
let values = [25,50,75, 100]
//等价于console.log(Math.max(25,50,75,100));
console.log(Math.max(...values)); //100
let values = [-25,-50,-75,-100]
console.log(Math.max(...values,0)); //0
var array = [1,2,3,4,5];
console.log(...array);//1 2 3 4 5
var str = "String";
console.log(...str);//S t r i n g
var defaultColors = ["red","greed"];
var favoriteColors = ["orange","yellow"];
var fallColors = ["fire red","fall orange"];
console.log(["blue","green",...fallColors,...defaultColors,...favoriteColors]
//["blue", "green", "fire red", "fall orange", "red", "greed", "orange", "yellow"]
var expense = {
type: "es6",
amount:"45"
};
var type = expense.type;
var amount = expense.amount;
console.log(type,amount);
const { type,amount } = expense;
console.log(type,amount);
let node = {type:"Identifier", name:"foo"},
type = "Literal",name = 5;
({type,name}= node);// 使用解构来分配不同的值
console.log(type); // "Identifier"
console.log(name); // "foo"
可以选择性地定义一个默认值,以便在指定属性不存在时使用该值。若要这么做,需要在 属性名后面添加一个等号并指定默认值,就像这样:let node = {
type: "Identifier",
name: "foo"
};
let {
type,
name,
value = true
} = node;
console.log(type); // "Identifier"
console.log(name); // "foo"
console.log(value); // true
使用类似于对象字面量的语法,可以深入到嵌套的对象结构中去提取你想要的数据。let node = {
type: "Identifier",
name: "foo",
loc: {
start: {
line: 1,
column: 1
},
end: {
line: 1,
column: 4
}
}
};
let { loc: { start }} = node;
console.log(start.line); // 1
console.log(start.column); // 1
function setCookie(name, value, {
secure,
path,
domain,
expires
}) {
// 设置cookie的代码
}
setCookie("type", "js");//报错
function setCookie(name, value, {
secure,
path,
domain,
expires
} = {}) {}
setCookie("type", "js");//不会报错
const names = ["Henry","Bucky","Emily"];
const [name1,name2,name3] = names;
console.log(name1,name2,name3);//Henry Bucky Emily
const [name,...rest] = names;//结合展开运算符
console.log(rest);//["Bucky", "Emily"]
const {length} = names;
console.log(length);//3
let colors = ["red", "green", "blue"],
firstColor = "black",
secondColor = "purple";
[firstColor, secondColor] = colors;
console.log(firstColor); // "red"
console.log(secondColor); // "green"
let colors = ["red"];
let [firstColor, secondColor = "green"] = colors;
console.log(firstColor); // "red"
console.log(secondColor);// "green"
//在ES5中克隆数组
var colors = ["red", "green", "blue"];
var clonedColors = colors.concat();
console.log(clonedColors); //"[red,green,blue]"
//在ES6中克隆数组
let colors = ["red", "green", "blue"];
let [...clonedColors] = colors;
console.log(clonedColors); //[red,green,blue]
const points = [
[4,5],
[10,1],
[0,40]
];
//期望得到的数据格式如下,如何实现?
// [
// {x:4,y:5},
// {x:10,y:1},
// {x:0,y:40}
// ]
let newPoints = points.map(pair => {
const [x,y] = pair;
return {x,y}
})
//还可以通过以下办法,更为简便
let newPoints = points.map(([x,y]) => {
return {x,y}
})
console.log(newPoints);
const people = [
{name:"Henry",age:20},
{name:"Bucky",age:25},
{name:"Emily",age:30}
];
//es5 写法
var age = people[0].age;
console.log(age);
//es6 解构
const [age] = people;
console.log(age);//第一次解构数组 {name:"Henry",age:20}
const [{age}] = people;//再一次解构对象
console.log(age);//20
4.注意点
var { type, name }; // 语法错误!
let { type, name }; // 语法错误!
const { type, name }; // 语法错误!
模板字符串中嵌入变量和函数,需要将变量名写在${}之中。**let name = "Henry";
function makeUppercase(word){
return word.toUpperCase();
}
let template =
`
<h1>${makeUppercase('Hello')}, ${name}!</h1>//可以存放函数和变量
<p>感谢大家收看我们的视频, ES6为我们提供了很多遍历好用的方法和语法!</p>
`;
document.getElementById('template').innerHTML = template; await this.$alert(
`<p><strong>确认是否升级${
this.lectureName
}</strong><br>(若已存在讲义套件,升级后请重新生成)</p>`,
{
dangerouslyUseHTMLString: true
}
)
ES6提供了更接近传统语言的写法,引入了Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。但是类只是基于原型的面向对象模式的语法糖。//传统构造函数
function MathHandle(x,y){
this.x=x;
this.y=y;
}
MathHandle.prototype.add =function(){
return this.x+this.y;
};
var m=new MathHandle(1,2);
console.log(m.add())
//class语法
class MathHandle {
constructor(x,y){
this.x=x;
this.y=y;
}
add(){
return this.x+this.y;
}
}
const m=new MathHandle(1,2);
console.log(m.add())
typeof MathHandle //"function"
MathHandle===MathHandle.prototype.constructor //true
对比在传统构造函数和 ES6 中分别如何实现继承:
//传统构造函数继承
function Animal() {
this.eat = function () {
alert('Animal eat')
}
}
function Dog() {
this.bark = function () {
alert('Dog bark')
}
}
Dog.prototype = new Animal()// 绑定原型,实现继承
var hashiqi = new Dog()
hashiqi.bark()//Dog bark
hashiqi.eat()//Animal eat
//ES6继承
class Animal {
constructor(name) {
this.name = name
}
eat() {
alert(this.name + ' eat')
}
}
class Dog extends Animal {
constructor(name) {
super(name) // 有extend就必须要有super,它代表父类的构造函数,即Animal中的constructor
this.name = name
}
say() {
alert(this.name + ' say')
}
}
const dog = new Dog('哈士奇')
dog.say()//哈士奇 say
dog.eat()//哈士奇 eat
Class 和传统构造函数有何区别
Promise原理
Promise的使用流程
function loadImg(src){
const promise=new Promise(function(resolve,reject){
var img=document.createElement('img')
img.onload=function(){
resolve(img)
}
img.onerror=function(){
reject()
}
img.src=src
})
return promise//返回一个promise实例
}
var src="http://www.imooc.com/static/img/index/logo_new.png"
var result=loadImg(src)
result.then(function(img){
console.log(img.width)//resolved(成功)时候的回调函数
},function(){
console.log("failed")//rejected(失败)时候的回调函数
})
result.then(function(img){
console.log(img.height)
})
let arr3 = [1, 2, 'kobe', true];
for(let i of arr3){
console.log(i); // 1 2 kobe true
}
let str = 'abcd';
for(let item of str){
console.log(item); // a b c d
}
var engines = new Set(["Gecko", "Trident", "Webkit", "Webkit"]);
for (var e of engines) {
console.log(e);
}
// Gecko
// Trident
// Webkit
/** 定义模块 math.js **/
var basicNum = 0;
var add = function (a, b) {
return a + b;
};
export { basicNum, add };
/** 引用模块 **/
import { basicNum, add } from './math';
function test(ele) {
ele.textContent = add(99 + basicNum);
}
// export-default.js
export default function () {
console.log('foo');
}
其他模块加载该模块时,import命令可以为该匿名函数指定任意名字。// import-default.js
import customName from './export-default';
customName(); // 'foo'
The above is the detailed content of Introduction to the usage of core features in ES6 (with examples). For more information, please follow other related articles on the PHP Chinese website!