参考视频:2019全新javaScript进阶面向对象ES6
参考文档:ES6入门教程
let
参考文档:JavaScript Let
let
用途:代替var
作为局部变量
let与var
比较 | var | let |
---|---|---|
作用域 | 函数内为局部,其余为全局(包括for) | 块级{ } |
变量提升 | 声明提升到开头 | 不提升 |
允许同名 | 声明同名变量会覆盖 | 同一块内不允许同名 |
从属 | window | 不属于window |
面试题
- 1:输出结果
var arr = [];
for(var i = 0; i < 2; i++) {
arr[i] = function(){
console.log(i);
}
}
arr[0](); //2
arr[1](); //2
var arr = [];
for(let i = 0; i < 2; i++) {
arr[i] = function(){
console.log(i);
}
}
arr[0](); //0
arr[1](); //1
函数执行时输出的是自己上一级(循环块作用域)下的i值。
const
参考文档:JavaScript Const
const
用途:声明常量
const与var
和let相同,唯一区别是不可更改。
比较 | var | const、let |
---|---|---|
作用域 | 函数内为局部,其余为全局(包括for) | 块级{ } |
变量提升 | 声明提升到开头 | 不提升 |
允许同名 | 声明同名变量会覆盖 | 同一块内不允许同名 |
从属 | window | 不属于window |
地址与值
- 初始化赋值
- 定义时赋初值:定义时必须赋初值,且以后不能再改
- 赋值性质:指针,指向一块内存区域的指针
- 地址与值
- 不可以修改:指向的位置(地址)
- 可以修改:指向区域的值(值)
- 可以修改的值
- 引用传递(数组、类等):可以修改
- 值传递(基本数据类型):不可修改
解构赋值
针对数组和对象,更便捷的取值方式。
数组解构
按照一一对应的关系从数组中提取值,赋值给变量。
- 先前写法:遍历取值
let arr = [1, 2, 3];
a = arr[0]; //1
b = arr[1]; //2
c = arr[2]; //3
- 数组解构:使用
[ ]
,变量顺序和数组顺序一一对应
let arr = [1, 2, 3];
let [a, b, c] = arr; //1 2 3
let [a, b, c] = [1, 2, 3]; //1 2 3
- 数组解构:缺失值处理为
undefined
let [a] = []; //a = undefined
let [b, c] = [1]; //b = 1 c = undefined
对象解构
- 先前写法:遍历取值
let person = {
name: 'my',
age: 20
};
let name = person.name; //name = 'my'
let age = person.age; //age = 20
- 对象解构:使用
{ }
,变量名称必须和属性一一对应
let person = {
name: 'my',
age: 20
};
let {name, age} = person; //name = 'my' age = 20
let {name, age} = {
name: 'my',
age: 20
}; //name = 'my' age = 20
- 对象解构:缺失值处理为
undefined
let {sex} = {}; //sex = undefined
let {name, age} = {name:'my'}; //age = undefined
- 对象解构:别名使用
:
let {name: myname, age: myage} = {
name: 'my',
age: 20
}; //myname = 'my' myage = 20
箭头函数
箭头函数用途:简化函数定义语法。
定义
- 格式
() => {}
( )
内为形参。
{ }
内为函数体
- 示例:
const
承接
const fn = (str) => {
console.log(str);
}
fn("hello"); //调用
- 示例:直接调用函数
(() => {console.log("world")}) (); //直接调用
省略:单句返回值
如果只有一行代码且为返回值,那么可以省略{ }
和return
。
- 不省略:
const sum = (a, b) => {return a + b};
- 省略:
const sum = (a, b) => a + b;
省略:单形参
如果只有一个形参,可以省略( )
。
- 不省略:
const sum = (a) => a + 2;
- 省略:
const sum = a => a + 2;
箭头函数中的this
不绑定this
,this
指向函数定义位置上下文的this
。
var obj = {in: "inobj"};
function fn(){
console.log(this); //输出函数内部this
return () => {console.log(this)}; //返回匿名箭头函数,输出this
}
fn()(); //1:window 2:window
fn.call(obj)(); //1:obj 2:obj
面试题
- 题目:输出结果
var obj = {
age: 20,
say: () => {
console.log(this.age);
}
}
obj.say(); //undefined
obj对象不产生作用域,此处this
指向window
。
- 修改
var obj = {
age: 20,
say: () => {
console.log(this.age);
}
}
var age = 10; //新增window.age
obj.say(); //10
- 修改
var obj = {
age: 20,
say: () => {
console.log(this); //输出当前this
}
}
obj.say(); //window
- 修改
var obj = {
age: 20,
say: () => {
console.log(this.obj.age); //修改
}
}
obj.say(); //20
剩余参数
不定数量的参数,可以表示为一个数组。
定义
- 形式:
...
function sum(...args){
let total = 0;
let len = args.length;
for(let i = 0; i < len; i++)
total += args[i];
return total;
};
console.log(sum(1, 2));
console.log(sum(1, 2, 3));
args
为一个数组,可以接受任意数量的参数。
- 优化:使用
const
承接函数
const sum = function(...args){
let total = 0;
let len = args.length;
for(let i = 0; i < len; i++)
total += args[i];
return total;
};
- 优化:使用
forEach
const sum = function(...args){
let total = 0;
args.forEach(function(value){
total += value;
})
return total;
};
- 优化:使用箭头函数定义回调函数
const sum = function(...args){
let total = 0;
args.forEach(value => {total += value});
return total;
};
- 优化:使用箭头函数定义整体函数
const sum = (...args) => {
let total = 0;
args.forEach(value => {total += value});
return total;
};
注意在箭头函数内使用剩余参数...
时,参数必须加( )
。
- 剩余参数和普通参数结合使用
const sum = (a, b, ...args) => {
let total = a + b;
args.forEach(value => {total += value});
return total;
};
2个以上参数的求和函数
使用剩余参数来解构
let arr = [1, 2, 3];
let [a, ...s] = arr;
console.log(a); //1
console.log(s); //[2, 3]
let arr = [1, 2, 3];
let [...s] = arr;
console.log(s); //[1, 2, 3]
Array扩展方法
…参数序列
将数组或者对象转为参数序列,以,
分隔。
let arr = [1, 2, 3]; //...arr的值为1, 2, 3
//等价
console.log(...arr); //1 2 3
console.log(1, 2, 3); //1 2 3
应用:合并数组
let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];
//方法1:创建新数组
let arr3 = [...arr1, ...arr2];
//方法2:使用push()直接在原数组添加
arr1.push(...arr2); //push可以有多个参数
参数序列的本质是,
分隔开的数组,外面加一个[ ]
也就成了真正的数组。
应用:将伪数组转化为真正的数组
<body>
<div></div>
<div></div>
<div></div>
<script>
let divs = document.getElementsByTagName('div');
console.log(divs); //HTMLCollection
divs = [...divs];
console.log(divs); //Array
</script>
</body>
Array.from()
将类数组或可遍历对象,转化为真正的数组。
- 转化数组
let obj = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
let arr = Array.from(obj); //['a', 'b', 'c']
let obj = {
'0': 'a',
'1': 'b',
'3': 'c',
length: 4
};
let arr = Array.from(obj); //['a', 'b', undefined, 'c']
对于索引和长度敏感。
- 可选参数2:回调函数
let obj = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
//方法1:回调函数
let arr1 = Array.from(obj, function(value){ return value + 'k'}); //['ak', 'bk', 'ck']
//方法2:箭头函数写回调函数
let arr2 = Array.from(obj, item => item + 'k'); //['ak', 'bk', 'ck']
数组实例.find()
找出第一个符合条件的成员并返回,否则返回undefined
。
- 参数为回调函数,类似
Array.some()
let obj1 = {id: 1, name: "obj1"};
let obj2 = {id: 2, name: "obj2"};
let arr = [obj1, obj2];
let target1 = arr.find(function(value) {
if(value.id == 2)
return true;
}); //obj2
let target2 = arr.find(function(value) {
if(value.id == 3)
return true;
}); //undefined
数组实例.find()
成功时返回目标,失败时返回undefined
。
数组实例.some()
成功时返回true
,失败时返回false
。
- 回调函数用箭头函数优化
let obj1 = {id: 1, name: "obj1"};
let obj2 = {id: 2, name: "obj2"};
let arr = [obj1, obj2];
let target = arr.find(value => value.id == 2); //obj2
数组实例.findIndex()
同find()
,成功时返回第一个索引,失败返回-1
.
数组实例.includes()
是否包含某个值,返回true
和false
。
- 判定条件和返回值类似
数组实例.some()
。
let arr = [1, 2, 3];
arr.includes(2); //true
arr.includes(4); //false
参数不同,数组实例.some()
参数是回调函数,数组实例.includes()
参数是目标值。
比较:find()、findIndex()、includes()、 some()
方法 | find() | findIndex() | includes() | some() |
---|---|---|---|---|
从属 | 实例对象 | 实例对象 | 实例对象 | Array |
参数 | 回调函数 | 回调函数 | 目标值 | 回调函数 |
返回值 | 对象、undefined | 索引、-1 | 布尔值 | 布尔值 |
String扩展方法
模板字符串``
- 定义:反引号
let str = `mystr`;
关于反引号
- 位置:TAB的上面 1的左面 ESC的下面
- 输入:英文状态
- 优点:可以换行
let str = "
mystr
"; //语法错误
let str = `
mystr
`; //语法允许
- 解析变量:使用
${ }
- 基本类型:使用值
let str = `mystr`;
let name = `it is ${str}`); //it is mystr
先前方法是使用字符串拼接(concat()
或+
)。
- 函数:使用返回值,用
( )
调用函数
const fn = str => `hello ${str}`;
let name = `it is ${fn("world")}`; //it is hello world
实例对象.repeat()
将字符串重复多次,取决于参数。
let str = "s".repeat(3); //"sss"
实例对象.startsWith()、endsWith()
实例对象.startsWith()
判断是否以参数开头。
实例对象.endsWith()
判断是否以参数结尾。
let str = "hello world";
str.startsWith("hello"); //true
str.endsWith("world"); //true
参数是字符串,返回布尔值。
实例对象.padStart()、padEnd()
- 原型
String.prototype.padStart(maxLength, fillString = '') //头部填充
String.prototype.padEnd(maxLength, fillString = '') //尾部填充
- 使用
let str = "s";
let str1 = str.padStart(5, "#"); // ####s
let str2 = str.padEnd(5, "#"); //s####
常见应用场景:时间个位数用0填充
Set
集合,数据结构之一。没有重复值。
定义
const s1 = new Set(); //集合:空
const s2 = new Set([1, 2]); //集合:1, 2
const s3 = new Set([1, 2, 2]); //集合:1, 2 //去重
基本用法
const s = new Set([1, 2, 2]);
//特殊用法
let arr = [...s]; //转化为数组
//属性
let len = s.size; //长度
//方法
s.add(3); //添加
s.add(4).add(5);
let flag = s.delete(1); //删除,返回布尔表示是否删除成功
let tag = s.has(1); //是否含有值,返回布尔
s.clear(); //清空
遍历:使用forEach()
const s = new Set([1, 2, 2]);
s.forEach(item => console.log(item));