admin 2025-12-19 18:06:33 养成攻略

概念

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 = `

  • ${text}

  • `

    解构赋值(数组、对象)

    // 存储数据的方式,声明变量

    // 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);// 事件调用者

    // }

    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);//报错,私有属性不能在类的外部使用

    模块化

    // 定义函数 代表搜索组件

    // 导出搜索模块

    export const search = function(){

    let div = document.createElement("div");

    div.innerHTML = `

    搜索组件

    `;

    document.body.appendChild(div);

    }

    // 导出模块1

    export const comp1 = function(){

    let div = document.createElement("div");

    div.innerHTML = `

    组件1

    `;

    document.body.appendChild(div);

    }

    // 导出模块2

    export const comp2 = function(){

    let div = document.createElement("div");

    div.innerHTML = `

    组件2

    `;

    document.body.appendChild(div);

    }

    // 导出模块

    export default {

    // 初始化

    init(){

    let div = document.createElement("div");

    div.innerHTML = `

    列表组件

    `;

    document.body.appendChild(div);

    }

    }

    // 定义对象

    const obj = {

    render(){

    let div = document.createElement("div");

    div.innerHTML = `

    播放器组件

    `;

    document.body.appendChild(div);

    }

    }

    // 导出组件时,修改组件的名称

    export { obj as audioPlayer };