【算法】手写题

画一个三角形

  • 采用的是相邻边框连接处的均分原理,将元素的宽高设置为0
  .box1 {
    
    
        width: 0;
        height: 0;
        border: 10px solid;
        border-color: red transparent transparent transparent;
      }

去除inline-block元素间的间距

  • 我们在使用CSS把非inline-block的元素改为inline-block的时候,元素之间就会产生默认间距
  • 通过font-size:0,就可以将大部分浏览器下inline-block元素之间的间距去除

单行文本溢出时显示省略号

  • overflow:hidden;white-space:nowrap;text-overflow:ellipsis;

多行文本溢出显示省略号

  • display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; overflow:hidden;

实现三栏布局

  • 三栏布局是两边固定,中间自适应

通过position和margin

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .container {
      
      
        position: relative;
      }
      .left,
      .right {
      
      
        position: absolute;
        height: 100%;
        top: 0;
        background-color: #ff69b4;
      }
      .left {
      
      
        left: 0;
        width: 100px;
      }
      .right {
      
      
        right: 0;
        width: 200px;
      }
      .main {
      
      
        height: 100%;
        margin: 0 200px 0 100px;
        background-color: #659;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="left">left</div>
      <div class="right">right</div>
      <div class="main">main</div>
    </div>
  </body>
</html>

通过float和margin

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .container {
      
      
        width: 100%;
        height: 100%;
      }
      .left {
      
      
        float: left;
        height: 100%;
        width: 100px;
        background-color: pink;
      }

      .right {
      
      
        float: right;
        height: 100%;
        width: 200px;
        background-color: pink;
      }

      .main {
      
      
        height: 100%;
        margin: 0 200px 0 100px;
        background-color: green;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="left">left</div>
      <div class="right">right</div>
      <div class="main">main</div>
    </div>
  </body>
</html>

通过flex实现

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .container {
      
      
        display: flex;
      }
      .left {
      
      
        width: 200px;
        background-color: red;
      }
      .main {
      
      
        flex: 1;
        background-color: pink;
      }
      .right {
      
      
        width: 200px;
        background-color: red;
      }
    </style>
  </head>
  <body>
    <div class="container">
      <div class="left">left</div>
      <div class="main">main</div>
      <div class="right">right</div>
    </div>
  </body>
</html>

变量提升题

  • 变量提升,声明式函数比var的优先级更高,后创建的函数覆盖前面的函数
  • 当JavaScript代码执行时,会进行两个阶段的处理:编译阶段和执行阶段。在编译阶段,JavaScript会将函数声明和变量声明(但是还没有赋值)提升到作用域的顶部。这意味着无论函数声明和变量声明在代码中的位置如何,它们都会在执行阶段之前被处理。
  • 函数声明的优先级高于变量声明
  • 输出fn(){console.log(400)},100,100,300,400

实现边框0.5px

原理:
方法1:高度1px,背景渐变,一半有颜色,一半没颜色
linear-gradient(0deg, #f00 50%, transparent 50%);
方法2:通过transform:scaleY(.5)进行缩放垂直尺寸

深拷贝

 <!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <script>
      //判断是不是对象
      function isObject(value) {
      
      
        const valueType = typeof value; // null,object,function,array
        return (
          value !== null && (valueType === "object" || valueType === "function")
        );
      }
      function deepCopy(originValue, map = new WeakMap()) {
      
      
        //通过map解决循环引用,
        //1.如果是原始类型,直接返回
        if (!isObject(originValue)) {
      
      
          return originValue;
        }
        //2.如果是对象类型,才需要创建对象
        if (map.get(originValue)) {
      
      
          return map.get(originValue);
        }
        const newObj = Array.isArray(originValue) ? [] : {
      
      };
        map.set(originValue, newObj);
        for (const key in originValue) {
      
      
          newObj[key] = deepCopy(originValue[key], map);
        }

        return newObj;
      }
      const info = {
      
      
        name: "why",
        age: 18,
        friend: {
      
      
          name: "kobe",
          address: {
      
      
            name: "洛杉矶",
            detail: "lmp",
          },
        },
      };
      info.self = info;
      const newObj = deepCopy(info);
      console.log(newObj);
    </script>
  </body>
</html>


快速排序

/**
 * LeetCode 912: 排序数组
 * @param {number[]} nums 数组
 * @return {number[]} 排序后的数组
 */
const sortArray = function(nums) {
    
    
  // 使用内置的快速排序算法进行排序
  const quickSort = (nums, start, end) => {
    
    
    if (start >= end) {
    
    
      return;
    }
    // 选择基准元素
    const pivot = nums[start];
    let left = start + 1;
    let right = end;

    while (left <= right) {
    
    
      // 找到左侧大于等于基准元素的值
      while (left <= right && nums[left] < pivot) {
    
    
        left++;
      }
      // 找到右侧小于等于基准元素的值
      while (left <= right && nums[right] > pivot) {
    
    
        right--;
      }
      // 交换左侧和右侧的值
      if (left <= right) {
    
    
        [nums[left], nums[right]] = [nums[right], nums[left]];
        left++;
        right--;
      }
    }
    // 将基准元素放到正确的位置
    [nums[start], nums[right]] = [nums[right], nums[start]];
    // 递归排序左右两部分
    quickSort(nums, start, right - 1);
    quickSort(nums, right + 1, end);
  };

  // 调用快速排序函数进行排序
  quickSort(nums, 0, nums.length - 1);

  return nums;
};

// 测试用例
const nums = [5, 2, 3, 1];
console.log(sortArray(nums)); // 输出 [1, 2, 3, 5]

冒泡排序


function randomArray(n) {
    
    
        let result = [];
        for (let i = 0; i < n; i++) {
    
    
          result.push((Math.random() * n) | 0);
        }
        return result;
      }

      function isSorted(ary) {
    
    
        for (var i = 1; i < ary.length; i++) {
    
    
          if (ary[i] < ary[i - 1]) {
    
    
            return false;
          }
        }
        return true;
      }

      function bubbleSort(ary) {
    
    
        for (var stop = ary.length - 1; stop >= 1; stop--) {
    
    
          var isChanged = false;
          for (let i = 0; i < stop; i++) {
    
    
            if (ary[i] > ary[i + 1]) {
    
    
              isChanged = true;
              let temp = ary[i + 1];
              ary[i + 1] = ary[i];
              ary[i] = temp;
            }
          }
          if (!isChanged) {
    
    
            break;
          }
        }
        return ary;
      }

选择排序

插入排序

归并排序

手写发布订阅/事件总线

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button class="nav-btn">nav button</button>
    <script>
      class HYEventBus {
      
      
        constructor() {
      
      
          this.eventMap = {
      
      };
        }
        on(eventName, eventFn) {
      
      
          let eventFns = this.eventMap[eventName];
          if (!eventFns) {
      
      
            eventFns = [];
            this.eventMap[eventName] = eventFns;
          }
          eventFns.push(eventFn);
        }
        emit(eventName, ...args) {
      
      
          let eventFns = this.eventMap[eventName];
          if (!eventFns) return;
          eventFns.forEach((fn) => {
      
      
            fn(...args);
          });
        }

        off(eventName, eventFn) {
      
      
          let eventFns = this.eventMap[eventName];
          if (!eventFns) return;
          for (let i = 0; i < eventFns.length; i++) {
      
      
            const fn = eventFns[i];
            if (fn === eventFn) {
      
      
              eventFns.splice(i, 1);
              break;
            }
          }
          //如果eventFns已经清空了
          if (eventFns.length === 0) {
      
      
            delete this.eventMap[eventName];
          }
        }
      }
      const eventBus = new HYEventBus();

      eventBus.on("navclick", (name, age, height) => {
      
      
        console.log("navclick listener 01", name, age, height);
      });
      const click = () => {
      
      
        console.log("navclick listener 02");
      };
      eventBus.on("navclick", click);
      setTimeout(() => {
      
      
        eventBus.off("navclick", click);
      }, 5000);
      eventBus.on("asideclick", () => {
      
      
        console.log("asideclick listener");
      });

      const navBtnEl = document.querySelector(".nav-btn");
      navBtnEl.onclick = () => {
      
      
        console.log("自己监听到");
        eventBus.emit("navclick", "why", 18, 1.88);
      };
    </script>
  </body>
</html>

去重

用set

[…new Set(arr)]

数组扁平化

function flatten(arr) {
    
    
        let result = [];
        for (let i = 0; i < arr.length; i++) {
    
    
          if (Array.isArray(arr[i])) {
    
    
            result = result.concat(flatten(arr[i]));
          } else {
    
    
            result = result.concat(arr[i]);
          }
        }
        return result;
      }
const a = [1, [2, [3, 4]]];
console.log(flatten(a));

创建10个a标签,点击弹出对应序号

 let a;
      for (let i = 0; i < 10; i++) {
    
    
        a = document.createElement("a");
        a.innerHTML = i + "<br>";
        a.addEventListener("click", (e) => {
    
    
          console.log(e);
          e.preventDefault();
          alert(i);
        });
        document.body.appendChild(a);
      }

实现一个new

 function myNew(fn, ...args) {
    
    
        const obj = Object.create(fn.prototype);
        const result = fn.apply(obj, args);
        return result instanceof Object ? result : obj;
      }

      // 示例使用
      function Person(name) {
    
    
        this.name = name;
      }

      Person.prototype.sayHello = function () {
    
    
        console.log(`Hello, my name is ${
      
      this.name}.`);
      };

      const person = myNew(Person, "John");
      person.sayHello(); // 输出:Hello, my name is John.

实现connect高阶组件

import {
    
     PureComponent } from "react";
import store from "../store";
export default function connect(mapStateToProps, mapDispatchToProps) {
    
    
  //高阶组件
  return function (WrapperComponent) {
    
    
    class NewComponent extends PureComponent {
    
    
      constructor(props) {
    
    
        super(props);
        this.state = mapStateToProps(store.getState());
      }
      componentWillMount() {
    
    
        this.unsubscribe = store.subscribe(() => {
    
    
          // this.forceUpdate();
          this.setState(mapStateToProps(store.getState()));
        });
      }
      componentWillUnmount() {
    
    
        this.unsubscribe();
      }
      render() {
    
    
        const stateObj = mapStateToProps(store.getState());
        const dispatchObj = mapDispatchToProps(store.dispatch);
        return (
          <WrapperComponent {
    
    ...this.props} {
    
    ...stateObj} {
    
    ...dispatchObj} />
        );
      }
    }
    return NewComponent;
  };
}

防抖函数

节流函数

求嵌套数组的深度

实现一个promise

实现Promise.all

实现Promise.race

实现Promise.any

实现call()

实现bind()

实现apply()

Vue实现分页器

Vue实现轮播图

React实现轮播图

用React写一个tab

import {
    
    useState, Children} from 'react'
function Tabs(props) {
    
    
  var [curr, setCurr] = useState(0)
  //通过Children.toArray可以扁平化数组
  var tabs = Children.toArray(props.children)
  return (
    <div style={
    
    {
    
    border:'1px solid'}}>
      <header>
        {
    
    
          tabs.map((tab,index) => {
    
    
            return <button key={
    
    index} onClick={
    
    () =>  setCurr(index) } style={
    
    {
    
    color:index==curr?'red':'black'}}>{
    
    tab.props.label}</button>
          })
        }
      </header>
      <main>
        {
    
    tabs[curr]}
      </main>
    </div>
  )
}
function Tab(props) {
    
    
  return (
    <div>
      {
    
    props.children}
    </div>
  )
}
function App() {
    
    
  return (
      <div>
        <Tabs>
          <Tab label="foo">
            aaaa
          </Tab>
          <Tab label="bar">
            bbbb
          </Tab>
          <Tab label="baz">
            cccc
          </Tab>
        </Tabs>
      </div>
  );
}

export default App;

React实现虚拟列表

import {
    
    useState,useRef} from 'react'
function List(props) {
    
    
  var {
    
     height, itemCount, itemSize, width, children } = props

  var containerStyle = {
    
    
    height: height,
    width: width,
    overflow: 'auto',
    border: '1px solid'
  }

  var innerSize = {
    
    
    height: itemSize * itemCount,
    position: 'relative'
  }

  var wrapper = useRef()

  var [range, setRange] = useState({
    
    
    start: 0,
    end: Math.ceil(height / itemSize)
  })

  function onScroll(e) {
    
    
    var scrollTop = wrapper.current.scrollTop
    var startIndex = Math.floor(scrollTop / itemSize)
    var endIndex = startIndex + Math.ceil(height / itemSize)
    setRange({
    
    
      start: startIndex,
      end: endIndex
    })
  }

  var visible = []
  for (var i = range.start; i <= range.end; i++) {
    
    
   var element = children({
    
    
     index: i,
     style: {
    
    
       position: 'absolute',
       height: itemSize,
       width: '100%',
       top: i * itemSize
     }
   })
   visible.push(element)
  }

  return (
    <div ref={
    
    wrapper} style={
    
    containerStyle} onScroll={
    
    onScroll}>
      <div style={
    
    innerSize}>
        {
    
    visible}
      </div>
  </div>
  )
}
function App() {
    
    
  return (
      <div>
      <List
        height={
    
    150}
        itemCount={
    
    100}
        itemSize={
    
    35}
        width={
    
    300}
      >
        {
    
    
          ({
     
      index, style }) =>
            <div style={
    
    style}>Row {
    
    index}</div>
        }
      </List>
      </div>
  );
}

export default App;

实现Redux

import {
    
     createContext, useContext, useEffect, useState } from "react";
export function createStore(reducer) {
    
    
  var state; // 存储应用程序状态的变量
  var action; // 最近一次分发的操作

  state = reducer(state, action); // 使用初始状态和初始操作来初始化状态

  var subscribes = []; // 存储订阅函数的数组

  return {
    
    
    getState() {
    
    
      return state; // 返回当前的状态
    },

    dispatch(action) {
    
    
      state = reducer(state, action); // 使用传入的操作和当前状态来更新状态
      for (var sub of subscribes) {
    
    
        sub(); // 通知所有订阅者,状态已更新
      }
      return action; // 返回分发的操作
    },

    subscribe(f) {
    
    
      subscribes.push(f); // 将订阅函数添加到订阅数组中
      return () => {
    
    
        var idx = subscribes.indexOf(f);
        if (idx >= 0) {
    
    
          subscribes.splice(idx, 1); // 取消订阅函数
        }
      };
    },
  };
}

export function connnect() {
    
    }

var ReduxContext = createContext();
//创建一个名字,可以在开发工具中的组件树展示出来
ReduxContext.displayName = "ReduxContext";
export function Provider(props) {
    
    
  //<Provider store = {store}><App/></Provider>
  var {
    
     store, children } = props;
  var [Change, setChange] = useState(0);
  useEffect(() => {
    
    
    var unsub = store.subscribe(() => {
    
    
      setChange((Change) => Change + 1);
    });
    return unsub;
  }, []);

  return (
    <ReduxContext.Provider value={
    
    {
    
     store: store }}>
      {
    
    children}
    </ReduxContext.Provider>
  );
}

export function useSelector(selector) {
    
    
  var store = useContext(ReduxContext).store;
  var state = store.getState();
  return selector(state);
}

export function useDispatch() {
    
    
  var store = useContext(ReduxContext).store;
  return store.dispatch;
}

猜你喜欢

转载自blog.csdn.net/partworld/article/details/130979507