前端笔记之ES678&Webpack&Babel(中)对象|字符串|数组的扩展&函数新特性&类
一、对象的扩展
1.1对象属性名表达式
ES6可以在JSON中使用[]包裹一个key的名字。此时这个key将用表达式作为属性名(被当做变量求值),这个key值必须是字符串。
var a = 'name'
var obj = {
[a] : "小明",
age:12,
sex:"男"
}
console.log(obj.name)
1.2 Object.assign()方法
该方法用于对象的合并,将源对象的所有可枚举的属性,复制到目标对象。
Object.assign()方法的第一个参数是目标对象,后面的参数都是源对象。
let obj1 = {a:1};
let obj2 = {a:2, b:3};
let obj3 = {b:4, c:5};
Object.assign(obj1,obj2,obj3) console.log(obj1)
console.log(obj2)
console.log(obj3)
注意:
l 它没有返回值,会直接改变Object.assign()中的第一个参数对象
l 后面可以罗列无限个对象,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
如果该参数不是对象,则会先转成对象,然后返回。
typeof Object.assign(2) // "object"
由于undefined和null无法转成对象,所以如果它们作为参数,就会报错。
Object.assign(undefined) // 报错
Object.assign(null) // 报错
1.3 Object.keys()方法
它可以将一个对象所有的键名(key)转为一个数组对象,并返回:
let o = {a: 1, b: 2, c: 3};
console.log(Object.keys(o)); //[ 'a', 'b', 'c' ]
1.4 Object.values()方法
它可以将一个对象所有的键值(value)转为一个数组对象,并返回:
let o = {a: 10, b: 20, c: 33};
console.log(Object.values(o)); //[ 10, 20, 33 ]
1.5 Object.entries()方法
它可以将一个对象所有的键名(key)和键值(value)转为一个数组对象,并返回:
let o = {a: 10, b: 20, c: 33};
console.log(Object.entries(o));
1.6 Object.is()
ES5 比较两个值是否相等,只有两个运算符:相等运算符(==)和严格相等运算符(===)。它们都有缺点,前者会自动转换数据类型,后者的NaN不等于自身,以及+0等于-0。JavaScript 缺乏一种运算,在所有环境中,只要两个值是一样的,它们就应该相等。
ES6 提出“Same-value equality”(同值相等)算法,用来解决这个问题。Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。
console.log(Object.is('a','a')); //true
console.log(Object.is({}, {})); //false
console.log(Object.is([], [])); //false 不同之处只有两个:一是:+0不等于-0,二是NaN等于自身。
console.log(+0 === -0); //true
console.log(NaN === NaN); //false console.log(Object.is(+0, -0)); //false
console.log(Object.is(NaN, NaN)); //true
二、字符串的扩展
2.1定义字符串``反引号
之前定义字符串,必须使用以下定界符
""或''
它们的缺点是在做连字符串的时候,不方便:
var name = "小明";
var age = 12;
var str = "你好,我是" + name + "我今年" + age + "岁";
console.log(str)
ES6中用``来做定界符:
var str = `你好`;
console.log(str)
console.log`str`
console.log(typeof str)
var name = "小明";
var age = 12;
var str = `你好,我是${name}我今年${age}岁`;
console.log(str)
注意:只有``中能够用${}嵌套变量
动态求值:
var str = `今年是${2016 + 2}`;
console.log(str); //
能写简单运算、函数调用、变量、Math函数、数组表达式方法(map、reduce、filter、join)、三元运算符
function sum(a,b){
return a + b;
} var str1 = `哈${Math.random()}哈`;
var str2 = `哈${sum(3,4)}哈`;
var str3 = `哈${5 > 10 ? true : false}哈`;
console.log(str1)
console.log(str2)
console.log(str3)
2.2字符串方法
以前JavaScript只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。
ES6又提供了三种新方法:
includes() 返回Boolean值,检查字符串或数组中是否存在某项
startsWith() 返回Boolean值,检查参数字符串是否在原字符串的开头
endsWith() 返回Boolean值,检查参数字符串是否在原字符串的结尾
var url = "http://www.aiqianduan.com/";
console.log(url.includes("www")); //true
console.log(url.startsWith("http")); //true
console.log(url.endsWith("com/")); //true
这三个方法都支持第二个参数,表示开始搜索的位置:
let s = 'Hello world!';
console.log(s.includes('Hello', 6)) //false
console.log(s.startsWith('world', 6)) //true
console.log(s.endsWith('Hello', 5)) //true
上面代码表示,使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。
repeat()返回一个新的字符串能够将原字符串重复n次
console.log('★'.repeat(10))
三、数组的扩展
3.1 find和findIndex方法
数组实例的find方法,用于找出第一个符合条件的数组成员,它不会遍历完整的数组。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员,就结束。如果没有符合条件的成员,则返回undefined。
let arr = [2,3,4,5,6,7,8,9,10,11,12];
let item = arr.find(function(item){
return item > 7;
})
console.log(item)
数组的findIndex()方法的用法和find一样,返回第一个符合条件的数组成员的下标位置,如果所有的成员都不符合,则返回-1。
let arr = [2,3,4,5,6,7,8,9,10,11,12]; let index = arr.findIndex(function(item){
return item > 7;
})
console.log(index); //
3.2 Array.from()方法
使用“...”可以类数组对象变为真正的数组。
什么是类数组对象?就是对象的键名都是0、1、2、3、4...,并且有length属性,可以被枚举。
var obj = {
0 : 100,
1 : 200,
2 : 300,
length:3
}
var arr= Array.from(obj);
console.log(obj)
console.log(arr)
最常见的类数组对象是arguments:
function fun(){
console.log([...arguments]);
}
fun(1,2,3,4)
3.3 Array.of()方法
它可以将零散的值变为数组
let arr = Array.of(3,4,5,6,7,8);
console.log(arr)
3.4 includes()方法
验证数组中是否存在某一项:
let arr = [3,4,5,88,100];
console.log(arr.includes(88)); //true
console.log(arr.includes(888)); //false
该方法的第二个参数表示搜索的起始位置,默认为。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度
(比如第二个参数为-4,但数组长度为),则会重置为从开始。
[1, 2, 3].includes(3, 3); // false
[1, 2, 3].includes(3, -1); // true
没有该方法之前,我们通常使用数组的indexOf方法,检查是否包含某个值。
indexOf方法有两个缺点,一是不够语义化,它的含义是找到参数值的第一个出现位置,所以要去比较是否不等于-1,表达起来不够直观。二是,它内部使用严格相等运算符(===)进行判断,这会导致对NaN的误判。
[NaN].indexOf(NaN)
// -1
includes使用的是不一样的判断算法,就没有这个问题。
[NaN].includes(NaN)
// true
3.5 fill()数组填充
var arr = new Array(10).fill("★");
console.log(arr)
3.6 for of遍历
增加了一种数组的遍历方法,叫for of遍历,通常配合arr.entries()
var arr = ['白板','幺鸡','二条','三饼','四筒'];
for(var v of arr){
console.log(v)
}
var arr = ['白板','幺鸡','二条','三饼','四筒'];
for(var [k,v] of arr.entries()){
console.log(k,v)
}
四、ES6中函数的新特性
4.1箭头函数(重点)
ES6 允许使用“箭头”(=>)定义函数:
注意:
l => 是一个完整的运算符,不能拆开 = >
l 箭头函数一定是匿名函数,要使用“=”赋值接收某一个匿名的箭头函数,来给这个匿名的箭头函数命名。
函数的扩展:http://es6.ruanyifeng.com/#docs/function
l 【function的基本简化】
const sum = function(a, b){
return a + b;
}
等价于,现在用箭头函数的定义:
const sum = (a, b)=>{
return a + b;
}
【return和{}、()都可以简化】
const sum = (a,b)=> a + b;
console.log(sum(4,5))
如果箭头函数中,只有一条return语句时,可以简化“{}”和return
言外之意:如果语句不止一条,必须加“{}”和return语句
如果箭头函数形参变量中,只有一个参数,可以不写形参变量的“()”圆括号
const mianji = r => 3.14 * r * r
console.log(mianji(10))
如果箭头函数不需要参数,就使用一个圆括号代表参数部分。
const f = ()=> 5
// 等价于
const f = function(){
return 5;
}
由于“{}”被解析为函数体,所以如果箭头函数直接返回一个对象,必须在对象外加上圆括号,否则报错。
// const fun = (id,name)=> {"id": id, "name": name} //报错
const fun = (id,name)=> ({"id": id, "name": name}) console.log(fun(10001,"小明"))
可以连续写箭头函数,表示函数的嵌套,外层的函数返回了一个函数。
const fun = a=> b=> a + b;
console.log(fun(10)(5))
等价于下面两种写法:
const fun = (a)=>{
return (b)=>{
return a + b;
}
}
function fun(a){
return function(b){
return a + b;
}
}
注意:箭头函数有几个使用注意点。
(1)函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
(2)不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
上面四点中,第一点尤其值得注意。this对象的指向是可变的,但是在箭头函数中,它是固定的。
4.2函数的剩余参数
ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
箭头函数和普通函数一样,也可以使用ES6的默认参数和剩余参数:
const fun = (a,...b)=>{
console.log(a)
console.log(b)
}
fun(1,2,3,4,5,6);
4.3函数的默认参数
ES6允许为函数的参数设置默认值,即直接写在参数定义的后面:
const sum = (a, b=10)=>{
return a + b;
}
console.log(sum(3,4)); //
console.log(sum(3)); //
在函数的形参中赋值了默认值10,表示如果调用的时候没有传入b的值,默认值才会生效。
4.4箭头函数的上下文
以前说的判断上下文
规则1:直接圆括号调用fn(),此时this是window
规则2:对象打点调用obj.fn(),此时this是obj
规则3:数组中枚举函数调用arr[3](),此时this是arr
规则4:定时器调用函数setInterval(fn , 10),此时this是window
规则5:按钮的事件监听oBtn.onclick = fn,此时this是oBtn
规则6:call和allpay可以指定,fn.call(obj),此时this是obj
规则7:用new调用函数,new fn(),此时this是秘密新创建的空白对象。
上面的规则,不适用于箭头函数!
箭头函数的上下文是什么规则呢?
箭头函数的上下文,是这个函数定义时所处的上下文,而不是看如何调用的。
箭头函数定义时所在的函数内的this是谁,这个箭头函数的this终身是谁,不能被改变。
l 题目1:应用场景,之前定时器经常要进行备份,现在有箭头函数就不需要备份了:
var obj = {
a : 10,
fn: function(){
setInterval(()=>{
console.log(this.a)
},1000)
}
} obj.fn()
红色这个函数的上下文是obj,此时箭头函数的上下文就继承自obj对象,而不是window。
l 题目2:fun函数里面有一个箭头函数,并且箭头函数执行了
function fun(){
const fn = ()=>{
console.log(this.a)
}
fn();
}
var laowang = {
a : ,
fun : fun
}
laowang.fun();
因为fun函数是laowang打点调用的,所以fun函数的上下文是laowang,此时箭头函数的上下文就是laowang
因为箭头函数的上下文,是箭头函数定义时,所在函数的上下文。
l 相等于在外部备份了一次this:
function fun(){
var self = this;
const fn = function(){
console.log(self.a)
}
fn();
}
var laowang = {
a : 666,
fun : fun
}
laowang.fun();
l 题目3:
var obj = {
say : function(){
var f1 = ()=>{
console.log(this); //obj
setTimeout(()=>{
console.log(this); //obj
})
}
f1();
}
} obj.say();
因为f1定义是所处的函数中的this指向obj,setTimeout的箭头函数this继承自f1,所以不管有多少层嵌套都是obj。
题目3的延伸:
var obj = {
say : function(){
var f1 = function(){
console.log(this); //window
setTimeout(()=>{
console.log(this); //window
})
}
f1();
}
} obj.say();
结果:window,因为箭头函数在定义的时候它所处的环境相当于window,所以在箭头函数内部的this就是window(node环境没有window,可以在浏览器执行)
也就是说,箭头函数的上下文取决于如何被定义,而不是如何被调用,正好和之前普通function相反。
进一步说,箭头函数上下文不能被改变。
题目4:
function fun(){
const fn = ()=>{
console.log(this.a)
}
const xiaohua = {
a : 9999999
} fn.call(xiaohua); //call和apply都不能改变箭头函数的上下文
}
var laowang = {
a : 666,
fun : fun
}
laowang.fun();
输出还是laowang的a,就是666,箭头函数上下文终身不能改。
箭头函数不能被call、apply
function还没有下岗
如果需要一个可变的上下文函数,用function
如果需要一个自动备份外部上下文的函数,用箭头函数
4.5 bind()绑定上下文
只有function能被bind(),箭头函数不能被bind()
一个函数如果被bind()指向了某个对象,此时这个函数上下文将终身绑定到这个对象,永不改变,call、apply都没有改变。
注意:bind()只绑定上下文,但不会执行函数,和call、apply不太一样
function fun(){
console.log(this.a);
} var laowang = {
a : 666
} var xiaozhang = {
a : 8888
} fun = fun.bind(laowang); //fun函数的上下文终身在是laowang
fun(); //即使圆括号调用fun函数,也是laowang fun.call(xiaozhang); //call和apply也不能改变,还是laowang
fun.apply(xiaozhang);
fun = fun.bind(xiaozhang); //再次bind也无效,还是laowang
setInterval(fun,1000); //定时器也不能改变它
只要写一遍bind(),没有任何方法可以改变函数的this指向。
4.6双冒号运算符
箭头函数可以绑定this对象,大大减少了显式绑定this对象的写法(call、apply、bind)。但是,箭头函数并不适用于所有场合,所以现在有一个提案,提出了“函数绑定”(function bind)运算符,用来取代call、apply、bind调用。
函数绑定运算符是并排的两个冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。
foo::bar;
// 等同于
bar.bind(foo); foo::bar(...arguments);
// 等同于
bar.apply(foo, arguments);
4.7对象中函数的简化
var result = Object.keys(obj).map(item=>({
"label": item,
"children" : obj[zimu].map(pinpai=>({
"label" : pinpai.brand ,
"children": pinpai.series.map(chexi=>({
"label" : chexi
}))
}))
}));
var obj = {
a : 100,
fun : function(){
console.log(this.a);
}
}
等价于:
var obj = {
a : 100,
fun(){
console.log(this.a);
}
}
obj.fun();
不等于:
var obj = {
a : 100,
fun:()=>{
console.log(this.a);
}
}
obj.fun();
4.8 babel翻译它们
翻译前 |
翻译后 |
箭头函数就是自动备份了this。
练习:下面有一个对象,不改变原来的对象,创建新的obj2对象,将id为2那个车主的地区变为“中国”。
var obj1 = {
"nowshow": 8,
"nowType":"All",
"dataArr":[
{
"id":1,
"brand":"奔驰",
"price":50,
"saler":{
"name":"王尼玛",
"provice":"德国"
}
},
{
"id":2,
"brand":"宝马",
"price":20,
"saler":{
"name":"李全蛋",
"provice":"韩国"
}
}
]
};
练习
var obj2 = {
...obj1,
"dataArr":obj1.dataArr.map((item)=>{
if(item.id == 2){
return {
...item,
saler:{
...item.saler,
provice:"中国"
}
}
} return item;
})
}
console.log(JSON.stringify(obj2))
答案
五、类(构造函数)
5.1 ES6类的新写法
原来定义一个类,是用构造函数,用new调用。
function People(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
People.prototype.sayHello = function(){
console.log(`我是${this.name}`);
}
People.prototype.singsing = function(){
console.log(`${this.name}在唱歌`);
} var xiaoming = new People("小明",12,"男");
var xiaohong = new People("小红",12,"女");
xiaoming.sayHello();
xiaohong.sayHello();
ES6中引入新的关键字class用来定义类,所有类的属性都要写在constructor()构造函数中,所有类的方法要一个个罗列在class花括号中。
class People {
constructor(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
} sayHello(){
console.log(`我是${this.name}`);
} sing(){
console.log(`${this.name}在唱歌`);
}
} var xiaoming = new People("小明",12,"男");
var xiaohong = new People("小红",12,"女");
xiaoming.sayHello();
xiaohong.sing();
虽然写在有了class关键字,可以更优雅的定义类,但原理没有任何变化。
程序中没有出现prototype,但方法还是在它身上。
5.2 ES6继承新写法
//人类
function People(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
} People.prototype.sayHello = function(){
console.log(`我是${this.name}`);
} //学生类
function Student(name,age,sex,xuehao,banji){
// this.name = name;
// this.age = age;
// this.sex = sex;
People.apply(this, arguments); //继承人类的属性
this.xuehao = xuehao;
this.banji = banji;
} //下面一条语句即可继承People类,改变prototype的指向
Student.prototype = new People(); Student.prototype.kaoshi = function(){
console.log(`${this.name},改打游戏啦,别学习了`);
} var xiaoming = new Student("小明",12,"男",10001, 08);
xiaoming.sayHello();
xiaoming.kaoshi();
ES6引入了新的关键字extends,表示继承
在子类的构造函数中,必须写super()调用超类(父类)的构造函数。
//学生类
class People {
//构造函数
constructor(name,age,sex){
this.name = name;
this.age = age;
this.sex = sex;
}
sayHello(){
console.log(`我是${this.name}`);
}
sing(){
console.log(`${this.name}在唱歌`);
}
} //学生类
class Student extends People{
//构造函数
constructor(name,age,sex,xuehao,banji){
super(name,age,sex)
this.xuehao = xuehao;
this.banji = banji;
} kaoshi(){
console.log(`我是${this.name},在考试`);
}
} var xiaoming = new Student("小明",12,"男",10001, 08);
xiaoming.sayHello();
xiaoming.kaoshi();
babel如何翻译class
babel会将class的写法翻译为原来的function和prototype的写法。
前端笔记之ES678&Webpack&Babel(中)对象|字符串|数组的扩展&函数新特性&类的更多相关文章
- 前端笔记之ES678&Webpack&Babel(下)AMD|CMD规范&模块&webpack&Promise对象&Generator函数
一.AMD和CMD规范(了解) 1.1传统的前端开发多个js文件的关系 yuan.js中定义了一个函数 function mianji(r){ return 3.14 * r * r } main.j ...
- 前端笔记之ES678&Webpack&Babel(上)初识ES678&Babel&let和const&解构&语法
一.ES版本简介和调试运行方法 1.1 ECMAScript简介 MDN手册:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript JavaS ...
- php中对象转数组有哪些方法(总结测试)
php中对象转数组有哪些方法(总结测试) 一.总结 一句话总结:json_decode(json_encode($array),true)和array强制转换(或带递归) 1.array方式强制转换对 ...
- 简单理解ECMAScript2015中的箭头函数新特性
箭头函数(Arrow functions),是ECMAScript2015中新加的特性,它的产生,主要有以下两个原因:一是使得函数表达式(匿名函数)有更简洁的语法,二是它拥有词法作用域的this值,也 ...
- matlab中的字符串数组与函数调用
1, matlab中的字符串就是1维字符数组,即如: a = 'dddssd'; b = 'lsde'; c = [a, b]; 当然也可以: c= strcat(a, b); 2, matlab中的 ...
- 【广州.NET社区推荐】【译】Visual Studio 2019 中 WPF & UWP 的 XAML 开发工具新特性
原文 | Dmitry 翻译 | 郑子铭 自Visual Studio 2019推出以来,我们为使用WPF或UWP桌面应用程序的XAML开发人员发布了许多新功能.在本周的 Visual Studio ...
- 前端笔记之服务器&Ajax(中)MySQL基础操作&PHP操作数据库&Ajax
一.数据库基础 1.1什么是数据库? 什么是数据库? 答:就是一个很大的一个文件,只不过这个文件可以通过一些‘命令’操作数据: 增.删.改.查数据: 数据库等于持久数据和数据操作的一个统称. 数据库是 ...
- JS中对象与数组(大括号{}与中括号[])
一.{ } 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或是函数. 如:var LangShen = {"Name":"Langshen",&qu ...
- javascript中对象和数组的异同点
一.JS声明对象或数组 JS对象:{ } JS数组:[ ] 对象 var b={m:'123',n:'abc'};alert(b.m);alert(b.n); 一维数组 var a=[1,2,3];a ...
随机推荐
- mongodb的安装使用,window和centos环境
官网:https://www.mongodb.org/downloads 版本:最终稳定版 (mongodb-win32-x86_64-2008plus-ssl-3.2.6-signed.msi 绿色 ...
- python 编码形式简单入门
为什么使用Python 假设我们有这么一项任务:简单测试局域网中的电脑是否连通.这些电脑的ip范围从192.168.0.101到192.168.0.200. 思路:用shell编程.(Linux通常是 ...
- 5月2日——iOS11定位失效问题
所存在的问题: (1)定位不能正常使用 (2)首次安装APP 时 "是否允许使用定位信息" 系统提示框不显示 iOS定位失效原因: 因为苹果现在增加了一项新的隐私保护功能 NSL ...
- Python_异常处理结构与调试
while True: x =input('Pleaes input:') try: x=int(x) print('You have input {0}'.format(x)) break exce ...
- 什么是web service ?
一.序言 大家或多或少都听过WebService(Web服务),有一段时间很多计算机期刊.书籍和网站都大肆的提及和宣传WebService技术,其中不乏很多吹嘘和做广告的成分.但是不得不承认的是Web ...
- PAT1088:Rational Arithmetic
1088. Rational Arithmetic (20) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue F ...
- SpringMVC中利用@CrossOrigin注解解决ajax跨域请求的问题
1. 什么是跨域 跨域,即跨站HTTP请求(Cross-site HTTP request),指发起请求的资源所在域不同于请求指向资源所在域的HTTP请求. 2. 跨域的应用情景 当使用前后端分离,后 ...
- VirtualBox报错:不能为虚拟电脑XXX打开一个新任务
报错产生的背景 今天在这里下载了一个用于VirtualBox的Kali Linux虚拟机文件(使用VirtualBox可以直接打开使用,不用执行安装过程).但是将该文件导入到VirtualBox中之后 ...
- jennifersoft,phantomjs
http://jennifersoft.com/en/ Real Value of APM (Application Performance Monitoring) http://npm.taobao ...
- SwaggerUI--SosoApi
1.SwaggerUI是什么? Swagger UI是一款RESTFUL接口的文档在线自动生成+功能测试功能软件. Swagger-UI 的官方地址:http://swagger.io/ Github ...