ES6的深入学习及使用

概念

javascript 是什么?

一门弱类型的脚本语言(高级编程语言)。简称JS

弱类型?

声明变量存储数据的语法比较自由,不是很严谨。

任何类型的数据(string/number/boolean/undefined/null...),都可以通过var关键字声明变量进行存储。

javascript
var a = "hello"
var b = 123;
var c = true;

强类型?例如java

int a ; boolean c;

ES6是什么

ECMAScript 6(简称ES6)是于2015年6月正式发布的JavaScript语言的标准,

正式名为 ECMAScript 2015(ES2015)。

简单点:ES6 就是javascript的第六个版本。(在2015之后发布的新增内容都在这个ES6)

为什么使用ES6?

ES6大部分浏览器都支持(ES5语法是所有浏览器都支持的)。 Babel 插件把ES6代码编译ES5代码

ES6的出现是为了弥补ES5的先天不足(变量、常量)。

目前市场上大多数的技术框架都是结合ES6语法或者typescript语法进行开发。(市场有需求)

ES6语法比较简约(箭头函数)、新增了许多实用的功能(数组API)。引入类的概念(面向对象的写法统一了)

//ES5 中不会报错 (变量重复声明,值可以随意修改)
var  a = "hello";
     a = 123;
var  a =  true;

VS

// ES6 语法比ES5要更加严谨、更加合理
const  a = "hello";
       a = 123; // 报错 
const a = true; // 错误

互联网编程语言的排行榜...

有哪些新特性

声明变量 (let)

ES5 使用var关键字 (比较自由)

ES6 使用let关键字 (比较严谨、合理)

有什么优点:

1、不允许变量声明提升(必须先声明后使用)

2、不允许重复声明变量

3、可以产生块级作用域 { 局部代码可执行环境 }

变量是什么?有什么作用?

变量是存储数据的容器(给数据起个名字)。主要用于存储数据、记录数据。

var a = 100;

实际上就是在内存中开辟小块空间名称叫做a, 用于存储数据100。

// ES5 
// 变量声明可以提升(名称提升了,但是值没有提升)
// console.log(a);// undefined 
// var a = 100;
// console.log(a);// 100
// 1) Uncaught ReferenceError: aaa is not defined
// console.log(aaa);// 内存中没有aaa这个变量,所有浏览器不能识别aaa,所以报错

// ES6
// 1) let 声明的变量,没有提升这个说法(必须先声明后引用,否则报引用类型错误)
// console.log(b);
let b = 100;
// console.log(b);// 100

// 2) 不允许变量重复声明,否则报错
// Uncaught SyntaxError: Identifier  报语法类型错误
// let b = 'hello';

// 3) 块级作用域 可以直接使用 { } 块级作用域;也可以是if语句、for语句、函数的大括号{}

// var index = 0;
// var index = 1;
// var index = 2;
// console.log(index);// 2
// for(var i = 0 ; i <= 10 ; i ++){
// }
// console.log(i);// 控制台输出的变量i是多少?11 ,因为var关键字声明的i是全局的,走出循环i++

// 有了块级作用域,甚至都不需要使用闭包了。
{
    let index = 0;
    console.log(index);// 0
}
{
    let index = 1;
    console.log(index);// 1
}
{
    let index = 2;
    console.log(index);// 2
}

// console.log(index);// 报错,因为全局环境下没有这个变量

for(let j = 0 ; j <= 10 ; j ++) {
    // let 会产生块级作用域,只能在 {} 中使用
    console.log(j);
}
// console.log(j);// 控制台输出的变量j是多少? 报错

声明常量 (const)

// 变量(值可以改变的)
let a = 100;
a = 99;
a = 98;

// 常量 (值是固定的,不能直接改变的)
const b = 100;
//  b = 99;
// 不能直接给常量赋值
// TypeError: Assignment to constant variable.
// 编写函数名称就可以使用常量
const login = function () { }

// 也有let关键字的特点1)不能声明提升 2)不能重复声明3)也有块级作用域
// 区别就是const声明的是常量,不允许重新赋值
const c = true;
//   c = false;//报错

// 面试题:
const arr = [100, 200, 300];
// 直接修改
// arr = ['red','green','blue'];// 报错

// 间接修改
arr[0] = 'red';
arr[1] = 'green';
arr[2] = 'blue';
console.log(arr);// 不报错,因为arr仍然是同一个引用地址,改变不过是引用地址里面的数据。
// 遇到数组、对象这些引用类型数据时,可以间接的通过索引值或者键值对修改引用地址里面的数据。

模板字符串

// 填充字符串(反单引号)
// ${变量} 把变量插入到模板中
ul.innerHTML = `
       <li>
            <p class="message">${text}</p>
        </li> 
`

解构赋值(数组、对象)

// 存储数据的方式,声明变量
// var a = 100;
// var b = 200;
// var c = 300;
// console.log(a,b,c);// 100 200 300

// 如果这些数据100 200 300 都是在数组中呢?在数组中如何取值
// 1) 可以通过索引值0 1 2进行取值
// var arr = [100,200,300];
// console.log(arr)
// console.log(arr[0]);// 100
// console.log(arr[1]);// 200
// console.log(arr[2]);// 300


// 解构:解剖结构
// 修饰关键字  变量 = 值 
// 隐式变量 = 值  (没有关键字  在严格模式下是不允许)

// 解构赋值(比较常用的语法)
// 数组  []
// 索引值0 1 2,....
// 2) 可以通过数组解构赋值
// 等于号左右两侧结构需要一致,可以全部取值,也可以取出部分的值 
let [a, b, c] = [100, 200, 300];
// console.log(a);// 100
// console.log(b);// 200
// console.log(c);// 300

let [, , g] = [100, 200, 300];
console.log(g);// 300

let [, , blue] = ['red', 'green', 'blue'];
console.log(blue);// 'blue'

let [[[num]]] = [[[100]]];
console.log(num);// 100


// 对象  {}
// 键值对
let point = { x: 300, y: 400, color: 'red' };
let { x, y, color } = point;
console.log(x);// 300
console.log(y);// 400
console.log(color);// 'red'

// 示例1:
let { code, result } = { code: 200, result: [{ name: '小明' }, { name: '小红' }, { name: '小兰' }] }
console.log(code);// 200
console.log(result);//[{name:'小明'},{name:'小红'},{name:'小兰'}]

// 示例2:
let { result: [item1, item2, item3] } = { code: 200, result: [{ name: '小明' }, { name: '小红' }, { name: '小兰' }] }
console.log(item1);// {name: '小明'}
console.log(item2);// {name: '小红'}
console.log(item3);// {name: '小兰'}

// 示例3:
let { result: [{ name: n1 }, { name: n2 }, { name: n3 }] } = { code: 200, result: [{ name: '小明' }, { name: '小红' }, { name: '小兰' }] }
console.log(n1);// '小明'
console.log(n2);// '小红'
console.log(n3);// '小兰'

// 总结:
// 针对数组、对象提供了一种快捷取值的方法
// 取值的方式有很多种,ES6提供了新的方式。那我们可以学习加以使用
// 等于号左右两侧结构需要一致,可以全部取值,也可以取出部分的值
// let [ 变量1, 变量2, 变量3 ] = 数组
// let { 变量4, 变量5, 变量6 } = 对象
// 变量名称不能冲突了。。。。

对象语法糖(简写)

 // 语法糖:某种语法的简写
let color = "red";
let width = "100px";
let height= "100px";

// 定义对象
let obj = {
    color,
    width,
    height
}
console.log(obj);// {color: 'red', width: '100px', height: '100px'}
// 定义变量,这些变量可以作为对象的key
let x = 50;
let y = 100;
let w = 200;
let h = 300;
// 直接输出变量,检查变量是否有值
// console.log({x,y,w,h});
let point = {
    x,y,w,h 
}
console.log(point);// {x: 50, y: 100, w: 200, h: 300}
// 可以把变量作为对象的key,写在大括号 {变量} 最终会形成 {变量: 值} 。

箭头函数

函数是什么?函数是代码块

是可重复执行的代码块。

是指可以实现特定功能的代码块。

提示:定义函数,需要调用函数,代码块才被执行。。。

普通函数:

function foo(){
}
foo()

构造函数:

function App(){
    this.version = "v1.0.0";
}
new App();

箭头函数:

强调一下,箭头函数不能作为构造函数,不能使用new来调用,因为箭头函数作用域没有this这个概念。

使用箭头 “ =>” 来声明的函数叫做箭头函数(也是可重复利用的代码块)

// 示例1: 区别普通函数和箭头函数写法
// 普通函数
// var foo = function(){
//     console.log("我是普通函数")
// }
// foo();

// 箭头函数
// const boo = () => {
//     console.log("我是箭头函数")
// }
// boo();


// 示例2:返回值
// return 需要在函数作用域中才起作用
const getRadomNum = ()=> {
    // 返回0~100之间的随机整数
    return Math.floor(Math.random() * 100);
}
// let v1 = getRadomNum();
// console.log({v1});// {v1: 随机数}

const getRadomNum = ()=> 返回值;
// 示例3:传参
// 形参和实参
// 形参就是局部变量
// 实参就是数据
// 有参数并且是一个参数的情况下,可以省略小括号 ()
// const sayHello = (userName)=> {
//     console.log(`${userName},你好。`);
// }

// const sayHello = userName => {
//     console.log(`${userName},你好。`);
// }
// sayHello("小明");
// sayHello("小新");

// 两个参数以上
const speaking = (userName, message)=> {
    console.log(`${userName},${message}`);
}
// speaking("小明", "你看看你,一天天的,就知道吃");
// speaking("xiaoming", "You see see you, one day day , just to eat");


// 参数默认值
// const add = (a,b) => {
//     return a + b;
// }
// const v2 = add();
// console.log({v2});// {v2:NaN}
// undefined  + undefined = NaN

// const add = (a=1,b=2) => {
//     return a + b;
// }
// const v2 = add();
// console.log({v2});// {v2:3}


// 示例4: this 指向
// 情况一:
// const foo = ()=> {
//     console.log(this);// 上一级作用域(就是全局作用 this | window)
// }
// foo();

// 情况二:
// document.querySelector(".btn").onclick = function(){
//     console.log(this);// 事件调用者 <button class="btn">点击一下</button>
// }
document.querySelector(".btn").onclick = () => {
    console.log(this);// // 上一级作用域(就是全局作用 this | window)
}

// 情况三:
// let obj = {
//     foo: function(){
//         console.log(this);// this 指向 obj 对象
//     }
// }
// obj.foo();

// let obj = {
//     foo: ()=>{
//         console.log(this);// this 指向 window对象
//     }
// }
// obj.foo();


// 情况四:
function App(){// 构造函数作用域  this 指向App构造函数的实例
    this.version = "V1.0.0";
    // 单独定义变量记录实例对象 _this  that xxx
    var xxx = this;
    setTimeout(function(){// 延迟定时器函数作用域 this 指向window对象
        console.log('1:',this.version);// 可不可以获取这个字符串 “"V1.0.0"” ? 不可以,是undefined
        console.log('2:',xxx.version);// 可不可以获取这个字符串 “"V1.0.0"” ? 可以
    },100)

    setTimeout(()=>{
        console.log('3:',this.version);// 可不可以获取这个字符串 “"V1.0.0"” ? 可以
    },100)
}
// new App();


//示例5: 把以下代码改成使用箭头函数
var f1 = function(x){
    return function(y){
        return function(color){
            return {
                x,y,color
            }
        }
    }
} 
// 单一传递参数的函数(柯里化函数)
var v3 = f1(100)(200)('red');
console.log(v3);// {x: 100, y: 200, color: 'red'}

// 箭头函数 (特殊写法)
const f2 = x => y => color => {
    return {x,y,color}
}
或者
const f2 = x => y => color => {x, y, color}

var v4 = f2(100)(200)('blue');
console.log(v4);// {x: 100, y: 200, color: 'red'}

拓展运算符 ...

// 拓展运算符
// ...

// 作用:
// 1. 复制数据集合中的数据
// 2. 展开集合中的数据
// 3. 处理剩余参数

// 定义数组
let arr1 = [100,200,300];
let arr2 = [400,500,600];

// 回想之前的“浅拷贝”
let newArr = [... arr1, ... arr2];
// console.log(newArr);// [100,200,300,400,500,600]

// 展开集合中的数据
// console.log(... arr1);// 100 200 300

// let obj = {x:"100px",y:"200px"};
// console.log(... obj);// 报类型错误


// 处理剩余参数(实参比形参数量要多的情况下)
// 后续在vuex插件中可以使用
//ES6
const foo = (a,b,c, ... rest)=> {
    console.log(a);
    console.log(b);
    console.log(c);
    console.log(rest);// [4,5,6,7,8]
    // console.log(arguments);// 在箭头函数作用域中 无法使用arguments对象
    // 否则报错 Uncaught ReferenceError: arguments is not defined
}
foo(1,2,3,4,5,6,7,8);

字符串&数组新增的API

// 字符串(带有引号的数据都叫字符串 'abc' "abc" `abc`)
// 面试题:请你列举5个字符串操作API?
// slice()
// indexOf()
// replace()
// toUpperCase()
// toLowerCase()
// split()
// .... 
let src = "https://www.xxxx.com/static/demo.jpg";
var v1 = src.startsWith('https');// 判断是否以 'https' 开头
var v2 = src.startsWith('file');
var v3 = src.includes('static'); // 判断是否包含 'static' 
var v4 = src.endsWith('.jpg');// 判断是否以 '.jpg' 结束
var v5 = src.endsWith('.txt');
console.log({v1,v2,v3,v4,v5});
// console.log({v1,v2,v3,v4,v5});


// 数组(特征:具有length属性以及通过索引去存值或取值的数据集合)
// 伪数组 (具有数组的特征,但是不能调用数组的方法)
// let divs = document.getElementsByTagName("div");
// console.log(divs);
// divs.push("aaa");// 报错

// 定义数组
let arr = ['aaa', 'bbb', 'ccc', 'ddd'];
// 1) 循环
arr.forEach((item, index) => {
    // console.log(item);// 代表的是数组的每一项数组 (以后在框架开发中经常这个"item")
    // console.log(index);// 索引
})

// 2)映射(一一对应的意思)
// 可以映射出一个新数组
// let newArr = arr.map((item)=>{
//     return item.toUpperCase();
// })
// console.log(newArr)

// 定义数组
let students = [
    { name: "小明", socre: 60, id: 1 },
    { name: "小红", socre: 50, id: 2 },
    { name: "小兰", socre: 80, id: 3 },
    { name: "小清", socre: 30, id: 4 },
    { name: "小黄", socre: 90, id: 5 }
]

// 根据数据映射一个新数据,标注哪些同学是及格的(>=60),哪些同学是不及格的(< 60)
// 以后react中有着重要的作用(jsx 做列表渲染)
let newStudents = students.map((item) => {
    // 根据分数做判断
    if (item.socre >= 60) {
        item.text = "及格的"
    }
    else {
        item.text = "不及格的"
    }
    return item;
})
// console.log(newStudents);

// 3) 过滤
// 过滤掉分数低于60分的同学
let data = students.filter((item)=>{
    // 判断分数是否大于等于60
    if(item.socre>=60){
        // 返回(保留)
        return item;
    }
})
// console.log(data);

// 4) reduce (累计计算)
let result = [1,2,3,4,5,6] // 全部加起来等于21
let total = result.reduce((prev,next)=>{
    return prev + next;
})
console.log("累计计算的结果:",total);// 累计计算的结果: 21

Set和Map

// Set 
// 这个函数可以操作数组 
// 1. 可以把数组中重复的数据过滤掉(让数组中的数据不重复)
// 2. 提供对数组进行新增、删除等相关功能

// 定义数组
let arr = ['a','b','c','a','b','c','d','e'];

// 编程题:如何实现数组去重?
// let obj = {};
// let newArr = [];
// for(let i = 0 ; i < arr.length ; i ++){
//     // 这个key其实就是arr数组的每一项数据
//     let key = arr[i];
//     if(obj[key] === undefined) {
//         // 把首次出现的key添加到新数组中
//         newArr.push(key);
//         // 给obj对象的key赋值
//         obj[key] = 1;
//     }
// }
// // 循环结束,数组去重了
// console.log(newArr);// ['a', 'b', 'c', 'd', 'e']

// ES6
// 数组去重
let setObj = new Set(arr);
let newArr2 = [... setObj];
console.log(newArr2);// ['a', 'b', 'c', 'd', 'e']

// 添加数据
setObj.add('f');
setObj.add('g');
// console.log(setObj);// Set(6) {'a', 'b', 'c', 'd', 'e','f','g'}

// 删除数据
setObj.delete('a');
console.log(setObj);// Set(6) {'b', 'c', 'd', 'e','f','g'}

// 判断集合中是否存在这个数据
console.log(setObj.has('c'));// true
console.log(setObj.has('x'));// false

// Map
// 这个函数可以操作对象
// 主要是提供可操作对象的API
let mapObj =  new Map(); 

// 普通对象(键要么是数字,要么是字符串)
let obj = {
    0: '100px',
    'width':'100px'
}      

// 设置键值对 (键可以是任意类型数据)
mapObj.set("width","100px");
mapObj.set("height","100px");
mapObj.set("color","red");

mapObj.set(true,10010);
// 获取键对应的值
let w = mapObj.get("width");
let h = mapObj.get("height");
let c = mapObj.get("color");
console.log({w,h,c});
// 删除对象中指定的数据
mapObj.delete("color");

// 循环mapObj对象
mapObj.forEach((value,key)=>{
    console.log(value,'---->',key);
})
console.log(mapObj);//Map(3) {'width' => '100px', 'height' => '100px', true => 10010}

Proxy和Reflect

// Reflect 
// 主要是针对对象进行操作
let data = {
    message: "好消息"
}
// 观察Reflect对象
// console.log(typeof Reflect);// 'object'  对象
// 观察Reflect对象结构,看这个对象都有哪些方法?
console.dir(Reflect);

// 1) 获取指定对象的属性值
let v1 = Reflect.get(data, 'message');
console.log(v1);// '好消息'

// 2) 设置指定对象的键值对
Reflect.set(data, "name", "小明");
Reflect.set(data, "age", 20);

// 3) 删除指定对象的属性
Reflect.deleteProperty(data, 'age');

// 控制台输出:
console.log(data);//{message: '好消息', name: '小明'}

// 4) 判断指定对象是否存在message这个键
console.log(Reflect.has(data, 'message'));// true
console.log(Reflect.has(data, 'xxx'));// false

// ES5
// console.log(data.message);// '好消息'


// Proxy (Vue3做响应式是基于这个函数)
// 这是构造函数
// console.log(typeof Proxy);// 'function'
// 可以代理对象,在Vue@3.x内部封装就采用了这个函数对数据进行监听,从而实现数据响应式。

// 主要是可以做拦截、数据响应式
let obj = {}

let proxyObj = new Proxy(obj, {
    // 监听对象的读写
    // 监听对象是否取值了
    // get:function(){},
    get(target, key) {
        // console.log("读取");
        // 拦截 对“age”这个属性进行拦截了
        if(key=="age") {
            return "不告诉你";
        }
        // 返回属性值
        return target[key];
    },

    // 监听对象是否赋值了
    set(target, key, value) {
        // console.log("写入")
        // 赋值
        target[key] = value;
    }
})

// 关于对象的取值和赋值
proxyObj.message = "hello world";// 赋值
proxyObj.age = 100;// 赋值
proxyObj.message;// 取值
console.log(proxyObj.age);// "不告诉你"
console.log(proxyObj.message);//  "hello world"


// 示例:感受一下什么叫做数据响应式
let inp = document.querySelector("input[type='text']");
let box = document.querySelector("div[class='box']");

let data2 = {
    msg:""
};

// 数据修改了,可以改变页面(响应式)
let pObj =  new Proxy(data2,{
    set(target,key,value){
        // 赋值
        target[key]=value;
        // 修改box标签的文本
        box.innerHTML = value;
        box.style.backgroundColor = value;
    }
})

// 给输入框添加事件
inp.addEventListener('input',function(){
    // 获取输入的值
    let v1 = inp.value;
    // 给pObj.msg属性赋值(通过修改msg,改变box标签的文本)
    pObj.msg = v1;
})

Promise 处理异步编程(必须)

// 示例1:
// 开关,布尔值为true, 
// 执行第一个then方法的第一个回调函数
// 否则false就执行第一个then方法的第二个回调函数
let isShow = true;

// 创建promise
let p1 = new Promise((resolve,reject)=>{
    if(isShow){
        resolve("符合条件");
    }
    else {
        reject("不符合条件");
    }
})

// console.log(p1);// Promise {} 这是promise实例, 可以实现链式操作
p1
.then(
    (msg)=>{
        console.log(msg);// '符合条件'
        return 111
    },
    (err)=> {
        console.log(err);// '不符合条件'
    }
)
.then(
    (msg)=>{
        console.log(msg);// 111 上一个then方法的第一个回调函数没有返回值,此处就是undefined
        return 222;
    }
)
.then(
    (msg)=>{
        console.log(msg);// 222
    }
)



// 示例2:
let p2 = new Promise((resolve,reject)=>{
    if(false){
        resolve();
    }
    else {
        reject();
    }
})

p2.
then(
    ()=>{
        console.log("1.0 符合条件")
    }
)
.catch(
    ()=>{
        console.log("2.0 不符合条件")
    }
)
.finally(
    ()=>{
        console.log("3.0 不管是否符合条件,最后都执行")
    }
)


// 总结:
    // Promise是一种解决异步编程的方案。
    // 创建Promise实例,其实这个Promise实例就是一套处理业务的逻辑(例如:登录的逻辑,加入购物车的逻辑,支付的逻辑)
    // 可以通过实例对象链式调用then方法,不断执行“下一个”逻辑,从而代替“回调地狱”
    // Promise实例可以调用then方法,catch方法,finally方法。

async 和 await 语法 (必须掌握)

既可以处理同步编程,也可以处理异步编程。

往往需要配合Promise使用,不然await不起作用。(await这个修饰符需在async函数作用域中使用)

const   init  = async ()=> {
        执行业务1
        await  登录promise
    await  收藏promise
    await  收藏列表promise
        执行业务2
}
// 示例1: async 关键字  (处理异步)
// const sayHello = async () => {}
const sayHello = async function(){
console.log("首先。。。。")
return 111;
}
// const pro =  sayHello();
// console.log(pro);
// pro
// .then(
//     (result)=>{
//         console.log("然后。。。。1", result);// 然后。。。。1 111
//     }
// )
// .then(
//     (result)=>{
//         console.log("然后。。。。2",result);// 然后。。。。2 undefined
//     }
// )
// .then(
//     ()=>{
//         console.log("然后。。。。3")
//     }
// )
// .then(
//     ()=>{
//         console.log("然后。。。。4")
//     }
// )

// 示例2: async 和 await (既可以处理同步,也可以处理异步)
// const speaking = async function(){
//     console.log("第一件事情:起床");
//     await setTimeout(()=>{ console.log("第二件事情:吃早餐") },300)
//     await setTimeout(()=>{ console.log("第三件事情:上课") },300)
//     console.log("第四件事情:下课");
// }
// speaking();

// 配合promise使用
const speaking = async function(){
console.log("第一件事情:起床");
await new Promise((resolve,reject)=>{
    setTimeout(()=>{ resolve() },5000)
})
.then(
    ()=> {
        console.log("第二件事情:吃早餐")
    }
)
await new Promise((resolve,reject)=>{
    setTimeout(()=>{
        resolve()
    },1000)
})
.then(
    ()=> {
        console.log("第三件事情:上课")
    }
)

console.log("第四件事情:下课");
}
speaking();

// 总结:
// async 关键字修饰的函数,可以返回promise实例。
// await 关键字必须在async函数作用域中使用,而且需要结合promise语法,才有“等待”的作用。

// 应用场景:
// 比如:首先渲染html字符串,然后操作html标签。

类 class (面向对象)

面向对象

概念

是一种编程思想(指导程序开发程序的思想),与面向过程相反。面向对象是判断软件好与坏的标准。

面向过程:步骤比较清晰(第一步获取标签,第二步绑定事件,第三步书写业务逻辑)

面向对象: 围绕对象成员实现不同功能 (通过this添加属性,通过原型添加方法,从而构建一个对象出来)

特性

封装性:把客观存在的数据添加到对象中(把实现业务逻辑的代码写在函数或对象中)

继承性:A对象(子)可以拥有B对象(父)的属性和方法 (代码复用)

多态性: 同一个对象或函数,在不同的场景下,可以有不同的表现形式。

抽象

抽象的事物有哪些?

比如:

人类

动物 ....

App构造函数(抽象的)

类 (class)

具体

具体的事物有哪些?

比如:

科技园楼下的红色大众汽车

前端就业班2429班的毅明班长

App实例对象

ES5 中面向对象的写法有很多种。。。。

直接量对象

工厂模式

构造函数

原型

apply call bind 改变this指向

....

class的使用

ES6 中的写法比较统一

都是围绕着 class 进行编写

// 设计对象  汽车  Car
    // 属性:  品牌(brand)  颜色(color) 价格(price)
    // 方法:  展示信息的方法(showInfo)    

// 编码:
// 声明类 (抽象)
class Car {
    // 这个词汇是固定的(构造函数)
    constructor(brand , color , price){
        // 添加属性
        this.brand = brand;
        this.color = color;
        this.price = price;
    }
    // 方法直接在类内部编写即可 (实际上这个方法就是在原型上添加)
    // 此处方法名称是自定义的
    showInfo(){
        console.log(`${this.price}价格的${this.color}的${this.brand}品牌汽车`)
    }
}


// 创建类的实例(具体的)
const c1 = new Car("宝马","黑色","30万");
c1.showInfo();

// 类(对象)
// 声明子类
class DaZhong extends Car {
    // 构造函数
    constructor(brand , color , price){
        // 通过父类函数接收参数
        super(brand , color , price);
    }
}

// 创建子类实例
const d1 = new DaZhong("辉腾","红色","20万");
d1.showInfo();

静态成员

// class 
// 提供静态成员(静态属性和静态方法),意思是由类对象直接使用的属性和方法
// 静态属性和静态方法不是给类的实例对象使用,而是给类直接使用

// 静态属性和静态方法
// 示例2:  声明类
class App2 {
    // static 修饰符
    // 静态属性
    static version = "v1.0.0";
    // 静态方法
    static showVersion() {
        // 是由类来引用属性,叫静态属性
        console.log(App2.version);
    }
    static updateVersion(version) {
        App2.version = version;
    }
}

// 这是app2是实例对象,其他没有静态成员
// const app2 = new App2();
// console.log(app2);

// 观察类 App2
// console.dir(App2);

// 这些由类直接使用的方法叫静态方法
App2.updateVersion("版本v5.0.0")
App2.showVersion();

私有属性

// 私有属性:只能在当前类内部使用的属性
class App {
    // 带有 “#” 符号修饰的属性叫做私有属性,只能在类的内部使用。
    #version="v1.0.0";
    showVersion(){
        console.log(this.#version);//输出版本
    }
    updateVersion(version){
        this.#version = version;
    }
}
const app = new App();
app.updateVersion('v6.0.0');
app.showVersion();
// console.log(app.version);// undefined
// console.log(app.#version);//报错,私有属性不能在类的外部使用

模块化

<script>
    // 模块化语法,通常是在web工程化项目中使用。(可以webpack构建web工程)
    // 现在我们并没有构建web工程,怎么演示使用这个模块化?
    // 可以给script标签 设置type属性等于module
</script>
<script type="module">
    // 1) 按需导入
    import { search , comp1 , comp2 } from './components/Search.js';
    search();
    // comp1();
    // comp2();

    // 2) 全部导入
    import listObj from './components/List.js';
    listObj.init();


    // 3)导入 (可以修改模块名称)
    import { audioPlayer } from  './components/Player.js';
    audioPlayer.render();
</script>
// 定义函数 代表搜索组件

// 导出搜索模块
export const search = function(){
    let div = document.createElement("div");
    div.innerHTML = `<h3>搜索组件</h3>`;
    document.body.appendChild(div);
}
// 导出模块1
export const comp1 = function(){
    let div = document.createElement("div");
    div.innerHTML = `<h3>组件1</h3>`;
    document.body.appendChild(div);
}
// 导出模块2
export const comp2 = function(){
    let div = document.createElement("div");
    div.innerHTML = `<h3>组件2</h3>`;
    document.body.appendChild(div);
}
// 导出模块
export default {
    // 初始化
    init(){
        let div = document.createElement("div");
        div.innerHTML = `<h3>列表组件</h3>`;
        document.body.appendChild(div);
    }
}
// 定义对象
const obj = {
    render(){
        let div = document.createElement("div");
        div.innerHTML = `<h3>播放器组件</h3>`;
        document.body.appendChild(div);
    }
}

// 导出组件时,修改组件的名称
export { obj as audioPlayer };

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值