2024年JavaScript进阶之OOP(一),这些面试题你会吗

紧跟潮流

大前端和全栈是以后前端的一个趋势,懂后端的前端,懂各端的前端更加具有竞争力,以后可以往这个方向靠拢。

这边整理了一个对标“阿里 50W”年薪企业高级前端工程师成长路线,由于图片太大仅展示一小部分

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

console.log(ldh); // {uname: “刘德华”, age: 18}

console.log(zxy); // {uname: “张学友”, age: 20}

ldh.sing(‘冰雨’) //刘德华唱冰雨

zxy.sing(‘李香兰’) //张学友唱李香兰

2.6 注意事项

  1. 在ES6中类没有变量提升,所以必须先定义类才能通过类实例化对象

  2. 类里面共有的属性和方法一定要加this使用

  3. 类里边的this指向问题

  • constructor里面的this指向实例对象

  • 方法里面的this指向这个方法的调用者

this指向问题案例

var that;

var _that;

class Star {

constructor(uname, age) {

// constructor 里面的this 指向的是 创建的实例对象

that = this;

console.log(this);

this.uname = uname;

this.age = age;

// this.sing();

this.btn = document.querySelector(‘button’);

this.btn.onclick = this.sing;

}

sing() {

// 这个sing方法里面的this 指向的是 btn 这个按钮,因为这个按钮调用了这个函数

console.log(this);

console.log(that.uname); // that.uname刘德华 that里面存储的是constructor里面的this

}

dance() {

// 这个dance里面的this 指向的是实例对象 ldh 因为ldh 调用了这个函数

_that = this;

console.log(this); //Star {uname: “刘德华”, age: undefined, btn: button}

}

}

var ldh = new Star(‘刘德华’);

console.log(that === ldh); //true

ldh.dance();

console.log(_that === ldh); // true

三、继承


现实中的继承:子承父业,比如我们都继承了父亲的姓

程序中的继承:子类可以继承父类的一些属性和方法

继承中,如果实例化子类输出一个方法,先看子类有没有这个方法,如果有就先执行子类的方法,如果子类里面没有,就去查找父类有没有这个方法,如果有,就执行父类的这个方法(就近原则

3.1 语法

class Father{

//父类

}

class son extends father{

//子类继承父类

}

示例:

// 1.类的继承

class Father{

constructor(){

}

money(){

console.log(100);

}

}

class Son extends Father{

}

let son = new Son()

son.money() //100

3.2 super关键字

super关键字用于访问和调用对象父类上的函数。可以调用父类的构造函数也可以调用父类的普通函数

示例:调用构造函数

class Father{

constructor(x,y){

this.x = x

this.y = y

}

sum(){

console.log(this.x + this.y)

}

}

class Son extends Father{

constructor(x,y){

// 这里不能访问父类的 this,父类的sum函数中的this是父类的,子类值没有传递进去

// this.x = x // 报错

// this.y = y // 报错

super(x,y);//调用父类中的构造函数

}

}

let son = new Son(1,2)

son.sum() // 3

示例:调用普通函数

// super调用父类的普通函数

class Father {

say() {

return ‘我是爸爸’

}

}

class Son extends Father {

say() {

//调用父类的普通方法

console.log(super.say()); //我是爸爸

}

}

let son = new Son()

3.3 继承方法的同时扩展方法

需求:继承父类的加法方法的同时,自己扩展一个减法方法。

注意事项:调用父类的函数时,super必须在子类this之前调用(父亲必须放在之前)

// 父类加法操作

class Father {

constructor(x, y) {

this.x = x

this.y = y

}

sum() {

console.log(this.x + this.y);

}

}

// 子类继承父类加法方法的同时扩展减法操作

class Son extends Father {

constructor(x, y) {

// 调用父类的构造函数 super必须在子类this之前调用(父亲必须放在之前)

super(x, y)

this.x = x

this.y = y

}

subtract() {

console.log(this.x - this.y);

}

}

let son = new Son(5, 3)

son.subtract() // 2

son.sum() // 8

四、Tab栏 案例


功能描述:

  1. 点击Tab栏能实现切换

  2. Tab栏和内容 点击右上角×号能删除当前栏目和内容

  3. 点击加号能实现增加Tab栏功能

  4. 双击Tab栏,可以编辑Tab栏名称

  5. 双击内容,可编辑内容

4.1 点击Tab栏能实现切换 Tab栏和内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4Tbb77xW-1614115973066)(ES6.assets/1.ee56c713.gif)]

4.2 点击右上角×号能删除当前栏目和内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5DIwvFk9-1614115973070)(ES6.assets/2.42074edd.gif)]

4.3 点击加号能实现增加Tab栏效果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mcCTVvOA-1614115973073)(ES6.assets/3.8f2ffa50.gif)]

4.4 双击Tab栏,可以编辑Tab栏名称

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-csnPZeE4-1614115973078)(ES6.assets/4.41c0a92c.gif)]

4.5 双击内容,可编辑内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KEmDUzkB-1614115973079)(ES6.assets/5.191ba8e3.gif)]

4.6 细节方面:

  1. 删除一个栏目后默认选中前一个栏目

  2. 新增的栏目也能实现基本功能

  3. 当默认选中的是第一个,并且删除的时候,选中删除后的第一个

  4. 在编辑Tab名称的时候,回车键也能确认编辑

  5. 新增的栏目默认选中

样例获取:

  1. Demo演示传送门

  2. 下面有实例代码!

源码和教程来自b站pink老师,传送门

是不是太棒了,在21世纪是不是 很久没有遇到博主这样贴心的人才了吧! 那还愣着干什么,点赞关注走一波啊! [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YBgTs74Y-1614115973081)(ES6.assets/20201105194549612.png)]

实例代码


JS:tab.js

let that = null

class Tab {

constructor(id) {

// 1.获取元素

this.main = document.querySelector(id)

this.tabadd = this.main.querySelector(‘.tabadd’)

// li的父元素

this.ul = this.main.querySelector(‘.fisrstnav ul:first-child’)

// section福元素

this.fatherSection = this.main.querySelector(‘.tabscon’)

that = this

this.init()

}

// 初始化

init() {

this.updateNode();

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

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

this.lis[i].setAttribute(‘data-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.tabadd.onclick = this.add

}

// 更新数据列表

updateNode() {

this.lis = this.main.querySelectorAll(‘li’)

this.sections = that.main.querySelectorAll(‘section’)

this.remove = this.main.querySelectorAll(‘.icon-guanbi’)

this.spans = this.main.querySelectorAll(‘.fisrstnav li span:nth-child(1)’)

console.log('this.spans: ', this.spans);

}

// 1.切换功能

toggleTab() {

that.clearClass()

this.className = ‘liactive’

that.sections[this.getAttribute(‘data-index’)].className = ‘conactive’

}

clearClass() {

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

this.lis[i].className = ‘’

this.sections[i].className = ‘’

}

}

// 2.添加

add() {

// 清除所有选中

that.clearClass()

// 1.创建 li元素和section元素

let random = Math.round(Math.random() * 100, 3)

let li = ‘

  • Tab
  • let section = ‘

    新内容’ + random + ‘

    // 2.追加元素 使用 insertAdjacentHTML 支持字符串形式

    that.ul.insertAdjacentHTML(‘beforeend’, li)

    that.fatherSection.insertAdjacentHTML(‘beforeend’, section)

    // 更新

    that.init()

    }

    // 3.删除

    removeTab(e) {

    // 阻止时间冒泡 防止触发li的点击切换事件

    e.stopPropagation();

    let index = this.parentNode.getAttribute(‘data-index’)

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

    that.lis[index].remove()

    that.sections[index].remove()

    that.init()

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

    // 该句核心思想,如果删除的是当前选中项,删除过后页面上没有 .liactive 进入判断,直接return 否则跳过

    if (document.querySelector(‘.liactive’)) return;

    // 当我们删除过后,设置默认选中其一个

    index == 0 ? index = 0 : index–

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

    }

    // 4.编辑

    editTab(e) {

    // 双击禁止选中文字

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

    let str = this.innerHTML;

    console.log(this);

    this.innerHTML = ‘’

    let input = this.children[0]

    input.value = str

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

    // 按下回车

    input.addEventListener(‘keyup’, function (e) {

    if (e.keyCode === 13) {

    // 手动调用表单失去焦点事件

    this.blur();

    }

    })

    input.onblur = function () {

    debugger

    this.parentNode.innerHTML = this.value

    }

    }

    }

    #let tab = new Tab(‘#tab’);

    HTML:index.html

    面向对象 Tab

    Js 面向对象 动态添加标签页

    • 测试1
    • 测试2
    • 测试3
    • +

      学习分享,共勉

      题外话,毕竟我工作多年,深知技术改革和创新的方向,Flutter作为跨平台开发技术、Flutter以其美观、快速、高效、开放等优势迅速俘获人心

      开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

      A-Compatible" content=“ie=edge”>

      面向对象 Tab

      Js 面向对象 动态添加标签页

      • 测试1
      • 测试2
      • 测试3
      • +

        学习分享,共勉

        题外话,毕竟我工作多年,深知技术改革和创新的方向,Flutter作为跨平台开发技术、Flutter以其美观、快速、高效、开放等优势迅速俘获人心

        开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

        [外链图片转存中…(img-JL9wq5iO-1714816192553)]

      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

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

      抵扣说明:

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

      余额充值