js基础第三篇(js面向对象)

本文介绍JavaScript面向对象编程的基础概念及其实现方式,包括构造函数、原型链等,并通过实例演示了如何使用面向对象的方法实现轮播图效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

js面向对象

swiper

swiper超链接

下载完后找到需要的文件:注意,点开头的文件夹都没用,不要管

需要:swiper-bundle.min.css和swiper-bundle.min.js,想要看的话可以选择不带min的文件

不会或者想要改动可以查找API文档

写一个轮播图:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
</head>
<link rel="stylesheet" href="./css/swiper-bundle.min.css">

<body>
    <div class="swiper-container">
        <div class="swiper-wrapper">
            <div class="swiper-slide">Slide 1</div>
            <div class="swiper-slide">Slide 2</div>
            <div class="swiper-slide">Slide 3</div>
        </div>
        <!-- 如果需要分页器 -->
        <div class="swiper-pagination"></div>

        <!-- 如果需要导航按钮 -->
        <div class="swiper-button-prev"></div>
        <div class="swiper-button-next"></div>

        <!-- 如果需要滚动条 -->
        <div class="swiper-scrollbar"></div>
    </div>
    <style>
        .swiper-container {
            width: 600px;
            height: 300px;
        }
    </style>
</body>
<script src="./js/swiper-bundle.min.js"></script>
<script>
    var mySwiper = new Swiper('.swiper-container', {
        direction: 'horizontal', // 垂直切换选项
        loop: true, // 循环模式选项

        // 如果需要分页器
        pagination: {
            el: '.swiper-pagination',
        },

        // 如果需要前进后退按钮
        navigation: {
            nextEl: '.swiper-button-next',
            prevEl: '.swiper-button-prev',
        },

        // 如果需要滚动条
        scrollbar: {
            el: '.swiper-scrollbar',
        },
    })  
</script>

</html>

html模板:模版之家

jquery插件,jq22.com





面向对象的概念

不是语法,是一种编程的思想,更加注重对象object

OOP:面向对象的编程





创建对象

1、字面量形式:

var obj ={}

2、构造函数形式

var obj =new Object();

第一种简洁方便,先选择第一个创建对象

先看下面的代码:

var name ="张三";
var age=12;

var name1="李四";
var age1 = 13;

变量多了容易乱:所以用对象存储。

var obj1={
    name:"张三",
    age:12
}
var obj2 ={
    name:"李四",
    age:13
}
//...

对象多了就是不停的重复(所以字面量形式定义对象不是最优发方案),我们需要处理重复:使用函数处理重复





工厂函数的创建以及他的缺点

函数处理字面量定义对象重复:

function getObj(){
    var obj2={
        name:"李四",
        age:13,
        sex:"女"
    }
    return obj2
}


var obj1 = getObj();
console.log(obj1);

var obj2=getObj();
console.log(obj2);

函数的参数不能写死:

function getObj(name,age,sex){
    var obj2={
        name:name,
        age:age,
        sex:sex
    }
    return obj2
}


var obj1 = getObj("张三",12,"男");
console.log(obj1);

var obj2=getObj("李四"13,"女");
console.log(obj2);

这种函数通常都是将数据仍进去,生产一个对象:称为工厂函数

工厂函数比直接使用字面量形式定义更加优秀

缺点:

var obj3= {
    name:"阿黄",
    age:12,
    sex:"母"
}

typeof都是object,看不出精准的数据类型,就像你不知道obj3是人是狗,使用的时候只能靠猜





构造函数解决工厂函数的缺点

之前学的var arr = new Array[];

var num = new Number();//都是有精准的数据类型

console.log(arr,number);

所以试试构造函数:

function fn(){
    
}
var f = new fn();
console.log(fn);



function Preson(){
    
}
var  obj1 = new Person();
console.log(obj1);



function Dog(){
    
}
var d = new Dog();
console.log(d);

可以得出自己定义构造函数来解决工厂函数数据类型不精准的缺点。



解决:

function Person(){//构造函数
    //在构造函数中给对象添加属性的方式:this
    this.name="张三";
    this.age=12;
    this.sex="女";
}
var person = new Person();//调用了构造函数
console.log(person);

this在构造函数中,代表被new 出来的对象(this代表person)

数据不应该写死:

function Person(name,age,sex){
    this.name=name;
   	this.sex=sex;
    this.age=age;
}

var zhangsan=new Person("张三"12,"男")var lisi = new Person("李四",12,"女");



function Dog(name,age,sex){
        this.name=name;
   	this.sex=sex;
    this.age=age;
}
var ahuang = new Dog("阿黄",12,"女");
consoole.log(ahuang);

Dog和Person的区别一目了然



注意事项

  1. 构造函数的首字母一般大写

  2. 构造函数被new的时候也是在调用函数,就能有形参和实参

  3. 在构造函数中给对象添加属性的时候,使用this关键字

this在构造函数中,代表new出来的对象

  1. new关键字/new运算符干了什么?

创建了个空对象,只是这个过程是看不见的

​ 将这个空对象直接复制给了this关键字(this=obj,也是看不见的)

​ 给this这个对象添加属性(只能看到这个,相当于给obj添加属性)

将这个对象返回(隐形的)



如何创建对象?构造函数是最优的方案

添加属性使用自定义构造函数也是最佳方案了





添加方法在构造函数不行,在全局有缺点

//使用自定义函数创建对象并添加方法
function Person(nem,age,sex){
     this.name=name;
    this.age=age;
    this.sex=sex;
    this.eat=function(){
        console.log("能吃");
    }
}


var  p = new Person("张三",12,"男");
   // p.eat(){
     //   console.log("能吃");
    //}
console.log(p);

var  p1 = new Person("李四",12,"女");
 console.log(p.eat===p1.eat);//复杂数据类型,结果为false 

为什么不相等,因为是匿名函数,每次创建都相当于在内存中开辟空间



所以在构造函数中添加方法是浪费的(方法是在堆内存开辟空间的对象的内存内的)

function eat(){
    console.log("能吃");
}
function Person(nem,age,sex){
     this.name=name;
    this.age=age;
    this.sex=sex;
    this.eat=eat;
}
var  p = new Person("张三",12,"男");
var  p1 = new Person("李四",12,"女");
 console.log(p.eat===p1.eat);//true,这是堆内存的一种节省

缺点:全局中的东西容易被覆盖(eat =123;这两个方法全凉凉)





利用原型解决方法在全局中的缺陷

任何对象天生自带一个属性,_ _ proto _ _




注:没得空格,这里是方便区分



__ proto __值是一个对象,这个对象叫做原型/原型对象



数组为什么能用push方法?

push方法在__ proto __里面。



对象天生就能使用原型的东西,为了便于理解,相当于顺着__ proto__找到父亲,身为儿子天生可以使用父亲的东西



给数组添加方法:

arr.__proto__.eat = function(){
    console.log("能吃");
}
console.log(arr);




全局函数被覆盖的问题用原型来解决。



任何函数天生自带属性prototype,指的是他老公----原型对象



现在理一下关系:我们需要的对象是由构造函数new出来的( var p = new Person() );构造出来的对象自带属性__proto__指向原型。同一个构造函数创建的对象都有共同的 proto属性(为什么?因为构造函数里面的prototype指的是原型对象)




添加方法的最优解决方法:构造函数给原型对象添加方法,对象使用

Person.prototype.eat=function(){console.log(eat)}




关系图:
复杂不堪的关系图





案例:面向对象版tab切换

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
    <style>
        * {
            margin: 0;
            padding: 0;
        }
        .box {
            width: 500px;
            height: 300px;
            border: 1px solid yellowgreen;
            margin:50px auto;
        }
        ul {
            height: 50px;
            background-color: pink;
            display: flex;
            justify-content: space-evenly;
            align-items: center;
        }
        ul li {
            list-style: none;
            width: 150px;
            height: 30px;
            background-color: gray;
            text-align: center;
            line-height: 30px;
            font-weight: bold;
            font-size: 20px;
            color:green;
        }

        ul li.active{
            background-color: #ff0;
            color:#f00;
        }
        ol li {
            display: none;
        }
        ol li.active {
            display: block;
        }
        ol li img{
            width: 500px;
            height: 250px;
        }
    </style>
<div class="box">
    <ul>
        <li class="active">1</li>
        <li>2</li>
        <li>3</li>
    </ul>
    <ol>
        <li class="active">
            <a href="">
                <img src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2493695704,2540399818&fm=26&gp=0.jpg" alt="">
            </a>
        </li>
        <li>
            <a href="">
                <img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1242578728,2152118644&fm=26&gp=0.jpg" alt="">
            </a>
        </li>
        <li>
            <a href="">
                <img src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3213912571,2486886761&fm=26&gp=0.jpg" alt="">
            </a>
        </li>
    </ol>
</div>
</body>
<script>
//使用面向对象的思维去做

function Tab(){
    //给对象添加属性----属性就是你要操作的那些元素
    this.ulis = document.querySelectorAll(".box ul li");
    this.olis = document.querySelectorAll(".box ol li");

}
//给对象添加方法---绑定事件,处理事件
Tab.prototype.click = function(){
    //给元素绑定事件
    for(let i =0;i<this.ulis.length;i++){//这个this是谁现在还不知道,这里只是定义,是谁得看调用对象
        this.ulis[i].onclick=()=>{
            for(let j = 0 ;  j<this.ulis.length;j++){//不换箭头函数this变成事件源this.ulis[i](每个li),是没有ulis的
                this.ulis[j].className="";
                this.olis[j].className="";
            }
            this.ulis[i].className="active";
            this.olis[i].className="active";
        }
    }
}

var tab = new Tab();
tab.click();
//console.log(tab);//查看属性长什么样子


</script>
</html>

基本三步骤:做对象,添加属性,添加方法





面向对象版轮播图

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>面向对象版轮播图</title>
</head>
<style>
    ul,
    ol {
        list-style: none;
    }

    .box {
        width: 500px;
        height: 300px;
        margin-left: 20px;
        position: relative;
    }

    * {
        margin: 0;
        padding: 0;
    }

    ul {
        width: 500px;
        height: 300px;
        border: 1px solid red;

    }

    ul li {
        display: none;
    }

    ul li.active {
        display: block;
    }

    ul li a img {
        width: 500px;
        height: 300px;
    }

    a {
        text-decoration: none;
        color: black;
        font-size: 30px;
    }

    ol {
        width: 200px;
        height: 26px;
        position: absolute;
        background-color: green;
        border-radius: 26px;
        left: calc(50% - 100px);
        bottom: 20px;
        display: flex;
        justify-content: space-evenly;
        align-items: center;
    }

    ol li {
        background-color: gray;
        width: 26px;
        height: 26px;
        border-radius: 26px;
    }

    ol li.active {
        background-color: red;
    }

    .leftBtn,
    .rightBtn {
        position: absolute;
        left: 0;
        top: calc(50% - 13px);
        height: 50px;
        width: 30px;
        background-color: rgba(0, 0, 0, .5);
        text-align: center;
        line-height: 50px;
    }

    .rightBtn {
        left: calc(100% - 28px);
    }
</style>

<body>
    <div class="box">
        <ul>
            <li class="active"><a href="#"><img
                        src="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=2493695704,2540399818&fm=26&gp=0.jpg"
                        alt=""></a></li>
            <li><a href=""><img
                        src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=1242578728,2152118644&fm=26&gp=0.jpg"
                        alt=""></a></li>
            <li><a href=""><img
                        src="https://ss2.bdstatic.com/70cFvnSh_Q1YnxGkpoWK1HF6hhy/it/u=3213912571,2486886761&fm=26&gp=0.jpg"
                        alt=""></a></li>
        </ul>
        <ol>
            <li class="active"></li>
            <li></li>
            <li></li>
        </ol>
        <a href="javascript:;" class="leftBtn">&lt;</a>
        <a href="javascript:;" class="rightBtn">&gt;</a>
    </div>

</body>
<script>
    //面向对象做轮播图
    function Carousel(classname,speed) {
        this.ulis = document.querySelectorAll("ul li");
        this.olis = document.querySelectorAll("ol li");
        this.leftBtn = document.querySelector("a.leftBtn");
        this.rightBtn = document.querySelector("a.rightBtn");
        this.box = document.querySelector("."+classname);
        this.index = 0;
        this.timer = null;
        this.click(speed);//相当于c.click
    }
    Carousel.prototype.click = function (speed) {
        //右键点击
        this.rightBtn.onclick = () => {
            this.right();
        }
        //左键点击
        this.leftBtn.onclick = () => {
            this.left();
        }
        //小点点击
        for (let i = 0; i < this.olis.length; i++) {
            this.olis[i].onclick = () => {
                this.dot(i);
            }
        }

        //自动轮播
        this.timer = setInterval(() => {
            //定时器中this代表window,改为箭头函数上一级的this(click方法执行对象)
            this.index++;
            if (this.index == this.ulis.length) {
                this.index = 0;
            }
            for (let j = 0; j < this.ulis.length; j++) {
                this.ulis[j].className = "";
                this.olis[j].className = "";
            }
            this.ulis[this.index].className = "active";
            this.olis[this.index].className = "active";
        }, speed)
        //鼠标移入停止
        this.box.onmouseover = () => {
            clearInterval(this.timer);
        }
        //鼠标移出继续
        this.box.onmouseout = () => {
            this.timer = setInterval(() => {
                //定时器中this代表window,改为箭头函数上一级的this(click方法执行对象)
                this.index++;
                if (this.index == this.ulis.length) {
                    this.index = 0;
                }
                for (let j = 0; j < this.ulis.length; j++) {
                    this.ulis[j].className = "";
                    this.olis[j].className = "";
                }
                this.ulis[this.index].className = "active";
                this.olis[this.index].className = "active";
            }, speed)
        }
    }



    Carousel.prototype.right = function () {
        this.index++;
        if (this.index == this.ulis.length) {
            this.index = 0;
        }
        for (let j = 0; j < this.ulis.length; j++) {
            this.ulis[j].className = "";
            this.olis[j].className = "";
        }
        this.ulis[this.index].className = "active";
        this.olis[this.index].className = "active";
    }

    Carousel.prototype.left = function () {
        this.index--;
        if (this.index < 0) {
            this.index = this.ulis.length - 1;
        }
        for (let j = 0; j < this.ulis.length; j++) {
            this.ulis[j].className = "";
            this.olis[j].className = "";
        }
        this.ulis[this.index].className = "active";
        this.olis[this.index].className = "active";
    }

    Carousel.prototype.dot = function (i) {
        this.index = i;
        for (let j = 0; j < this.ulis.length; j++) {
            this.ulis[j].className = "";
            this.olis[j].className = "";
        }
        this.ulis[this.index].className = "active";
        this.olis[this.index].className = "active";
    }
    let c = new Carousel("box",2000);//调用
</script>

</html>

原型链:

什么是原型:
任何对象天生自带的属性__prroto__的值
任何函数自带的属性prototype的值
构造函数的原型和对象的原型是同一个对象




任何原型天生自带属性constructor:原型找构造函数的

function Person(){
	
}
var p  =new Person();
console.log(p.__proto__ ===Person.prototype);
console.log(Person.prototype.constructor)

原型也是对象,只要是对象就有原型
console.log(Person.prototype.proto);
也可以控制台打印p,不断找,应该只有原型的原型

原型也是对象,对象就有原型,这样就形成了一条链式结构,叫原型链(访问属性和方法的时候用:当一个对象访问一个树形或方法的时候,逐级往上找,一直到null,null也没有返回undefined)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值