JS学习笔记
一. 基础部分
1. 数组
- 数组中可以包含不同类型的元素,如var job=[“你好”,24]。
- 字符串中的元素不可以通过索引(如“nihao”[3]=“n”)更改,但是数组可以。
- 通过push(item,,,)方法往数组最后添加一个或多个元素,如push(“你好”,24),对于二维数组还有push([“niha”,786])等操作 。通过unshift(item,,,)方法往数组头部添加一个或多个元素,如unshift(“你好”,24),对于二维数组还有unshift([“niha”,786])等操作
- 通过pop()弹出数组中最后一个元素,通过.shift()弹出数组中第一个元素。
- 处理数组元素
let johnDoe = ["John", "Doe", "Iskolo"]
let [firstName, lastName] = johnDoe
console.log(firstName, lastName) // John Doe
let johnDoe = ["John", "Doe", "Iskolo"]
let [, lastName, title] = johnDoe
console.log(lastName, title) // Doe Iskolo
我们同样可以使用rest operator
let [firstName, ...others] = "John Doe Iskolo".split(" ")
console.log(firstName, others) // John Iskolo
- 使用for…of…语法遍历数组中的元素
let obj = {
firstName : "John",
lastName : "Doe",
title : "Iskolo"
}
for(let [key, value] of Object.entries(obj)) {
console.log(`${key} : ${value}`)
}
- 使用array.splice(int1,int2)函数删除int1索引 处开始的int2个数组元素,并返回被删除的元素组成的新数组。
let array = ['I', 'am', 'feeling', 'really', 'happy'];
let newArray = array.splice(3, 2); //array==["i","an","feeling"]
// newArray equals ['really', 'happy']
当欲返回包含数组最后一个元素的子数组时,可”越界访问“:
let arr= [12,"g","f","j"];
let arr_2 = arr.slice(2,4); //返回arr中索引为2,3的所有元素
- 使用array.splice(int1,int2,elem1,elem2…)方法,替换array数组中从int1索引开始的int2个元素为elem1,elem2…,并返回被替代掉的元素集合。
let arr=['DarkGoldenRod', 'WhiteSmoke', 'LavenderBlush', 'PaleTurqoise', 'FireBrick'].splice(0,2,'DarkSalmon','BlanchedAlmond') //["DarkSalmon", "BlanchedAlmond", "LavenderBlush", "PaleTurqoise", "FireBrick"]
//arr等于.['DarkGoldenRod', 'WhiteSmoke']
可使用这个方法向数组中指定位置增加元素
let arr1=[1,2,3]
let arr2=[4,5,6]
for (let i = 0; i < arr1.length; i++) {
arr2.splice(1, 0, arr1[i]);
}
console.log(arr2) //[4,3,2,1,5,6]
- 使用array.slice(int1,int2)函数,将array中从int1索引开始到int2(不包括int2)索引结束之间的元素复制成一个新数组并返回。
let weatherConditions = ['rain', 'snow', 'sleet', 'hail', 'clear'];
let todaysWeather = weatherConditions.slice(1, 3);
// todaysWeather equals ['snow', 'sleet'];
// weatherConditions still equals ['rain', 'snow', 'sleet', 'hail', 'clear']
- 使用展开操作(Spread Operator)(…),代替展开一个数组中的所有元素:
let thisArray = [true, true, undefined, false, null];
let thatArray = [...thisArray];
// thatArray equals [true, true, undefined, false, null]
// thisArray remains unchanged, and is identical to thatArray
- 使用array.indexOf(elem)方法检验elem是否存在于array之中,如果存在,返回其实际索引,如果不存在,则返回-1.
let fruits = ['apples', 'pears', 'oranges', 'peaches', 'pears'];
fruits.indexOf('dates') // returns -1
fruits.indexOf('oranges') // returns 2
fruits.indexOf('pears') // returns 1, the first index at which the element exists
注意:JS中数组的长度是会随元素的缺获进行加减的。在使用for循环中这点需要注意,即arr.length是可变的,例如:欲输出[1,2,3,3,4,5,6]这个数组中,除却3的其他数:
正确:
let arr = [1,2,3,3,4,5,6];
for(let i =0;i<arr.length;i++){
if(arr[i]==3){
arr.splice(i,1);
i--;
}
}
for(var i=0;i<arr.length;i++) console.log(arr[i]) //1,2,4,5,6
错误:(i–;)
let arr = [1,2,3,3,4,5,6];
for(let i =0;i<arr.length;i++){
if(arr[i]==3){
arr.splice(i,1);
}
}
for(var i=0;i<arr.length;i++) console.log(arr[i]) //1,2,3,4,5,6
- 使用array.join()方法连接array中的元素成一个字符串并返回,当join()中无参数时,各元素之间以逗号连接并返回,当join中参数为一字符串时,各元素之间以该字符串相连。
var elements = ['Fire', 'Air', 'Water'];
console.log(elements.join());
// expected output: "Fire,Air,Water"
console.log(elements.join(''));
// expected output: "FireAirWater"
console.log(elements.join('---'));
// expected output: "Fire--Air--Water"
- 使用array.reverse()函数返回array被反转之后的数组,注意,运行该函数之后,原函数也会被反转:
var array1 = ['one', 'two', 'three'];
console.log('array1: ', array1);
// expected output: Array ['one', 'two', 'three']
var reversed = array1.reverse();
console.log('reversed: ', reversed);
// expected output: Array ['three', 'two', 'one']
/* Careful: reverse is destructive. It also changes
the original array */
console.log('array1: ', array1);
// expected output: Array ['three', 'two', 'one']
- 使用String.split(string1)方法将字符串String以string1为间隔拆分成数组,并返回该数组。
var str = 'The quick brown fox jumps over the lazy dog.';
var words = str.split(' ');
console.log(words[3]);
// expected output: "fox"
var chars = str.split('');
console.log(chars[8]); //即每遇到一个字符就进行一次拆分
// expected output: "k"
var strCopy = str.split();
console.log(strCopy);
// expected output: Array ["The quick brown fox jumps over the lazy dog."]
- 使用string.endsWith()方法判断String是否以某个特定字符串结尾
1.string.endsWith(string1) 判断字符串是否以String1结尾
2.string.endsWith(string1,int) 判断字符串是否在第int个字符处以string1结尾
const str1 = 'Cats are the best21!'; //一共20个字符
console.log(str1.endsWith('best21', 19));
// expected output: true
const str2 = 'Is this a question';
console.log(str2.endsWith('?'));
// expected output: false
-
使用string.length获取字符串长度
-
使用array.filter(function)方法筛选array中的元素,如果function(array[i])返回true,则返回true,最后返回所有运算结果为true的元素组成的数组
var students = [
{ name: 'Quincy', grade: 96 },
{ name: 'Jason', grade: 84 },
{ name: 'Alexis', grade: 100 },
{ name: 'Sam', grade: 65 },
{ name: 'Katie', grade: 90 }
];
var studentGrades = students.filter(function (student) {
return student.grade >= 90;
});
return studentGrades; // [ { name: 'Quincy', grade: 96 }, { name: 'Alexis', grade: 100 }, { name: 'Katie', grade: 90 } ]
或者
var students = [
{ name: 'Quincy', grade: 96 },
{ name: 'Jason', grade: 84 },
{ name: 'Alexis', grade: 100 },
{ name: 'Sam', grade: 65 },
{ name: 'Katie', grade: 90 }
];
var studentGrades = students.filter(student => student.grade >= 90);
return studentGrades; // [ { name: 'Quincy', grade: 96 }, { name: 'Alexis', grade: 100 }, { name: 'Katie', grade: 90 } ]
使用array.fliter(Boolean)返回删除array中的所有”假值“(false、null、0、""、undefined 和 NaN)之后的新数组
有关Boolean:Boolean 对象如果逻辑对象无初始值或者其值为 0、-0、null、""、false、undefined 或者NaN,那么对象的值为 false。
否则,其值为 true(即使当自变量为字符串 “false” 时)!
下面的所有的代码行均会创建初始值为 false 的 Boolean 对象。
var myBoolean=new Boolean();
var myBoolean=new Boolean(0);
var myBoolean=new Boolean(null);
var myBoolean=new Boolean("");
var myBoolean=new Boolean(false);
var myBoolean=new Boolean(NaN);
18.使用array.sort(function)给数组元素排序(如果忽略function参数,函数默认按照首字符哈希值或unicode值进行排序),并返回排序之后的数组(原数组也会被排序)。
var fruit = ['cherries', 'apples', 'bananas'];
fruit.sort(); // ['apples', 'bananas', 'cherries']
var scores = [1, 10, 2, 21];
scores.sort(); // [1, 10, 2, 21]
// Watch out that 10 comes before 2,
// because '10' comes before '2' in Unicode code point order.
var things = ['word', 'Word', '1 Word', '2 Words'];
things.sort(); // ['1 Word', '2 Words', 'Word', 'word']
// In Unicode, numbers come before upper case letters,
// which come before lower case letters.
//or
let arr=[7,9,32,3,2,4]
arr.sort(function(a, b) {
return a - b;
});
//arr =[2,3,4,7,9,32]
2. function
- 通过如下方式定义方法
function functionName() {
console.log("Hello World");
}
- 如同一个数组中可以定义不同种类的元素,定义一个带参方法时,不需要指明参数的类型,如
function testFun(param1, param2) {
console.log(param1, param2);
}
testFun("Hello", "World");
- js中,如果使用了任何一个未被定义的变量,系统会自动在方法外自动定义一个全局的同名变量。通常情况下,不建议这么做,这可能会导致难以发现的不必要错误
- 如果同时定义了两个同名的全局变量,和myFun内的局部变量someVar,则,myFun中引用该变量时,遵循就近原则,即实际引用的是方法内的变量,如:
var someVar = "Hat";
function myFun() {
var someVar = "Head";
return someVar;
}
- 如下写法是合法的,但是返回值使无定义的
var sum = 0;
function addSum(num) {
sum = sum + num;
}
var returnedValue = addSum(3); // sum will be modified but returned value is undefined
- 带有默认参数的方法
function greeting(name = "Anonymous") {
return "Hello " + name;
}
console.log(greeting("John")); // Hello John
console.log(greeting()); // Hello Anonymous
当方法带有多个参数,而其中部分参数为有默认值时,注意(若传入不足个参数,传入的参数依此对应从左往右的形参,应设置最右边的参数带有默认值):
const increment = (function() {
"use strict";
return function increment(number, value=1) {
return number + value;
};
})();
console.log(increment(5)); // returns 6
3. if条件句
同Java大体类似
function test (myCondition) {
if (myCondition) {
return "It was true";
}
return "It was false";
}
test(true); // returns "It was true"
test(false); // returns "It was false"
不同点:
- “==”: 当两种不同数据类型的变量进行比较操作时,js会自动进行类型转换,如下:
1 == 1 // true
1 == 2 // false
1 == '1' // true
"3" == 3 // true
!==, >, <, >=, <= 也如此。
- "= = =“ : 严格比较,与 “= =”相对应,当被比较元素含有不同类型时,则返回false,如下:
3 === 3 // true
3 === '3' // false
1==true
返回true,1!="false"
返回true ,1=="true"
返回true(这点类似c语言),类推“!==”亦然。
4. Switch语句
代码段一
switch (num) {
case value1:
statement1;
break;
case value2:
statement2;
break;
...
default:
defaultStatement;
break;
}
代码段二
switch(val) {
case 1:
case 2:
case 3:
result = "1, 2, or 3";
break;
case 4:
result = "4 alone";
}
代码段3
function chainToSwitch(val) {
var answer = "";
switch(val){
case "bob":
answer = "Marley";
break;
case 42:
answer="The Answer";
break;
case 1:
answer = "There is no #1";
}
return answer;
}
- 同Java类似,只有碰到符合条件的case语句后,除非遇到break;语句,否则,将会一直执行下去。
- Java中Switch传值类型:byte,short,int,char ,JDK5以后可以是枚举 ,JDK7以后可以是String,不支持long、float、double、boolean四种基本类型。写其他类型时的错误提示:Only convertible int values, strings or enum variables are permitted。对于Js,
5. 对象的定义与使用
- 对象的定义
其中属性名称可以是变量名(name),字符串(“hello”),数字(3),etc…
- 示例代码1:
var cat = {
"name": "Whiskers",
"legs": 4,
"tails": 1,
"enemies": ["Water", "Dogs"]
};
- 示例代码2:
var anotherObject = {
make: "Ford",
5: "five",
"model": "focus"
};
注意各属性之间,采用“,”分隔,而属性名称,与属性值之间采用:连接。对象中的键默认是字符串类型的即Object.keys(anotherObject)[[0]===“make”,返回true。即在anotherObject[]中,[]中只能添加string的情况下,亦可有如下写法:
let users = {
Alan: {
age: 27,
online: false
},
Jeff: {
age: 32,
online: true
}
};
for(let user in users){
console.log(users[user].age); //27 32
}
2.属性的调用
对象属性有两种调用方法,
1)通过“.”+"属性名称"调用,如:
var myObj = {
prop1: "val1",
prop2: "val2"
};
var prop1val = myObj.prop1; // val1
var prop2val = myObj.prop2; // val2
2)当属性名称中包含空格时,和数组类似,可通过”[]“调用,如:(注:[]中的属性名必须带双引号,或者单引号)
var myObj = {
"Space Name": "Kirk",
"More Space": "Spock",
"NoSpace": "USS Enterprise"
};
myObj["Space Name"]; // Kirk
myObj['More Space']; // Spock
myObj["NoSpace"]; // USS Enterprise
3)附加几种变态无聊的方法:
(1)
var someObj = {
propName: "John"
};
function propPrefix(str) {
var s = "prop";
return s + str;
}
var someProp = propPrefix("Name"); // someProp now holds the value 'propName'
console.log(someObj[someProp]); // "John"
(2)
var dogs = {
“Fido”: "Mutt",
Hunter: "Doberman",
Snoopie: "Beagle",
54: "bnjdhsv"
};
var myDog = "Hunter";
var finger= 54
var fido="Fido";
var myFido1=dogs.Fido;
var myFido2=dogs[fido];
var myFido3=dogs["Fido"]
var myFinger=dogs[finger];
var myBreed = dogs[myDog]; /*此处不能采用dogs.myDog的调用方法,因为myDog的值是
“Hunter”,不是Hunter,这样一来,调用就变成了dogs.“Hunter”,这是错误的,
同样如果采用dogs.finger的方法也是错误的(这就不知道为什么了)*/
console.log(myBreed); // "Doberman"
(3)嵌入对象的调用(真的皮):
var myStorage = {
"car": {
"inside": {
"glove box": "maps",
"passenger seat": "crumbs"
},
"outside": {
"trunk": "jack"
}
}
};
var gloveBoxContents = myStorage.car.inside["glove box"];
(4)检索数组中嵌入对象或者对象中嵌入数组元素的情况:
var ourPets = [
{
animalType: "cat",
names: [
"Meowzer",
"Fluffy",
"Kit-Cat"
]
},
{
animalType: "dog",
names: [
"Spot",
"Bowser",
"Frankie"
]
}
];
ourPets[0].names[1]; // "Fluffy"
ourPets[1].names[0]; // "Spot"
::就问你无不无聊!!
3. 可以通过和调用属性值一样的方法来给一个对象添加本不存在的新属性并赋值,如:
ourDog.bark = "bow-wow";
or
ourDog["bark"] = "bow-wow";
- 通过delete关键值删除属性:
delete ourDog.bark;
or
delete outDog["bark"];
- 使用object.hasOwnProperty(propname)关键字,确定对象有没有propname属性,有返回true,没有返回false。
var myObj = {
top: "hat",
bottom: "pants"
};
myObj.hasOwnProperty("top"); // true
myObj.hasOwnProperty("middle"); // false
//or
myObj.hasOwnProperty('top','bottom') //true
-
使用Object.keys(object)方法返回object对象中所有键组成的数组
-
获取对象成员数量
var obj = {
a:1,
b:2,
c:3
}
var length1 = Object.keys(obj).length
var length2=Object.getOwnPropertyNames(obj).length;
console.log(length1) //3
console.log(length2 ) //3
6.特殊方法
- 通过Math.random()生成[0-1)的随机小数。
- 生成随机整数:
生成0-19之间的整数:
var a=Math.floor( Math.random*20 ) //返回0-19之间的整数
生成min-max之间的整数:
Math.floor(Math.random() * (max - min + 1)) + min
- String转Int
- parseInt(String)
如果string中第一个字节不能被转换,则,返回nan;
var a = parseInt("007");
- parseInt(String,radix)实现将String当作radix进制的整数转化为十进制并返回:
var a = parseInt("11", 2); //a=3;
- Math.max(…arr) 返回arr数列中最大值,等同于Math.max(1,2,34,5,5)(注意:传入的实参不能是数组)
7.字符串
- 使用string.split()方法将字符串拆分成数组
- 使用array.join()方法将数组元素练成连成字符串并返回
- 使用string.replace(regex|substr,string1|func)方法将将符合条件的子字符串替换为其他字符串并返回替换后的字符串,注意源字符串不发生变化!
- 使用string.toUpperCase()(string.toLowerCase())方法返回将string中的字符全部大写(小写)后的字符串,原字符串不发生变化
let str = "abcDEF"
let str2=str.toLowerCase();
//str=“abcDEF”
//str2=“abcdef”
- 使用string.slice(int1,int2)返回字符串中int1个字符到int2个字符之间的字符串,当int是小数的时候,其表示从字符串末尾往字符串头部开始索引,使用string.slice(int)返回字符串中第int个索引直到末尾的子字符串。
var str = 'The quick brown fox jumps over the lazy dog.';
console.log(str.slice(31));
// expected output: "the lazy dog."
console.log(str.slice(4, 19));
// expected output: "quick brown fox"
console.log(str.slice(-4));
// expected output: "dog."
console.log(str.slice(-9, -5));
// expected output: "lazy"
- 字符串可以部分当作数组处理
"hello".length //5
"hello"[0] //h
"hello".slice(1,5) //ello
"hello".indexOf("l") //2
"hello".splice(1,3,"ghfj","fhd","fhjd") //error
.
.
.
7.使用string.endsWith()方法判断String是否以某个特定字符串结尾
- string.endsWith(string1) 判断字符串是否以String1结尾
- string.endsWith(string1,int) 判断字符串是否在第int个字符处以string1结尾
8. NaN
即非数值(not a number),是一个特殊的数值,用来表示一个本该返回数值的操作未返回数值,任何与NaN进行运算的操作都会返回NaN,NaN与自身不相等(并且NaN不与任何值相等)
NaN 属性是代表非数字值的特殊值。该属性用于指示某个值不是数字
NaN==NaN;
false
通过isNaN(element)判断element是否是非数值(true,false,”10“,10均是数值或者可以转化为数值)
alert(isNaN(NaN)); //true
alert(isNaN(20)); //false(20是一个数值)
alert(isNaN("10")); //false(可以被转换成数值10)
alert(isNaN("jjh")); //true(不能转换成数值)
alert(isNaN(true)); //false(可以被转换成数值1)
还可以通过与自生比较判断一个变量是否是NaN
NaN!==NaN //true
注意:
- myeclipse下tomcat目录D:\Myeclipse2017\plugins\com.genuitec.eclipse.server.embedded.tomcat.core_13.0.0.me201612211440\tomcat85\lib
二.ES6
ES6全名为ECMAScript 6 ,更新于2015年,是一个标准化的js版本,ES6版本更新了许多重要的特性如:
Arrow functions
Classes
Modules
Promises
Generators
let and const
等,但并非所有的浏览器都支持ES6,如果当前浏览器不支持,则应该
通过相应方法转化为ES5。
1. 严格模式*
JS5往后添加了一种新的运作模式,旨在消除js旧版本中的一些矛盾点,使得语言本身更严谨,安全,合理,目前,包括IE10在内的浏览器都已支持严格模式。同样的代码,在严格模式中将会有不同的运行结果,一些正常模式中可以运行的代码,在严格模式下将不能运行
<script>
"use strict";
console.log("这是严格模式。");
</script>
<script>
console.log("这是正常模式。");
</script>
case
- 严格模式下,不允许变量未声明直接调用
2.let 关键字.
- 当使用var关键字的时候,可以重复声明两个同名变量,如:
var camper = 'James';
var camper = 'David';
console.log(camper);
// logs 'David'
而使用let关键字的时候,不允许声明同名变量,如:
let camper = 'James';
let camper = 'David'; // throws an error
- 当用var声明变量时,其为全局变量,只有在方法体中用var声明变量时,才为局部变量。以下代码中,i为全局变量:
for (var i = 0; i < 3; i++) {
...
}
console.log(i);
// returns 3
改为let声明
'use strict';
let printNumTwo;
for (let i = 0; i < 3; i++) {
if (i === 2) {
printNumTwo = function() {
return i;
};
}
}
console.log(i);
// returns "i is not defined"
3. const关键字
与swift不同的是,let关键字声明的变量是可变的,而当需要声明只读变量时,需用到const关键字。
const关键字的属性与let关键字基本雷同
"use strict"
const FAV_PET = "Cats";
FAV_PET = "Dogs"; // returns error
使用const关键字定义数组,对象时,数组或者对象的内容仍是可变的,但是不允许被重定向。如:
"use strict";
const s = [5, 6, 7];
s = [1, 2, 3]; // throws error, trying to assign a const
s[2] = 45; // works just as it would with an array declared with var or let
console.log(s); // returns [5, 6, 45]
若要定义真正意义上不可更改的对象,可采用JS提供的Object.freeze方法,当企图给任何freeze操作之后的对象更改或者添加删除属性时,都会被拒绝,而不会报错!
let obj = {
name:"FreeCodeCamp",
review:"Awesome"
};
Object.freeze(obj);
obj.review = "bad"; //will be ignored. Mutation not allowed
obj.newProp = "Test"; // will be ignored. Mutation not allowed
console.log(obj);
// { name: "FreeCodeCamp", review:"Awesome"}
4.匿名函数
句法:
const myFunc = function() {
const myVar = "value";
return myVar;
}
ES6提供了 一个“语法糖”(syntactic sugar),以简化匿名函数的写法,你可以转而使用”箭头函数语法“ (arrow function syntax):
const myFunc = () => {
const myVar = "value";
return myVar;
}
当语法糖中没有方法体,而只有返回语句时,则可以省略书写return关键字和括号:
const myFunc = () => "value"
问:匿名函数能否使用var,let等关键字声明?
带参匿名函数的语法:const 函数名 = (参数1,…)=>{ };
// doubles input value and returns it
const doubler = (item) => item * 2;
let d = doubler(3);
箭头(或匿名)函数可以与map(),filter(),reduce()等以(其他处理数据集合的)函数作为参数的函数连用:
1
FBPosts.filter(function(post) {
return post.thumbnail !== null && post.shares > 100 && post.likes > 500;
})
2
FBPosts.filter((post) => post.thumbnail !== null && post.shares > 100 && post.likes > 500)
推荐使用第二种写法,更简洁。
arr.filter( function ) 根据function帅选出数组arr中的符合条件的元素,并组成一个新的数组如:
var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => word.length > 6);
console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]
arr.map(function) 根据function逐一处理数组arr中的元素,并返回新元素组成的数组:
var array1 = [1, 4, 9, 16];
// pass a function to map
const map1 = array1.map(x => x * 2);
console.log(map1);
// expected output: Array [2, 8, 18, 32]
5. (rest operator/spread operator.)剩余操作符/排列操作符
- 在方法参数名之前以“…”做前缀,在函数被调用时,该形参会成为一个数组,数组中的元素都是传递给该函数的多出来的实参的值。
function sum(a,b,...i){
console.log(args.length); // 传进来的参数的个数 3
let s = a + b;
if(args && args.length){
args.forEach(i => {s += i});
}
return s;
}
sum(1, 2, 3, 4, 5 ); // 传进来的参数的个数 3
其中第一个形参a对应的是1,第二个形参b对应的2,…args表示的就是[3, 4, 5]。
- 将一个数组中的元素添加进另一个新数组(连接数组):
var certsToAdd = ['a', 'b'];
var certifications = ['c', ...certsToAdd, 'd', 'e', 'f'];
console.log(certifications); //[a,b,c,d,e,f]
- 作为实参调用来方法,该方法中形参与实参中的数从左往右一一对应,如:
function addThreeNumbers(x, y, z) {
console.log(x+y+z) //x=0,y=1,z=2
}
var args = [0, 1, 2, 3];
addThreeNumbers(...args); //3
- 复制数组
var arr = [1, 2, 3];
var arr2 = [...arr]; // like arr.slice()
arr2.push(4);
console.log(arr); //[1,2,3]
console.log(arr2); //[1,2,3,4]
var [prehead, [head, ...sub],tail] = [0000,[1,2,3,4,5],6];
//or
let [a,...arg] = [1,2,3,4,5,6];
var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
//arr1.concat(arr2);
arr1 = [...arr1, "freeCodeCamp", ...arr2];
console.log(arr1); //[0, 1, 2, "freeCodeCamp", 3, 4, 5]
…arg这种写法只能作为最后的参数, 如果在…arg后面加别的参数会报错:
let [a,...arg,b] = [1,2,3,4,5,6]; //error!
- 剩余操作符只能用于函数形参/实参,或者是代替数组中的元素,以下代码将不起作用:
const spreaded = ...arr; // will throw a syntax error
问:为什么以下arr不是数列3,4,5,6…而是数组【3,4,5,6,7…】?
const [a, b, ...arr] = [1, 2, 3, 4, 5, 7];
console.log(a, b); // 1, 2
console.log(arr); // [3, 4, 5, 7]
6.解构语法(Destructuring Assignment)
ES6中的新语法,利用这种语法 ,可以实现快速复制和有选择的抽取对象中的元素并复制。如:
let [a,b,c] = [1,2,3];
console.log( a +"|"+ b +"|"+ c); //1|2|3
//or
const { x, y, z } = {x: 3.6, y: 7.4, z: 6.54 }; // x = 3.6, y = 7.4, z = 6.54
你甚至可以选择性的将x的值放入a,y的值放入b等,如:
const { x : a, y : b, z : c } = {x: 3.6, y: 7.4, z: 6.54 }; // a = 3.6, b = 7.4, c = 6.54
//or
const { x : a} = {x: 3.6, y: 7.4, z: 6.54 }; // a = 3.6
//or
const { z : c } = {x: 3.6, y: 7.4, z: 6.54 }; // c = 6.54
注意,如下代码的结果:即当对对象中的元素使用解构函数,而未对对象中的元素重命名时,对象中的元素名应与变量值一一对应:
const { a, b, x } = {x: 3.6, y: 7.4, z: 6.54 };
console.log(a+" "+x+" "+b); //undefined 3.6 undefined
//or
const { z, y, x } = {x: 3.6, y: 7.4, z: 6.54 }; //不管x,y,z如何排列,结果都是 x = 3.6, y = 7.4, z = 6.54
console.log(x+" "+y+" "+z);
字符串的解构
let [a,b,c,d,e ] = "abcde";
console.log(a+b+c+d+e); //abcde
解构嵌套数组
var [prehead, [head, ...sub],tail] = [0000,[1,2,3,4,5],6];
只要某种数据结构具有Iterator接口,都可以采用数组形式的解构赋值:参考:ES6新特性:利用解构赋值 (destructuring assignment), 简化代码
function* run() {
let a = 0;
while (true) {
yield a;
a++;
}
}
var [first, second, third, fourth, fifth, sixth] = run();
console.log(first+"_"+second+"_"+third+"_"+fourth+"_"+fifth+"_"+sixth);
使用解构语法读取嵌入对象的属性:
const a = {
start: { x: 5, y: 6},
end: { x: 6, y: -9 }
};
const { start : { x: startX, y: startY }} = a;
console.log(startX, startY); // 5, 6
解构数组,不同于解构对象的是,我们不能指定数组元素的值会被赋予哪个变量,即从左往右,数组中第一个值赋给啊,第二个值赋给b,,等。
const [a, b] = [1, 2, 3, 4, 5, 6];
console.log(a, b); // 1, 2
//or
const [a, b,,, c] = [1, 2, 3, 4, 5, 6];
console.log(a, b, c); // 1, 2, 5
解构方法中的形参
const profileUpdate = (profileData) => {
const { name, age, nationality, location } = profileData;
// do something with these variables
}
or
const profileUpdate = ({ name, age, nationality, location }) => {
/* do something with these fields */
}
7.模板字符串(Template Literals)和字符串插值(string interpolation)
两者都是ES6的新语法,通过模板字符串实现复杂字符串变量的创造
通过
` (注意不是单引号)
…
`
实现多行字符串变量的创建,通过${…}实现字符串插值:
const person = {
name: "Zodiac Hasbro",
age: 56
};
// Template literal with multi-line and string interpolation
const greeting = `Hello, my name is ${person.name}!
I am ${person.age} years old.`;
console.log(greeting); // prints
// Hello, my name is Zodiac Hasbro!
// I am 56 years old.
${…}也可以插入表达式:
${a + b}
8. 在ES6中用简略语法编写简洁的声明函数(shorthand syntax)
在ES5中
const person = {
name: "Taylor",
sayHello: function() {
return `Hello! My name is ${this.name}.`;
}
};
在ES6中(更简洁)
const person = {
name: "Taylor",
sayHello() {
return `Hello! My name is ${this.name}.`;
}
};
or
class Me{
constructor(name1){
this.eat(name1);
console.log(name1);
}
eat(name){
console.log(`${ name } is eating food`);
}
}
const m1 = new Me("章");
console.log("hello world");
9.类语法(class Syntax)
ES6提供的一种用于创造对象新语法,必须要说的是,类语法不同于java,python等语言的类,他并不是一种成熟的基于继承父类和泛型的实现
在ES5中,我们会定义一个方法,然后通过new 调用从而返回并声明一个对象
var SpaceShuttle = function(targetPlanet){
this.targetPlanet = targetPlanet;
}
var zeus = new SpaceShuttle('Jupiter');
类语法通过编写构造函数(constructor function )省略了方法的创建
class SpaceShuttle {
constructor(targetPlanet){
this.targetPlanet = targetPlanet;
}
}
const zeus = new SpaceShuttle('Jupiter');
10.私有方法
11.getter and setter
访问器属性不包含数据值,他们包含一对 getter 和setter, 不过这两个函数都不是必须的。在读取属性值时,会调用getter 函数,这个函数负责返回有效值;在写入属性值时,会调用seter函数并传入新值,这个函数负责决定如何处理数据。
通过getter和setter方法获得对象中的属性 (包括私有属性):
class Book {
constructor(author) {
this._author = author;
}
// getter
get writer(){
return this._author;
}
// setter
set writer(updatedAuthor){
this._author = updatedAuthor;
}
}
const lol = new Book('anonymous');
console.log(lol.writer); // anonymous
lol.writer = 'wut';
console.log(lol.writer); // wut
getter和setter是重要的,因为它隐藏了方法的实现细节。
Example:
function makeClass() {
"use strict";
class Thermostat{
constructor (temperature){
this.temperature=temperature;
}
set Thermostat(temperature){
this.temperature=temperature;
}
get Thermostat(){
return this.temperature;
}
}
return Thermostat;
}
const Thermostat = makeClass();
const thermos = new Thermostat(76); // setting in Fahrenheit scale
let temp = thermos.temperature; // 24.44 in C
thermos.temperature = 26;
temp = thermos.temperature; // 26 in C
12. import / require / export???
import
//or
import { function } from "file_path_goes_here"
// We can also import variables the same way!
export
const capitalizeString = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
}
export { capitalizeString } //How to export functions.
export const foo = "bar"; //How to export variables.
or
const capitalizeString = (string) => {
return string.charAt(0).toUpperCase() + string.slice(1);
}
const foo = "bar";
export { capitalizeString, foo }
导出全部文件
import * as myMathModule from "math_functions";
myMathModule.add(2,3);
myMathModule.subtract(5,3);
or
import * as object_with_name_of_your_choice from "file_path_goes_here"
object_with_name_of_your_choice.imported_function
默认导出(export default),每个文件只能有一个属性被默认导出,且默认导出不能与var, let, or const连用
export default function add(x,y) {
return x + y;
}
导入一个默认导出的文件(Import a Default Export),与正常的import不同的是,他不需要{}包围导入的属性,如下(假设默认导出的文件是math_functions):
import add from "math_functions";
add(5,4); //Will return 9