【面试】前端面试常考手写题 - JavaScript - CSS

【面试】前端面试常考手写题 - JavaScript - CSS_第1张图片

持续更新中…

文章目录

  • 1. CSS布局
    • 1.1 盒子居中对齐
    • 1.2 两栏布局
    • 1.3 三栏布局
      • 双飞翼
      • 圣杯
    • 1.4 品字布局
    • 1.5 画图
      • 三角形
      • 圆形
      • 筛子
  • 2. JS手写函数
    • 2.1 手写原生
      • Promise
      • Promise.all
      • Promise.race
      • Promise.resolve()
      • Promise.reject()
      • call
      • apply
      • bind
      • new
      • instanceof
      • Object.create
      • Object.assign
      • setTimeout模拟setInterval
      • setInterval模拟setTimeout
      • map
      • reduce
      • filter
      • find
      • findIndex
      • every
      • some
    • 2.2 自定义函数
      • 类型判断
      • 数组去重unique
      • 数组合并方法 cancat
      • 数组切片方法 slice
      • 数组扁平化flatten
      • 数组分块方法 chunk
      • 数组取差集 difference
      • 删除数组部分元方法 pull pullAll
      • 得到数组部分元方法 drop dropRight
      • 深拷贝
      • 深比较
      • 自定义合并对象mergeObject
      • 节流
      • 防抖
      • 寄生式组合继承
      • ES6继承
      • 一次性执行函数
      • 柯里化
      • Ajax
      • 随机数
      • 字符串反转
      • 检测回文字符串
      • 截取字符串
  • 3. 场景题
    • 自定义DOM事件监听
      • 自定义事件总线eventBus
      • 自定义消息订阅与发布PubSub
    • url转object
    • object转url
    • 手机号3-3-4分割
    • 千分位格式化数字
    • 解析url参数
    • 实现一个通用函数判断数据类型
    • 字符串转驼峰
    • 生成随机字符串
    • 生成随机hex颜色
    • rgb颜色转成hex
    • hex颜色转成rgb

1. CSS布局

1.1 盒子居中对齐

【CSS】实现盒子居中对齐的七种方法

知道父子盒子宽高的情况

定位:子绝父相,margin 纯计算【不推荐】

.parent {
   
  width: 500px;
  height: 500px;
  position: relative;
}

.child {
   
  width: 200px;
  height: 200px;
  position: absolute;
  margin-top:150px;
  margin-left:150px;
}

父子盒子宽高不知道的情况

定位 + margin

.parent {
   
  position: relative;
}

.child {
   
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  margin: auto;
}

定位 + transform

.parent {
   
  position: relative;
}

.child {
   
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

flex

.parent {
   
  display: flex;
  justify-content: center;
  align-items: center;
}

table-cell

.parent {
   
    display: table-cell;
    vertical-align: middle;
}
.child {
   
  margin: 0 auto;
}

inline-block

.parent {
   
  text-align: center;
  line-height: 500px;
}
.child {
   
  display: inline-block;
}

1.2 两栏布局

1.3 三栏布局

【CSS】看了C站CSDN源码,这次带你彻底搞清楚经典的 双飞翼布局 与 圣杯布局 - margin负值 - 浮动 - padding

双飞翼

<header>头部header>
<div class="main ">
  <div class="center">主区域div>
div>
<div class="left ">左区域div>
<div class="right ">右区域div>
<footer>底部footer>
header {
   
  background-color: pink;
}

.main {
   
  width: 100%;
  float: left;
  background-color: skyblue;
}

.center {
   
  margin: 0 100px;
}

.left {
   
  width: 100px;
  background-color: green;
  float: left;
  margin-left: -100%;
}

.right {
   
  width: 100px;
  background-color: red;
  float: left;
  margin-left: -100px;
}

footer {
   
  background-color: pink;
  clear: both
}

圣杯

<header>头部header>
<div class="clearfix wrapper">
  <div class="center">主区域div>
  <div class="left">左区域div>
  <div class="right">右区域div>
div>
<footer>底部footer>
header {
   
  background-color: pink;
}

.clearfix::after {
   
  content: '';
  display: block;
  clear: both;
}

.wrapper {
   
  padding: 0 100px;
}

.center {
   
  width: 100%;
  background-color: skyblue;
  float: left;
}

.left {
   
  background-color: green;
  float: left;
  width: 100px;
  margin-left: -100%;
  position: relative;
  left: -100px;
}

.right {
   
  width: 100px;
  background-color: red;
  float: left;
  margin-right: -100px;
}

footer {
   
  background-color: pink;
}

1.4 品字布局

1.5 画图

三角形

圆形

筛子

2. JS手写函数

2.1 手写原生

Promise

/**
 * Promise构造函数
 * @param {*} executor 执行器函数(同步执行)(resolve, reject) => {}
 */
function Promise(executor) {
   

  const self = this; // 保存当前实例对象的this的值
  // 添加属性
  self.PromiseState = PENDING // 给promise对象指定status属性,初始值为pending
  self.PromiseResult = null // 给promise对象指定一个用于存储结果数据的属性
  self.callbacks = [] // 存的是对象 每个元素的结构:{onResolved() {}, onRejected() {}}

  /**
   * executor内部定义成功时调用的函数
   * @param {*} value 成功的值
   * @returns 
   */
  function resolve(value) {
   
    // 如果当前状态不是pending,直接结束
    if (self.PromiseState !== PENDING) return
    // 1. 修改对象的状态(promiseState)为 fulfilled
    self.PromiseState = RESOLVED 
    // 2. 设置对象结果值(promiseResult)为 value
    self.PromiseResult = value
    // 如果有待执行的callback函数,立即【异步】执行回调函数onResolved
    if (self.callbacks.length > 0) {
   
      setTimeout(() => {
    // 放入队列中执行所有成功的回调
        self.callbacks.forEach(callbacksObj => {
   
          callbacksObj.onResolved(value)
        })
      }, 0)
    }
  }
  
  /**
   * executor内部定义失败时调用的函数
   * @param {*} reason 失败的原因
   * @returns 
   */
  function reject(reason) {
   
    // 如果当前状态不是pending,直接结束
    if (self.PromiseState !== PENDING) return
    // 1. 修改对象的状态(promiseState)为 rejected
    self.PromiseState = REJECTED
    // 2. 设置对象结果值(promiseResult)为 reason
    self.PromiseResult = reason
    // 如果有待执行的callback函数,立即【异步】执行回调函数onRejected
    if (self.callbacks.length > 0) {
   
      setTimeout(() => {
    // 放入队列中执行所有失败的回调
        self.callbacks.forEach(callbacksObj => {
   
          callbacksObj.onRejected(reason)
        })
      }, 0)
    }
  }
  
  // 立即【同步】执行executor函数
  try {
   
    executor(resolve, reject)
  } catch(error) {
    // 如果执行器抛出异常,promise对象变成rejected状态
    reject(error)
  }
}

Promise.all

接收的是一个promise数组promises
当传入的所有promise都成功,则返回一个成功的promise,值为所有成功promise的值的数组【注意顺序】
当传入的promises中有一个不成功,则返回一个失败的promise,其值为这个失败的promise的值

思路
首先创建一个结果数组,再创建要给计数变量

Promise.all = function(promises){
   
	return new Promise((resolve, reject)=>{
   
		let count = 0
		const values = []
		for(let i = 0; i < promises.length; i++){
   
			Promise.resolve(promise[i]).then(value => {
   
				count++
				values[i] = value
				if(count === promises.length){
   
					resolve(values)
				}
			}, reason => {
    
				reject(reason) 
			})
		}
	})
}

Promise.race

接收的是一个promise数组promises
返回一个promise,状态和值都取决于第一个改变状态的promise

Promise.race = function(promises) {
   
	return new Promise((resolve, reject)=>{
   
		for(let i = 0; i < promises.length; i++) {
   
			Promise.resolve(promises[i]).then(value => {
   
				resolve(value)
			}, reason => {
   
				reject(reason)
			}
		}
	})
}

Promise.resolve()

Promise.resolve = function(value) {
   
	return new Promise((resolve, reject) => {
   
		if(value instanceof Promise) {
   
			value.then(resolve, reject)
		} else {
   
			resolve(value)
		}
	}
}

Promise.reject()

Promise.reject = function(reason) {
   
	return new Promise((resolve, reject)=> {
   
		reject(reason)
	})
}

call

function call(Fn, obj, ...args) {
   
  if (obj === undefined || obj === null) {
   
    // 表示全局对象(ES11新增特性)
    obj = globalThis;
  }
  // 为 obj 添加临时的方法
  obj.temp = Fn;
  // 调用 temp 方法
  let result = obj.temp(...args);
  // 删除tempfangfa
  delete obj.temp;
  // 返回执行结果
  return result;
}
Function.prototype.myCall = function(context,...args){
   
    let cxt = context || window;
    //将当前被调用的方法定义在cxt.func上.(为了能以对象调用形式绑定this)
    //新建一个唯一的Symbol变量避免重复
    let func = Symbol() 
    cxt[func] = this;
    args = args ? args : []
    //以对象调用形式调用func,此时this指向cxt 也就是传入的需要绑定的this指向
    const res = args.length > 0 ? cxt[func](...args) : cxt[func]();
    //删除该方法,不然会对传入对象造成污染(添加该方法)
    delete cxt[func];
    return res;
}

apply

function apply(Fn, obj, arr) {
   
  if (obj === undefined || obj === null) {
   
    obj = globalThis;
  }
  // 为obj添加临时方法
  obj.temp = Fn;
  // 执行方法
  let result = obj.temp(...arr);
  

你可能感兴趣的:(JavaScript,面试,面试,javascript,css)