自学JS的小白,问大神们一个面向对象的问题!

武大路 2022-04-18 13:05:35

下面有段JS代码我差不多也算明白,但就是有个问题比较晕,就是this的指向问题,有的时候用this有的时候用that比较晕有点分不清,大神们有什么好的办法区分吗?教教我,谢谢了!

var that;

class Tab {

    constructor(id) {

        // 获取元素

        that = this;

        this.main = document.querySelector(id);

        this.add = this.main.querySelector('.tabadd');

        // li的父元素

        this.ul = this.main.querySelector('.fisrstnav ul:first-child');

        // section 父元素

        this.fsection = this.main.querySelector('.tabscon');

        this.init();

    }

    init() {

            this.updateNode();

            // init 初始化操作让相关的元素绑定事件

            this.add.onclick = this.addTab;

            for (var i = 0; i < this.lis.length; i++) {

                this.lis[i].index = i;

                this.lis[i].onclick = this.toggleTab;

                this.remove[i].onclick = this.removeTab;

                this.spans[i].ondblclick = this.editTab;

                this.sections[i].ondblclick = this.editTab;

 

            }

        }

        // 因为我们动态添加元素 需要从新获取对应的元素

    updateNode() {

            this.lis = this.main.querySelectorAll('li');

            this.sections = this.main.querySelectorAll('section');

            this.remove = this.main.querySelectorAll('.icon-guanbi');

            this.spans = this.main.querySelectorAll('.fisrstnav li span:first-child');

        }

        // 1. 切换功能

    toggleTab() {

            // console.log(this.index);

            that.clearClass();

            this.className = 'liactive';

            that.sections[this.index].className = 'conactive';

        }

        // 清除所有li 和section 的类

    clearClass() {

            for (var i = 0; i < this.lis.length; i++) {

                this.lis[i].className = '';

                this.sections[i].className = '';

            }

        }

        // 2. 添加功能

    addTab() {

            that.clearClass();

            // (1) 创建li元素和section元素

            var random = Math.random();

            var li = '<li class="liactive"><span>新选项卡</span><span class="iconfont icon-guanbi"></span></li>';

            var section = '<section class="conactive">测试 ' + random + '</section>';

            // (2) 把这两个元素追加到对应的父元素里面

            that.ul.insertAdjacentHTML('beforeend', li);

            that.fsection.insertAdjacentHTML('beforeend', section);

            that.init();

        }

        // 3. 删除功能

    removeTab(e) {

            e.stopPropagation(); // 阻止冒泡 防止触发li 的切换点击事件

            var index = this.parentNode.index;

            console.log(index);

            // 根据索引号删除对应的li 和section   remove()方法可以直接删除指定的元素

            that.lis[index].remove();

            that.sections[index].remove();

            that.init();

            // 当我们删除的不是选中状态的li 的时候,原来的选中状态li保持不变

            if (document.querySelector('.liactive')) return;

            // 当我们删除了选中状态的这个li 的时候, 让它的前一个li 处于选定状态

            index--;

            // 手动调用我们的点击事件  不需要鼠标触发

            that.lis[index] && that.lis[index].click();

        }

        // 4. 修改功能

    editTab() {

        var str = this.innerHTML;

        // 双击禁止选定文字

        window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();

        // alert(11);

        this.innerHTML = '<input type="text" />';

        var input = this.children[0];

        input.value = str;

        input.select(); // 文本框里面的文字处于选定状态

        // 当我们离开文本框就把文本框里面的值给span

        input.onblur = function() {

            this.parentNode.innerHTML = this.value;

        };

        // 按下回车也可以把文本框里面的值给span

        input.onkeyup = function(e) {

            if (e.keyCode === 13) {

                // 手动调用表单失去焦点事件  不需要鼠标离开操作

                this.blur();

            }

        }

    }

 

}

new Tab('#tab');

...全文
98 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
丰云 2022-04-18
  • 打赏
  • 举报
回复

如果js是第一血,还好理解,要是你是从其他高级语言转js,的确会在this指代上犯迷糊。。。。
js虽然是动态解释性语言,但它也是一个真面向对象的语言,一切都是对象。
注意:js里面,function也是对象,这是跟其他高级静态语言的一个显著区别!
大部分的情况下,我们可以这样理解:谁调起这个方法(function),方法里面的this就是指代谁!
注意,方法里面的this,是调用方法的对象,而不是方法本身,也不是定义方法的对象!

武大路 2022-04-18
  • 举报
回复
@丰云 非常感谢,谁调起这个方法(function),方法里面的this就是指代谁!这个我明白。 但是 init() { this.updateNode(); // init 初始化操作让相关的元素绑定事件 this.add.onclick = this.addTab; for (var i = 0; i &lt; this.lis.length; i++) { this.lis[i].index = i; this.lis[i].onclick = this.toggleTab; this.remove[i].onclick = this.removeTab; this.spans[i].ondblclick = this.editTab; this.sections[i].ondblclick = this.editTab; } } 这段代码 中this.updateNode();为什么不能是that.updateNode();呢? 还有就是下面代码 toggleTab() { // console.log(this.index); that.clearClass(); this.className = 'liactive'; that.sections[this.index].className = 'conactive'; } 调用that.clearClass();为什么不能是this.clearClass();呢 ? 就是这点不明白
丰云 2022-04-18
  • 举报
回复
@武大路 你提供的代码里面,没有that变量的定义,因此无法判断其作用域。但大概能猜到它定义在方法外面。在无法确定运行环境的情况下,打字很难说明问题,建议你多用断点调式,自己分析归纳。注意一定要区分清楚变量的作用域以及作用域链
武大路 2022-04-18
  • 举报
回复
@丰云 谢谢,朋友!

87,988

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧