每日前端手写题--day13

如果你最近想要换工作或者巩固一下自己的前端知识基础,不妨和我一起参与到每日刷题的过程中来,如何?

第13天要刷的手写题如下:

  1. 不使用临时变量交换两数的值

  2. 实现一个简单的双向数据绑定

  3. 实现一个简单的哈希路由

下面是我自己写的答案:

1. 不使用临时变量交换变量的值

如果是交换两个整数的值:

let a =20;
let b =15;
a = a ^ b;
b = a ^ b;
a = a ^ b;

如果是交换两个number的值:

let a =20.1;
let b =15.1;
a = a + b;
b = a - b;
a = a - b; 

交换两个变量的值:

[a ,b] = [b, a];

[arr[i], arr[j]] = [arr[j], arr[i]]; 

2. 实现一个简单的双向数据绑定功能

分以下步骤进行:

  1. 创建展示需要的数据结构obj和input以及span标签

  2. 通过propertyDescriptor设置obj的setter和getter

  3. 监听input的keyup事件,在其回调中实现obj的setter

const obj = {};

const input = document.createElement('input');
const span = document.createElement('span');

Object.defineProperty(obj, 'text', {
    configurable: true,
    set(v) {
        span.innerText = v;
        input.value = v;
    },
});

input.addEventListener('keyup', (e) => {
    obj.text = e.target?.value;
});

document.body.append(input, span);

  • 需要注意的点:setter和writable或者value不能同时出现在propertyDescriptor中!

  • 也就是说使用PropertyDescriptor的setter和addEventListener是可以实现数据的双向绑定的!

升级版本:使用Proxy -- 唯一的区别就是将Object.defineProperty换成了const proxyObh = new Proxy(obj, {})

const obj = { text: '' };

const input = document.createElement('input');
const span = document.createElement('span');

const proxyObj = new Proxy(obj, {
  set(target, key, value) {
    target[key] = value;
    if (key === 'text') {
      span.innerText = value;
      input.value = value;
    }
    return true;
  },
});

input.addEventListener('keyup', (e) => {
  proxyObj.text = e.target?.value;
});

document.body.append(input, span);


最直观的升级就是,可以对obj的多个属性进行一次性的绑定了,尽管使用Object.defineProperties也可以达到相同的效果!

3. 实现简单的哈希路由

  • 首先必须明确,实现哈希路由到底是在问什么?

  • 也就是哈希路由的本质是什么。对于这道题来说,它实际上是想问:在页面的哈希值发生变化的时候能够执行预先存储的回调函数

  • 所以需要实现两个功能:
      1. 预先存储路由和对应的回调函数

      1. 当路由地址发生变化的时候能够找到当前的url对应的回调并执行

  • 根据上面的分析,需要构件的类中应该包括如下的属性和方法:
    • routes: 是一个哈希表,存放的是路由地址和回调之间的关系

    • currentHash:当前的路由地址

    • storeRoute (path, cb):将路由地址和回调函数对应起来

    • freshRoute ():调用当前路由地址对应的回调函数

    • 最后监听window上的load时间和hashchange事件,当事件发生的时候调用freshRoute方法

class Route {
    constructor () {
        this.routes ={};
        this.currentHash = '';
        
        window.addEventListener('load', this.refresh, false); 
        window.addEventListener('hashchange', this.refresh, false);
    }

    
    store (path, cb) {
        this.routes[path] = cb ?? Function();
    }

    
    refresh () {
        this.currentHash = location.hash.slice(1) || '/';
        this.routes[this.currentHash]();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Web面试那些事儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值