为了账号安全,请及时绑定邮箱和手机立即绑定

JS面向对象及简单选项卡的面向对象写法

标签:
JavaScript

面向对象
对象的组成:1.方法:过程,动态的;2.属性:状态,静态的
难点:this

    /*
    * 将对象的创建封装为一个函数
    * 属性作为参数传递进去
    * */
    function CreatePerson(name) {
        //1.原料
        this.name = name;
        //2.加工
        this.showName = function () {
            alert(this.name);
        }
        //3.出厂
        //return obj;
        //此处默认返回this
    }

    let p1 = new CreatePerson('Kangkang');
    //new后面调用的函数叫做构造函数
    p1.showName();
    let p2 = new CreatePerson('Michael');
    p2.showName();

    //当new调用一个函数时,函数中的this就是new创建的对象,而且函数的返回值直接就是this
    //被称为隐式返回

对象的引用&原型
在上例中若判断p1.showNam===p2.showName,它们都是指的方法showName本身,但是却返回false。因为两者引用地址不同。每个对象的方法有自己的内存地址。
基本类型:赋值是值的复制
对象类型:赋值不仅是值的赋值,也是引用的传递
原型:去改写对象下面公用的方法或者属性,让公用的方法或者属性在内存中只存在一份。提高性能。
可类比于CSS
原型:CSS中的class
普通方法:CSS中的style

    //普通函数写法
    let arr = [1,2,3,4,5];
    arr.sum1 = function () {
        let result = 0;
        for(let i=0;i<this.length;i++){
            result += this[i];
        }
        return result;
    }
    /*
    * 原型:prototype,要写在构造函数下面
    */
    let arr1 = [1,2,3];
    let arr2 = [1,2];
    Array.prototype.sum2 = function () {
        let result = 0;
        for(let i=0;i<this.length;i++){
            result += this[i];
        }
        return result;
    }
    alert(arr1.sum2());
    alert(arr2.sum2());
    //普通函数的优先级高于原型

将上面的creatPerson改为原型写法

    function CreatPerson2(name) {
        this.name = name;
    }
    CreatPerson2.prototype.showName2 = function () {
        alert(this.name);
    }
/*
* 面向对象写法:
* function 构造函数(){
*       this.属性;
* }
*
* 构造函数.原型.方法 = function(){};
*
* let 对象1 = new 构造函数();
* 对象1.方法();
* */

改为面向对象写法时要注意的this问题

oDiv. = function () {
    this: oDiv
}

oDiv. = show;
function show() {
    this: oDiv             //this依然是oDiv
}

oDiv. = function () {
    show();
}                           //this在function show中,
function show() {           //而show是在function中被调用,this指向window
    this: window
}

选项卡的实现

非面向对象代码写法

let oParent = document.getElementById('div1');
let aInput = oParent.getElementsByTagName('input');
let aDiv = oParent.getElementsByTagName('div');

for(let i=0;i<aInput.length;i++){
    aInput[i].index = i;
    aInput[i]. = function () {
        for(let i=0; i<aInput.length;i++){
            aInput[i].className = '';
            aDiv[i].style.display = 'none';
        }
        this.className = 'active';
        aDiv[this.index].style.display = 'block';
    }
}

修改为面向对象思路

//尽量不要出现函数嵌套函数
//可以有全局变量
//把中不是赋值的语句放到单独函数中

将代码初步修改后出现this的指向问题,分析及代码如下

/*
* 全局变量就是属性
* 函数就是方法
* Onload中创建对象
* 改this指向问题:事件或者定时器,尽量让面向对象中的this指向对象
* */
window. = function () {
    let t1 = new Tab();
    t1.create();
}
function Tab(id) {
    //此处的传参id增加复用性
    //这里面的this是在构造函数里面
    // new一个构造函数时调用,this指向创建出来的对象
    this.oParent = document.getElementById(id);
    this.aInput = this.oParent.getElementsByTagName('input');
    this.aDiv = this.oParent.getElementsByTagName('div');
}
Tab.prototype.init = function () {
    //t1.init()调用,this指向t1
    for(let i=0;i<this.aInput.length;i++){
        this.aInput[i].index = i;
        this.aInput[i]. = this.change;
    }
}
Tab.prototype.change = function () {
    //在this.aInput[i]. = this.change调用
    // this指向点击的按钮,即上文中的this.aInput[i]
    //应将this调整为对象t1
    //xxx处依然应当为按钮
    for(let i=0; i<this.aInput.length;i++){
        this.aInput[i].className = '';
        this.aDiv[i].style.display = 'none';
    }
    xxx.className = 'active';
    this.aDiv[xxx.index].style.display = 'block';
}

调整方法的调用方式,即可改变this的指向

Tab.prototype.create = function () {
    for(let i=0;i<this.aInput.length;i++){
        const This = this;//保存当前作为对象的this,通过赋值方式传递给change
        this.aInput[i].index = i;
        this.aInput[i]. = function () {
            This.change(this);//修改了此处的调用方式,让change的this指向对象
        }
    }
}
Tab.prototype.change = function (obj) {
    //将按钮作为参数传递进来
    for(let i=0; i<this.aInput.length;i++){
        this.aInput[i].className = '';
        this.aDiv[i].style.display = 'none';
    }
    obj.className = 'active';
    this.aDiv[obj.index].style.display = 'block';
}
点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消