常见的手写代码题集

实现一个 1/4 圆、任意弧度的扇形

有多种实现方法,这里选几种简单方法(我看得懂的)实现。

Document

水平垂直居中

实现子元素的水平垂直居中

水平垂直居中

清除浮动

要求:清除浮动

可以通过 clear:both 或 BFC 实现

清除浮动

弹出框

使用 CSS 写一个弹出框效果

Document

页面内容

弹出框

导航栏

要求:一个 div 内部放很多水平 div ,并可以横向滚动。

Document
item1
item2
item3
item4
item5
item6
item7
item8
item9

CSS 部分完,总结,Flex 无敌。


JavaScript 部分


手写 bind、call 和 apply

Function.prototype.bind = function(context, …bindArgs) {

// func 为调用 bind 的原函数

const func = this;

context = context || window;

if (typeof func !== ‘function’) {

throw new TypeError(‘Bind must be called on a function’);

}

// bind 返回一个绑定 this 的函数

return function(…callArgs) {

let args = bindArgs.concat(callArgs);

if (this instanceof func) {

// 意味着是通过 new 调用的 而 new 的优先级高于 bind

return new func(…args);

}

return func.call(context, …args);

}

}

// 通过隐式绑定实现

Function.prototype.call = function(context, …args) {

context = context || window;

context.func = this;

if (typeof context.func !== ‘function’) {

throw new TypeError(‘call must be called on a function’);

}

let res = context.func(…args);

delete context.func;

return res;

}

Function.prototype.apply = function(context, args) {

context = context || window;

context.func = this;

if (typeof context.func !== ‘function’) {

throw new TypeError(‘apply must be called on a function’);

}

let res = context.func(…args);

delete context.func;

return res;

}

实现一个继承

// 参考 You Dont Know JavaScript 上卷

// 基类

function Base() {

}

// 派生类

function Derived() {

Base.call(this);

}

// 将派生类的原型的原型链挂在基类的原型上

Object.setPrototypeOf(Derived.prototype, Base.prototype);

实现一个 new

// 手动实现一个 new 关键字的功能的函数 _new(fun, args) --> new fun(args)

function _new(fun, …args) {

if (typeof fun !== ‘function’) {

return new Error(‘参数必须是一个函数’);

}

let obj = Object.create(fun.prototype);

let res = fun.call(obj, …args);

if (res !== null && (typeof res === ‘object’ || typeof res === ‘function’)) {

return res;

}

return obj;

}

实现一个 instanceof

// a instanceof b

function _instanceof(a, b) {

while (a) {

if (a.proto === b.prototype) return true;

a = a.proto;

}

return false;

}

手写 jsonp 的实现

// foo 函数将会被调用 传入后台返回的数据

function foo(data) {

console.log(‘通过jsonp获取后台数据:’, data);

document.getElementById(‘data’).innerHTML = data;

}

/**

  • 通过手动创建一个 script 标签发送一个 get 请求

  • 并利用浏览器对

*/

(function jsonp() {

let head = document.getElementsByTagName(‘head’)[0]; // 获取head元素 把js放里面

let js = document.createElement(‘script’);

js.src = ‘http://domain:port/testJSONP?a=1&b=2&callback=foo’; // 设置请求地址

head.appendChild(js); // 这一步会发送请求

})();

// 后台代码

// 因为是通过 script 标签调用的 后台返回的相当于一个 js 文件

// 根据前端传入的 callback 的函数名直接调用该函数

// 返回的是 ‘foo(3)’

function testJSONP(callback, a, b) {

return ${callback}(${a + b});

}

ajax 的实现

感觉这个有点无聊了……

// Asynchronous Javascript And XML

function ajax(options) {

// 选项

var method = options.method || ‘GET’,

params = options.params,

data = options.data,

url = options.url + (params ? ‘?’ + Object.keys(params).map(key => key + ‘=’ + params[key]).join(‘&’) : ‘’),

async = options.async === false ? false : true,

success = options.success,

headers = options.headers;

var request;

if (window.XMLHttpRequest) {

request = new XMLHttpRequest();

} else {

request = new ActiveXObject(‘Microsoft.XMLHTTP’);

}

request.onreadystatechange = function() {

/**

readyState:

0: 请求未初始化

1: 服务器连接已建立

2: 请求已接收

3: 请求处理中

4: 请求已完成,且响应已就绪

status: HTTP 状态码

**/

if (request.readyState === 4 && request.status === 200) {

success && success(request.responseText);

}

}

request.open(method, url, async);

if (headers) {

Object.keys(headers).forEach(key => request.setRequestHeader(key, headers[key]));

}

method === ‘GET’ ? request.send() : request.send(data);

}

// e.g.

ajax({

method: ‘GET’,

url: ‘…’,

success: function(res) {

console.log(‘success’, res);

},

async: true,

params: {

p: ‘test’,

t: 666

},

headers: {

‘Content-Type’: ‘application/json’

}

})

reduce 的实现

function reduce(arr, callback, initial) {

let i = 0;

let acc = initial === undefined ? arr[i++] : initial;

for (; i < arr.length; i++) {

acc = callback(acc, arr[i], i, arr);

}

return acc;

}

实现 generator 的自动执行器

要求是 yield 后面只能是 Promise 或 Thunk 函数,详见 es6.ruanyifeng.com/#docs/gener…

function run(gen) {

let g = gen();

function next(data) {

let result = g.next(data);

if (result.done) return result.value;

if (result.value instanceof Promise) {

result.value.then(data => next(data));

} else {

result.value(next);

}

}

return next();

}

// ======== e.g. ==========

function func(data, cb) {

console.log(data);

cb();

}

function *gen() {

let a = yield Promise.resolve(1);

console.log(a);

let b = yield Promise.resolve(2);

console.log(b);

yield func.bind(null, a + b);

}

run(gen);

/**

output:

1

2

3

**/

节流

老生常谈了,感觉没必要写太复杂

/**

  • 节流函数 限制函数在指定时间段只能被调用一次

  • 用法 比如防止用户连续执行一个耗时操作 对操作按钮点击函数进行节流处理

*/

function throttle(func, wait) {

let timer = null;

return function(…args) {

if (!timer) {

func(…args);

timer = setTimeout(() => {

timer = null;

}, wait);

}

}

}

防抖

/**

  • 函数调用后不会被立即执行 之后连续 wait 时间段没有调用才会执行

  • 用法 如处理用户输入

*/

function debounce(func, wait) {

let timer = null;

return function(…args) {

if (timer) clearTimeout(timer); // 如果在定时器未执行期间又被调用 该定时器将被清除 并重新等待 wait 秒

timer = setTimeout(() => {

func(…args);

}, wait);

}

}

手写 Promise

简单实现,基本功能都有了。

const PENDING = 1;

const FULFILLED = 2;

const REJECTED = 3;

function MyPromise(executor) {

let self = this;

this.resolveQueue = [];

this.rejectQueue = [];

this.state = PENDING;

this.val = undefined;

function resolve(val) {

if (self.state === PENDING) {

setTimeout(() => {

self.state = FULFILLED;

self.val = val;

self.resolveQueue.forEach(cb => cb(val));

});

}

}

function reject(err) {

if (self.state === PENDING) {

setTimeout(() => {

self.state = REJECTED;

self.val = err;

self.rejectQueue.forEach(cb => cb(err));

});

}

}

try {

// 回调是异步执行 函数是同步执行

executor(resolve, reject);

} catch(err) {

reject(err);

}

}

MyPromise.prototype.then = function(onResolve, onReject) {

let self = this;

// 不传值的话默认是一个返回原值的函数

onResolve = typeof onResolve === ‘function’ ? onResolve : (v => v);

onReject = typeof onReject === ‘function’ ? onReject : (e => { throw e });

if (self.state === FULFILLED) {

return new MyPromise(function(resolve, reject) {

setTimeout(() => {

try {

let x = onResolve(self.val);

if (x instanceof MyPromise) {

x.then(resolve);

} else {

resolve(x);

}

} catch(e) {

reject(e);

}

});

});

}

if (self.state === REJECTED) {

return new MyPromise(function(resolve, reject) {

setTimeout(() => {

try {

let x = onReject(self.val);

if (x instanceof MyPromise) {

x.then(resolve);

} else {

resolve(x);

}

} catch(e) {

reject(e);

}

});

});

}

if (self.state === PENDING) {

return new MyPromise(function(resolve, reject) {

self.resolveQueue.push((val) => {

try {

let x = onResolve(val);

if (x instanceof MyPromise) {

x.then(resolve);

} else {

resolve(x);

}

} catch(e) {

reject(e);

}

});

self.rejectQueue.push((val) => {

try {

let x = onReject(val);

if (x instanceof MyPromise) {

x.then(resolve);

} else {

resolve(x);

}

} catch(e) {

reject(e);

}

});

});

}

}

MyPromise.prototype.catch = function(onReject) {

return this.then(null, onReject);

}

MyPromise.all = function(promises) {

return new MyPromise(function(resolve, reject) {

let cnt = 0;

let result = [];

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

promises[i].then(res => {

result[i] = res;

if (++cnt === promises.length) resolve(result);

}, err => {

reject(err);

})

}

});

}

MyPromise.race = function(promises) {

return new MyPromise(function(resolve, reject) {

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

promises[i].then(resolve, reject);

}

});

}

MyPromise.resolve = function(val) {

return new MyPromise(function(resolve, reject) {

resolve(val);

});

}

MyPromise.reject = function(err) {

return new MyPromise(function(resolve, reject) {

reject(err);

})

}

实现一个路由 - Hash

实现原理就是监听 url 的哈希值变化了

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里获取!

ise.all = function(promises) {

return new MyPromise(function(resolve, reject) {

let cnt = 0;

let result = [];

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

promises[i].then(res => {

result[i] = res;

if (++cnt === promises.length) resolve(result);

}, err => {

reject(err);

})

}

});

}

MyPromise.race = function(promises) {

return new MyPromise(function(resolve, reject) {

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

promises[i].then(resolve, reject);

}

});

}

MyPromise.resolve = function(val) {

return new MyPromise(function(resolve, reject) {

resolve(val);

});

}

MyPromise.reject = function(err) {

return new MyPromise(function(resolve, reject) {

reject(err);

})

}

实现一个路由 - Hash

实现原理就是监听 url 的哈希值变化了

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

[外链图片转存中…(img-EDkLZhRF-1712714935847)]

[外链图片转存中…(img-BbtFRwrv-1712714935847)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!

[外链图片转存中…(img-A4J5RZXT-1712714935848)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)

最后

前端CSS面试题文档,JavaScript面试题文档,Vue面试题文档,大厂面试题文档,需要的读者可以戳这里获取!

[外链图片转存中…(img-mTiEuUAM-1712714935848)]

[外链图片转存中…(img-5SJ1pVd6-1712714935848)]

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值