实现一个 1/4 圆、任意弧度的扇形
有多种实现方法,这里选几种简单方法(我看得懂的)实现。
水平垂直居中
实现子元素的水平垂直居中
清除浮动
要求:清除浮动
可以通过 clear:both
或 BFC 实现
弹出框
使用 CSS 写一个弹出框效果
页面内容
弹出框
导航栏
要求:一个
div
内部放很多水平div
,并可以横向滚动。
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前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
最后
技术是没有终点的,也是学不完的,最重要的是活着、不秃。零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。
技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。有需要面试题资料的朋友点击这里可以免费领取。
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-AlMdLMq3-1713782104817)]
[外链图片转存中…(img-HYTm6GtE-1713782104818)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上前端开发知识点,真正体系化!
[外链图片转存中…(img-c4yqaK18-1713782104818)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:前端)
[外链图片转存中…(img-nYr9Cd0h-1713782104819)]
最后
技术是没有终点的,也是学不完的,最重要的是活着、不秃。零基础入门的时候看书还是看视频,我觉得成年人,何必做选择题呢,两个都要。喜欢看书就看书,喜欢看视频就看视频。最重要的是在自学的过程中,一定不要眼高手低,要实战,把学到的技术投入到项目当中,解决问题,之后进一步锤炼自己的技术。
技术学到手后,就要开始准备面试了,找工作的时候一定要好好准备简历,毕竟简历是找工作的敲门砖,还有就是要多做面试题,复习巩固。有需要面试题资料的朋友点击这里可以免费领取。
[外链图片转存中…(img-cBdpgEgr-1713782104819)]