如何搭建一个自己的专属音乐播放器?教程拿去!

admin 2022年5月17日19:20:41评论112 views字数 4501阅读15分0秒阅读模式
如何搭建一个自己的专属音乐播放器?教程拿去!
点击蓝字 关注我们
如何搭建一个自己的专属音乐播放器?教程拿去!

内容来源于掘金:单程线_01(黄灿民),别忘记看文末福利~

JavaScript 的继承是通过原型链实现的,要实现继承需要理解原型和原型链的概念。

原型和原型链

1、仅函数上存在 prototype 属性(这是一个显式原型属性),其指向原型对象,原型对象上存在两个属性:constructor 和 [[prototype]] (无法访问,部分浏览器可通过 __proto__ 访问,这是一个隐式的原型属性);

    • constructor :指向构造函数,即是函数自身

    • [[prototype]](__proto__):指向构造函数的原型对象,即 Object ,Object.__proto__ = null

    2、当通过 new 调用这个函数时,得到的对象会存在 [[prototype]](__proto__),指向的是函数的 prototype 属性;

    3、所有的对象上都存在 [[prototype]](__proto__)属性;

    4、这种通过 __proto__ 在各对象间建立链接的工具就是原型链,通过原型链可以访问到其他对象的属性和方法。

    继承的实现方式

    继承指一个对象直接使用另一对象的属性和方法。JavaScript 的继承是通过原型链实现的。

    实现属性继承的核心代码是 SuperFn.call(this),实现方法继承的核心代码是 SubFn.prototype.__proto__ = SuperFn.prototype,具体实现方式有以下6种:

    1、ES6 class 类 extends 继承

    通过 ES6 新增的语法糖实现继承。

    class SuperClass {    constructor(name) {        this.name = name || 'super';        this.arr = [1, 2];    }    sayName(){        console.log(this.name)    }}
    class SubClass extends SuperClass{    constructor(){        super();    }}
    const sub0 = new SubClass();const sub00 = new SubClass();sub00.name = 'sub11';sub00.arr.push(3);
    sub0.sayName(); // 'super'console.log(sub0.name, sub0.arr, sub0.arr === sub00.arr, sub0 instanceof SubClass, sub0.constructor ===SubClass); // 'super'  [1,2]  false true true

    2、基于原型继承

    原型赋值 SubFn.prototype = new SuperFn();

    问题点:

    • 原型对象的 constructor 属性值变为 Object;

    • 原型对象中包含引用值,值操作会同时反应到所有继承对象上;

    • 子类型在实例化时不能给父类型的构造函数传参。

    function SuperFn(name) {    this.name = name || 'super';    this.arr = [1, 2];}SuperFn.prototype.sayName = function () {    console.log(this.name)}/*  基于原型继承: SubFn1.prototype = new SuperFn();    问题点:    - 原型对象的 constructor 属性值变为 Object    - 原型对象中包含引用值,值操作会同时反应到所有继承对象上    - 子类型在实例化时不能给父类型的构造函数传参*/function SubFn1() {}// 继承属性和方法:SubFn1 的原型指向 SuperFn 的实例和方法// 带来的影响://   - SubFn1 的构造函数变为 Object//   - SuperFn 的实例对象中包含引用值,值操作会同时反应到所有继承对象上SubFn1.prototype = new SuperFn();
    const sub1 = new SubFn1();const sub11 = new SubFn1();sub11.name = 'sub11';sub11.arr.push(3);
    sub1.sayName(); // 'super'console.log(sub1.name, sub1.arr,sub1.arr === sub11.arr, sub1 instanceof SubFn1, sub1.constructor ===SubFn1); // 'super'  [1,2,3] true true  false

    3、借用构造函数

    构造函数内部执行 SuperFn.call(this),只能继承属性,不能继承原型链上的方法。

    问题点:

    • 只能继承父类的实例属性和方法,不能继承原型属性/方法;

    • 字类构造函数无法实现复用,每个子类都有父类实例函数的副本。

    /* 借用构造函数:SuperFn.call(this)   问题点:    - 只能继承父类的实例属性和方法,不能继承原型属性/方法    - 字类构造函数无法实现复用,每个子类都有父类实例函数的副本*/function SubFn2() {   // 继承属性:子类构造函数中调用父类构造函数并绑定 this ,   // 每次创建实例的过程,函数都会重新执行,同一个属性每次都会新建   SuperFn.call(this, ...arguments)}
    const sub2 = new SubFn2('sub2');const sub22 = new SubFn2();sub22.name = 'sub22';sub22.arr.push(3);
    // sub2.sayName(); // 报错console.log(sub2.name, sub2.arr,sub2.arr === sub22.arr, sub2 instanceof SubFn2, sub2.constructor ===SubFn2); // 'sub2'  [1,2]  false true  true

    4、组合继承

    构造函数内部执行 SuperFn.call(this),原型赋值 SubFn.prototype.__proto__ = SuperFn.prototype

    /* 组合继承:SuperFn.call(this)  SubFn3.prototype.__proto__ = SuperFn.prototype;   问题点:属性重复建立*/function SubFn3() {   // 继承属性:子类构造函数中调用父类构造函数并绑定 this ,   //每次创建实例的过程,函数都会重新执行,同一个属性每次都会新建   SuperFn.call(this, ...arguments)}// 继承方法SubFn3.prototype.__proto__ = SuperFn.prototype;
    const sub3 = new SubFn3('sub3');const sub33 = new SubFn3();sub33.name = 'sub33';sub33.arr.push(3);
    sub3.sayName(); // 'sub3'console.log(sub3.name, sub3.arr,sub3.arr === sub33.arr, sub3 instanceof SubFn3, sub3.constructor ===SubFn3); // 'sub3'  [1,2]  false true true 

    5、原型式继承

    此种方式和 subObj = Object.create(superObj) 实现的功能相同。

    /* 原型式继承:此种方式和 Object.create() 实现的功能相同   问题点:    - 原型对象中包含引用值,值操作会同时反应到所有继承对象上    - 无法传递参数*/
    // 此函数用来创建一个对象,对象的原型指向传递的参数(继承的对象)let Fn;function CreateObj(obj) {   // 函数内部定义构造函数   function F() {}   Fn = F;   // 构造函数的原型对象指向传递的进来的对象   F.prototype = obj;   // 创建实例化对象并返回,此实例对象的 __proto__ = F.prototype = obj   return new F();}const SuperObj = {   name: 'super',   arr: [1, 2],   sayName() {       console.log(this.name)   }}
    const sub4 = CreateObj(SuperObj); // 等价于 sub4 = Object.create(SuperObj) sub4.__proto__ = SuperObjconst sub44 = CreateObj(SuperObj);
    sub44.name = 'sub44';sub44.arr.push(3);
    sub4.sayName(); // 'super'console.log(sub4.name, sub4.arr, sub4.arr === sub44.arr,sub4 instanceof Fn, sub4.constructor === Object); // 'super'  [1,2,3] true true true  

    6、寄生式组合继承

    构造函数内部执行 SuperFn.call(this),原型赋值 SubFn.prototype = Object.create(SuperFn.prototype)

    /* 5.寄生式组合继承*/
    function inheritPrototype(SuperFn, SubFn) {   //此函数实现的目的如下  SubFn.prototype.__proto__ = SuperFn.prototype   SubFn.prototype = Object.create(SuperFn.prototype);   SubFn.prototype.constructor = SubFn;}
    function SubFn5() {   SuperFn.call(this, ...arguments);}inheritPrototype(SuperFn, SubFn5);
    const sub5 = new SubFn5();const sub55 = new SubFn5();sub55.name = 'sub55';sub55.arr.push(3);
    sub5.sayName(); // 'super'console.log(sub5.name, sub5.arr,sub5.arr === sub55.arr, sub5 instanceof SubFn5,sub5.constructor ===SubFn5); // 'super'  [1,2]  false true true 

    另外,作者黄灿民在蓝桥云课上线了《JavaScript 从零构建音乐播放器》,供大家实战做项目。

    本实验采用原生 JavaScript 搭建类似网易云的音乐播放器,应用到的技术包括 ES6 新增的语法糖如解构赋值、箭头函数、展开运算符模板字符串 、异步处理 Promise、ES6 模块化等。

    通过上述技术最终完成页面切换、轮播图、音乐播放器等功能。

    播放器首页(轮播图)效果

    如何搭建一个自己的专属音乐播放器?教程拿去!

    推荐列表详情页效果

    如何搭建一个自己的专属音乐播放器?教程拿去!

    播放器页面效果

    如何搭建一个自己的专属音乐播放器?教程拿去!

    如果你想学习《JavaScript 从零构建音乐播放器》,欢迎扫码入群领取 3 日标准会员,即享 8 折优惠学

    ▼扫码立即领取优惠▼

    如何搭建一个自己的专属音乐播放器?教程拿去!

    如何搭建一个自己的专属音乐播放器?教程拿去!

    戳戳“阅读原文”直达课程页面!

    原文始发于微信公众号(蓝桥云课精选):如何搭建一个自己的专属音乐播放器?教程拿去!

    • 左青龙
    • 微信扫一扫
    • weinxin
    • 右白虎
    • 微信扫一扫
    • weinxin
    admin
    • 本文由 发表于 2022年5月17日19:20:41
    • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                     如何搭建一个自己的专属音乐播放器?教程拿去!https://cn-sec.com/archives/1014991.html

    发表评论

    匿名网友 填写信息