JavaScript高级(ES6)
创建类
<script>
//创建类class,创建一个明星类
class star {
//类的共有属性放在constructor
constructor(uname,age){
this.uname = uname;
this.age = age;
}
//创建方法
sing(sing){
// console.log("唱歌");
console.log(this.uname + sing);
}
}
//利用类创建对象 new
var tkx = new star("谭坤新",22);
console.log(tkx);
tkx.sing("小跳蛙");
</script>
类的继承
<script>
//类的继承
// class Father{
// constructor(){
// }
// money(){
// console.log(100);
// }
// }
// class Son extends Father{
// }
// var son = new Son();
// son.money();
class Father{
constructor(x,y){
this.x = x;
this.y = y;
}
sum(){
console.log(this.x + this.y);
}
}
class Son extends Father{
constructor(x,y){
super(x,y);
}
}
var son = new Son(1,2);
son.sum();
</script>
<script>
class Father{
constructor(x,y){
this.x = x;
this.y = y;
}
sum(){
console.log(this.x+this.y);
}
}
class Son extends Father{
constructor(x,y){
super(x,y);
this.x = x;
this.y = y;
}
subtract(){
console.log(this.x-this.y);
}
}
var son = new Son(5,2);
son.sum();
son.subtract();
</script>
ES6注意点
- ES6中没有变量提升,必须先定义类,才能通过类实例化对象;
- 类里面的共有属性和方法一定要加this;
- 类里面的this指向问题;
- constructor里面的this指向实例对象,方法里面的this指向这个方法的调用者;
构造函数
原型prototype
- 实现方法共享;
对象原型
constructor构造函数
构造函数、实例、原型对象三者关系
原型链
js成员查找规则
call()
function fn(x, y) {
console.log('我想喝手磨咖啡');
console.log(this);
console.log(x + y);
}
var o = {
name: 'andy'
};
fn.call(o, 1, 2);
- 改变this指向;
改变this指向方法
call() | apply() | bind() |
---|---|---|
第一个参数指向的地方,后面传多个参数,以逗号分隔,会立即执行这个函数 | 第一个参数指向的地方,后面传入一个数组,多个参数放在数组里,会立即执行这个函数 | 第一个参数指向的地方,后面传多个参数,以逗号分隔 |
add.bind(o,a, b); //不执行函数,只改变this指向,传参
add.bind(o,a, b)();//改变this指向,传参同时执行函数
借用原型对象继承方法
<script>
// 借用父构造函数继承属性
// 1. 父构造函数
function Father(uname, age) {
// this 指向父构造函数的对象实例
this.uname = uname;
this.age = age;
}
Father.prototype.money = function() {
console.log(100000);
};
// 2 .子构造函数
function Son(uname, age, score) {
// this 指向子构造函数的对象实例
Father.call(this, uname, age);
this.score = score;
}
// Son.prototype = Father.prototype; 这样直接赋值会有问题,如果修改了子原型对象,父原型对象也会跟着一起变化
Son.prototype = new Father();
// 如果利用对象的形式修改了原型对象,别忘了利用constructor 指回原来的构造函数
Son.prototype.constructor = Son;
// 这个是子构造函数专门的方法
Son.prototype.exam = function() {
console.log('孩子要考试');
}
var son = new Son('刘德华', 18, 100);
console.log(son);
console.log(Father.prototype);
console.log(Son.prototype.constructor);
</script>
foreach()
<script>
// forEach 迭代(遍历) 数组
var arr = [1, 2, 3];
var sum = 0;
arr.forEach(function(value, index, array) {
console.log('每个数组元素' + value);
console.log('每个数组元素的索引号' + index);
console.log('数组本身' + array);
sum += value;
})
console.log(sum);
</script>
filter()
<script>
// filter 筛选数组
var arr = [12, 66, 4, 88, 3, 7];
var newArr = arr.filter(function(value, index) {
// return value >= 20;
return value % 2 === 0;
});
console.log(newArr);
</script>
some()
<script>
// some 查找数组中是否有满足条件的元素
var arr1 = ['red', 'pink', 'blue'];
var flag1 = arr1.some(function(value) {
return value == 'pink';
});
console.log(flag1);
// 1. filter 也是查找满足条件的元素 返回的是一个数组 而且是把所有满足条件的元素返回回来
// 2. some 也是查找满足条件的元素是否存在 返回的是一个布尔值 如果查找到第一个满足条件的元素就终止循环
</script>
trim()
- 去除字符串两侧空格;
object.keys()
- 获取对象的所有的属性;
Object.defineProperty()
- 所有函数都是Fuction的实例;
严格模式
- 变量必须先声明再使用;
- 不能随意删除定义好的变量;
- 全局作用域下this指向undefined;
- 构造函数中,不加new,this会报错;
- 函数里面的参数不允许重名;
高阶函数
- 对其他函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出;
闭包
- 闭包指有权访问另一个函数作用域中变量的函数,一个作用域可以访问另外一个函数内部的局部变量;
- 闭包延伸了变量的作用范围;
递归
- 如果一个函数在内部可以调用其自身,那么这个函数就是递归函数;
深拷贝与浅拷贝
- 浅拷贝:Object.assign();
<script>
// 浅拷贝只是拷贝一层, 更深层次对象级别的只拷贝引用.
// 深拷贝拷贝多层, 每一级别的数据都会拷贝.
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
}
};
var o = {};
// for (var k in obj) {
// // k 是属性名 obj[k] 属性值
// o[k] = obj[k];
// }
// console.log(o);
// o.msg.age = 20;
// console.log(obj);
console.log('--------------');
Object.assign(o, obj);
console.log(o);
o.msg.age = 20;
console.log(obj);
</script>
- 深拷贝:深拷贝拷贝多层, 每一级别的数据都会拷贝;
<script>
// 深拷贝拷贝多层, 每一级别的数据都会拷贝.
var obj = {
id: 1,
name: 'andy',
msg: {
age: 18
},
color: ['pink', 'red']
};
var o = {};
// 封装函数
function deepCopy(newobj, oldobj) {
for (var k in oldobj) {
// 判断我们的属性值属于那种数据类型
// 1. 获取属性值 oldobj[k]
var item = oldobj[k];
// 2. 判断这个值是否是数组
if (item instanceof Array) {
newobj[k] = [];
deepCopy(newobj[k], item)
} else if (item instanceof Object) {
// 3. 判断这个值是否是对象
newobj[k] = {};
deepCopy(newobj[k], item)
} else {
// 4. 属于简单数据类型
newobj[k] = item;
}
}
}
deepCopy(o, obj);
console.log(o);
var arr = [];
console.log(arr instanceof Object);
o.msg.age = 20;
console.log(obj);
</script>
正则表达式
- 用于匹配字符串中字符组合的模式,也是对象;
let
- let声明的变量只在所处于的块级有效;
- 使用let关键字声明的变量才具有块级作用域,使用var声明的变量不具备块级作用域特性;
- 防止循环变量变成全局变量;
- 不存在变量提升;
- 暂时性死区;
const
- 声明常量,常量就是值(内存地址)不能变化的值;
- 具有块级作用域;
- 声明常量必须赋值;
- 常量赋值后,值不能修改,复杂数据类型数据结构内部的值可以更改,但数据值本身不能更改;
let、const、var区别
var | let | const |
---|---|---|
函数作用域 | 块级作用域 | 块级作用域 |
变量提升 | 不存在变量提升 | 不存在变量提升 |
值可更改 | 值可更改 | 值不可更改 |
解构赋值
- ES6中允许从数组中提取值,按照对应位置,对变量赋值,对象也可以实现解构;
- 数组解构;
<script>
//数组解构允许我们按照一一对应的关系从数组中提取值,然后将值赋值给变量
let [a,b,c,d] = [1,2,3];
console.log(a);
console.log(b);
console.log(c);
console.log(d); //未定义返回undefined
</script>
箭头函数
- () =>{} const fn = () =>{};
- 箭头函数是用来简化函数定义语法的;
- 在箭头函数中,如果函数体中只有一句代码并且代码的执行结果就是函数的返回值 函数体大括号可以省略;
- 如果形参只有一个,可以省略小括号;
- 箭头函数不绑定this 箭头函数没有自己的this关键字,如果在箭头函数中使用this,this关键字将指向箭头函数定义位置中的this;
剩余函数
<script>
const sum = (...args) => {
let totle = 0;
args.forEach(item =>totle +=item);
return totle
};
console.log(sum(10,20));
console.log(sum(10,20,30));
//剩余参数和结构配合使用
let ary1 = ['张三','李四','王五'];
let [s1,...s2] = ary1;
console.log(s1);
console.log(s2);
</script>
扩展运算符
- 扩展运算符可以将数组拆分成以逗号分隔的参数序列;
- 将伪数组转换成真正的数组 可调用数组的方法;
var oDivs = document.querySelectorAll('li');
console.log(oDivs);
var ary6 = [...oDivs];
ary6.push('a');
console.log(ary6);
Array.from()
let arrayLike = {
'0':1,
'1':2,
'length':2,
};
var ary4 = Array.from(arrayLike);
var ary5 = Array.from(arrayLike,item => item*2);
console.log(ary4);
console.log(ary5);
find()
<script>
var ary = [{
id: 1,
name: '张三'
}, {
id: 2,
name: '李四'
}];
let target = ary.find(item => item.id == 3);
console.log(target);
//查找不到返回undefined
</script>
findIndex()
<script type="text/javascript">
let ary = [10, 20, 50];
let index = ary.findIndex(item => item > 15);
console.log(index);
//查找第一个满足条件的返回元素索引,如果找不到,返回-1
</script>
includes
<script type="text/javascript">
let ary = ["a", "b", "c"];
let result = ary.includes('a')
console.log(result)
result = ary.includes('e')
console.log(result);
//表示某个数组是否包含给定的值,返回布尔值
</script>
模板字符串
<script>
//模板字符串
let name = `李泽言`;
let sayHello = `Hello,我的名字叫${name}`;
alert(sayHello);
//可以换行,显示比较好
let result = {
name: '李泽言',
age:22,
};
let html = `
<div>
<span>${result.name}</span>
<span>${result.age}</span>
</div>
`
console.log(html);
//可以调用函数
const fn = () => {
return '我说fn函数';
};
let fun = `我是模板字符串,${fn()}`;
console.log(fun);
</script>
startsWith方法和endsWith方法
<script type="text/javascript">
let str = 'Hello ECMAScript 2015';
let r1 = str.startsWith('Hello');
console.log(r1);
let r2 = str.endsWith('2016');
console.log(r2);
//返回布尔值
//startsWith 以...开始
//endsWith 以...结尾
</script>
repeat()
<script type="text/javascript">
console.log("y".repeat(5))
</script>
<!-- repeat方法 将原字符串重复n次 -->
set
<script>
const s1 = new Set();
console.log(s1.size);
const s2 = new Set(['a','b']);
console.log(s2.size);
//数组去重
const s3 = new Set(['a','b','a','b']);
console.log(s3.size);
const ary1 = [...s3];
console.log(ary1);
//实例方法
const s4 = new Set();
//添加值
s4.add('a').add('b');
console.log(s4.size);
//删除值 删除不存在的返回false
s4.delete('a');
const r1 = s4.delete('c');
console.log(s4.size);
console.log(r1);
//判断是否是set数据结构中的成员
const r2 = s4.has('a');
console.log(r2);
//清空set数据结构中的值
s4.clear();
console.log(s4.size);
//对每个成员执行某种操作,没有返回值
const s5 = new Set(['a','b','c']);
s5.forEach( value => {
console.log(value);
});
</script>