Web前端最全作为一名优秀的前端需要了解哪几种设计模式?(2),2024年最新Web前端最新实习面试经验总结

刷面试题

刷题的重要性,不用多说。对于应届生或工作年限不长的人来说,刷面试题一方面能够尽可能地快速自己对某个技术点的理解,另一方面在面试时,有一定几率被问到相同或相似题,另外或多或少也能够为自己面试增加一些自信心,可见适当的刷题是很有必要的。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

  • 前端字节跳动真题解析

  • 【269页】前端大厂面试题宝典

最后平时要进行自我分析与评价,做好职业规划,不断摸索,提高自己的编程能力和抽象思维能力。大厂面试远没有我们想的那么困难,摆好心态,做好准备,你也可以的。

@testDec

class Demo {

// …

}

function testDec(target) {

target.isDec = true

}

console.log(Demo.isDec)

//输出true

打印出来了true,说明@testDec这个装饰器已经成功了,函数是个装饰器,用@testDec给Demo装饰了一遍。这个target其实就是class Demo,然后给她加一个isDec。

拆解后就是下面的内容:

// 装饰器原理

@decorator

class A {}

// 等同于

class A {}

A = decorator(A) || A;

装饰器参数的形式

@testDec(false)

class Demo {

}

function testDec(isDec) {

return function (target) {

target.isDec = isDec

}

}

console.log(Demo.isDec);

验证是否是一个真正的装饰器模式需要验证以下几点:

1.将现有对戏那个和装饰器进行分离,两者独立存在

2.符合开放封闭原则

2. 适配器模式

适配器模式:旧接口格式和使用者不兼容,中间加一个适配转换接口。

比如国外的插座跟国内的插座不一样,我们需要买个转换器去兼容。

适配器模式

上代码:

class Adaptee {

specificRequest() {

return ‘德国标准的插头’;

}

}

class Target {

constructor() {

this.adaptee = new Adaptee();

}

request() {

let info = this.adaptee.specificRequest();

return ${info} -> 转换器 -> 中国标准的插头

}

}

// 测试

let client = new Target();

client.request();

结果:

德国标准的插头 -> 转换器 -> 中国标准的插头

场景上可封装旧接口:

// 自己封装的ajax,使用方式如下:

ajax({

url: ‘/getData’,

type: ‘Post’,

dataType: ‘json’,

data: {

id: ‘123’

}

}).done(function(){

})

// 但因为历史原因,代码中全都是:

// $.ajax({…})

这个时候需要一个适配器

// 做一层适配器

var $ = {

ajax: function (options) {

return ajax(options)

}

}

3. 代理模式

代理模式:使用者无权访问目标对象,中间加代理,通过代理做授权和控制。

明星经纪人:比如有个演出,要请明星,要先联系经纪人。

或者理解为:为一个对象提供一个代用品或者占位符,以便控制对它的访问。例如图片懒加载、中介等。代理模式

/**

  • pre:代理模式

  • 小明追求A,B是A的好朋友,小明比不知道A什么时候心情好,不好意思直接将花交给A,

  • 于是小明将花交给B,再由B交给A.

*/

// 花的类

class Flower{

constructor(name){

this.name = name

}

}

// 小明拥有sendFlower的方法

let Xioaming = {

sendFlower(target){

var flower = new Flower(“玫瑰花”)

target.receive(flower)

}

}

// B对象中拥有接受花的方法,同时接收到花之后,监听A的心情,并且传入A心情好的时候函数

let B = {

receive(flower){

this.flower =flower

A.listenMood(()=>{

A.receive(this.flower)

})

}

}

// A接收到花之后输出花的名字

let A = {

receive(flower){

console.log(A收到了${flower.name} )

// A收到了玫瑰花

},

listenMood(func){

setTimeout(func,1000)

}

}

Xioaming.sendFlower(B)

虚拟代理用于图片的预加载

图片很大,页面加载时会空白,体验不好,所以我们需要个占位符,来短暂替代这个图片,等图片加载好了放上去。

let myImage = (function(){

let img = new Image

document.body.appendChild(img)

return {

setSrc:(src)=>{

img.src = src

}

}

})()

let imgProxy =(function(){

let imgProxy = new Image

// 这个地方我使用了setTimeout来增强演示效果,否则本地加载太快,根本看不到。

imgProxy.οnlοad=function(){

setTimeout(()=>{

myImage.setSrc(this.src)

},2000)

}

return (src)=>{

myImage.setSrc(“…/…/img/bgimg.jpeg”)

imgProxy.src=src

}

})()

imgProxy(“…/…/img/background-cover.jpg”)

ES6 Proxy

其实在ES6中,已经有了Proxy,这个内置的函数。我们来用一个例子来演示一下他的用法。这是一个明星代理的问题。

let star={

name : “张XX”,

age:25,

phone : “1300001111”

}

let agent = new Proxy(star,

{

get:function(target,key){

if(key === “phone”){

return “18839552597”

}else if(key === “name”){

return “张XX”

}else if(key === “price”){

return “12W”

}else if(key === “customPrice”){

return target.customPrice

}

},

set:function(target,key,value){

if(key === “customPrice”){

if(value < “10”){

console.log(“太低了!!!”)

return false

}else{

target[key] = value

return true

}

}

}

}

)

console.log(agent.name)

console.log(agent.price)

console.log(agent.phone)

console.log(agent.age)

agent.customPrice = “12”

console.log(agent)

console.log(agent.customPrice)

设计原则验证

代理类和目标类分离,隔离开目标类和使用者

符合开放封闭原则


行为型模式


1. 策略模式

策略模式是一种简单却常用的设计模式,它的应用场景非常广泛。我们先了解下策略模式的概念,再通过代码示例来更清晰的认识它。

策略模式由两部分构成:一部分是封装不同策略的策略组,另一部分是 Context。通过组合和委托来让 Context 拥有执行策略的能力,从而实现可复用、可扩展和可维护,并且避免大量复制粘贴的工作。

策略模式

策略模式的典型应用场景是表单校验中,对于校验规则的封装。接下来我们就通过一个简单的例子具体了解一下:

/**

  • 登录控制器

*/

function LoginController() {

this.strategy = undefined;

this.setStrategy = function (strategy) {

this.strategy = strategy;

this.login = this.strategy.login;

}

}

/**

  • 用户名、密码登录策略

*/

function LocalStragegy() {

this.login = ({ username, password }) => {

console.log(username, password);

// authenticating with username and password…

}

}

/**

  • 手机号、验证码登录策略

*/

function PhoneStragety() {

this.login = ({ phone, verifyCode }) => {

console.log(phone, verifyCode);

// authenticating with hone and verifyCode…

}

}

/**

  • 第三方社交登录策略

*/

function SocialStragety() {

this.login = ({ id, secret }) => {

console.log(id, secret);

// authenticating with id and secret…

}

}

const loginController = new LoginController();

// 调用用户名、密码登录接口,使用LocalStrategy

app.use(‘/login/local’, function (req, res) {

loginController.setStrategy(new LocalStragegy());

loginController.login(req.body);

});

// 调用手机、验证码登录接口,使用PhoneStrategy

app.use(‘/login/phone’, function (req, res) {

loginController.setStrategy(new PhoneStragety());

loginController.login(req.body);

});

// 调用社交登录接口,使用SocialStrategy

app.use(‘/login/social’, function (req, res) {

loginController.setStrategy(new SocialStragety());

loginController.login(req.body);

});

从以上示例可以得出使用策略模式有以下优势:

  1. 方便在运行时切换算法和策略

  2. 代码更简洁,避免使用大量的条件判断

  3. 关注分离,每个strategy类控制自己的算法逻辑,strategy和其使用者之间也相互独立

2. 观察者模式

观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一或一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。典型代表vue/react等。

使用观察者模式的好处:

  1. 支持简单的广播通信,自动通知所有已经订阅过的对象。

  2. 目标对象与观察者存在的是动态关联,增加了灵活性。

  3. 目标对象与观察者之间的抽象耦合关系能够单独扩展以及重用。

观察者模式当然给元素绑定事件的addEventListener()也是一种:

target.addEventListener(type, listener [, options]);

Target就是被观察对象Subject,listener就是观察者Observer。

观察者模式中Subject对象一般需要实现以下API:

  • subscribe(): 接收一个观察者observer对象,使其订阅自己

  • unsubscribe(): 接收一个观察者observer对象,使其取消订阅自己

  • fire(): 触发事件,通知到所有观察者

用JavaScript手动实现观察者模式:

// 被观察者

function Subject() {

this.observers = [];

}

Subject.prototype = {

// 订阅

subscribe: function (observer) {

this.observers.push(observer);

},

// 取消订阅

unsubscribe: function (observerToRemove) {

this.observers = this.observers.filter(observer => {

return observer !== observerToRemove;

})

},

// 事件触发

fire: function () {

this.observers.forEach(observer => {

observer.call();

});

}

}

验证一下订阅是否成功:

const subject = new Subject();

function observer1() {

console.log(‘Observer 1 Firing!’);

}

function observer2() {

console.log(‘Observer 2 Firing!’);

}

subject.subscribe(observer1);

subject.subscribe(observer2);

subject.fire();

输出:

Observer 1 Firing!

Observer 2 Firing!

验证一下取消订阅是否成功:

subject.unsubscribe(observer2);

subject.fire();

输出:

Observer 1 Firing!

3. 迭代器模式

ES6中的迭代器 Iterator 相信大家都不陌生,迭代器用于遍历容器(集合)并访问容器中的元素,而且无论容器的数据结构是什么(Array、Set、Map等),迭代器的接口都应该是一样的,都需要遵循 迭代器协议

迭代器模式解决了以下问题:

  1. 提供一致的遍历各种数据结构的方式,而不用了解数据的内部结构

  2. 提供遍历容器(集合)的能力而无需改变容器的接口

迭代器模式

一个迭代器通常需要实现以下接口:

  • hasNext():判断迭代是否结束,返回Boolean

  • next():查找并返回下一个元素

为Javascript的数组实现一个迭代器可以这么写:

const item = [1, ‘red’, false, 3.14];

function Iterator(items) {

this.items = items;

this.index = 0;

}

Iterator.prototype = {

hasNext: function () {

return this.index < this.items.length;

},

next: function () {

return this.items[this.index++];

}

}

验证一下迭代器:

const iterator = new Iterator(item);

while(iterator.hasNext()){

console.log(iterator.next());

}

输出:

1, red, false, 3.14

ES6提供了更简单的迭代循环语法 for...of,使用该语法的前提是操作对象需要实现 可迭代协议(The iterable protocol),简单说就是该对象有个Key为 Symbol.iterator 的方法,该方法返回一个iterator对象。

比如我们实现一个 Range 类用于在某个数字区间进行迭代:

function Range(start, end) {

return {

[Symbol.iterator]: function () {

return {

next() {

if (start < end) {

return { value: start++, done: false };

}

return { done: true, value: end };

}

}

}

}

}

文末

如果30岁以前,可以还不知道自己想去做什么的话,那30岁之后,真的觉得时间非常的宝贵,不能再浪费时间在一些碎片化的事情上,比如说看综艺,电视剧。一个人的黄金时间也就二,三十年,不能过得浑浑噩噩。所以花了基本上休息的时间,去不断的完善自己的知识体系,希望可以成为一个领域内的TOP。

同样是干到30岁,普通人写业务代码划水,榜样们深度学习拓宽视野晋升管理。

这也是为什么大家都说30岁是程序员的门槛,很多人迈不过去,其实各行各业都是这样都会有个坎,公司永远都缺的高级人才,只用这样才能在大风大浪过后,依然闪耀不被公司淘汰不被社会淘汰。

269页《前端大厂面试宝典》

包含了腾讯、字节跳动、小米、阿里、滴滴、美团、58、拼多多、360、新浪、搜狐等一线互联网公司面试被问到的题目,涵盖了初中级前端技术点。

开源分享:【大厂前端面试题解析+核心总结学习笔记+真实项目实战+最新讲解视频】

前端面试题汇总

JavaScript

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值