js/css/sass/html

JS

https://www.cnblogs.com/chenwenhao/p/11253403.html

typeof判断哪个类型会出错

Object.prototype.toString.call()判断哪个类型会出错

js堆与栈

栈内存主要用于存储各种基本类型的变量,包括Boolean、Number、String、Undefined、Null以及对象变量的指针,堆主要存储object

new出来的对象开辟内存存在堆上,对应地址是指针存的内容

token

token 也称作令牌,由uid+time+sign[+固定参数]
token 的认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式, 非常适合于 REST API 的场景. 所谓无状态就是服务端并不会保存身份认证相关的数据。

  • 组成
    uid: 用户唯一身份标识
    time: 当前时间的时间戳
    sign: 签名, 使用 hash/encrypt 压缩成定长的十六进制字符串,以防止第三方恶意拼接
    固定参数(可选): 将一些常用的固定参数加入到 token 中是为了避免重复查库

  • 存放
    token在客户端一般存放于localStorage,cookie,或sessionStorage中。在服务器一般存于数据库中

  • token认证流程
    token 的认证流程与cookie很相似

用户登录,成功后服务器返回Token给客户端。
客户端收到数据后保存在客户端
客户端再次访问服务器,将token放入headers中
服务器端采用filter过滤器校验。校验成功则返回请求数据,校验失败则返回错误码

token优势/与cookie,session区别

但token不同,token是开发者为了防范csrf而特别设计的令牌,浏览器不会自动添加到headers里,攻击者也无法访问用户的token,所以提交的表单无法通过服务器过滤,也就无法形成攻击

闭包

销毁闭包 : 就是把返回出来的函数重新赋值
例如res = null这样闭包就会被销毁销毁闭包

let/const/var

var定义的变量,没有块的概念,可以跨块访问, 不能跨函数访问。
let定义的变量,只能在块作用域里访问,不能跨块访问,也不能跨函数访问。
const用来定义常量,使用时必须初始化(即必须赋值),只能在块作用域里访问,而且不能修改

var存在变量提升,而let和const不存在变量提升
var声明的变量会添加进window对象中,而let和const声明的变量不会
let和const声明的变量不可以重复声明
let和const声明的变量存在暂时性死区
const声明的基础类型不可修改,const声明的引用类型只能修改该引用类型的属性而不能给该变量重新赋值(const确定了一个地址,该地址不能被修改)
let和const存在块级作用域,而var不存在
let在for循环中每循环一次就会重新声明一次(因为let有块级作用域)

参数传递按值传递

ECMAScript中所有函数的参数都是按值传递的——《高程3》,其实对于参数是对象的情况,实际上也是按值传递,把传参的指针复制出一个完全独立的变量,只是存的内容和传参对象地址一摸一样

JWT

jwt的缺点

如果不用jwt,我直接存用户的状态可不可以

xss,csrfs

设计模式的分类

创建型:帮助我们优雅地创建对象

工厂模式

单例模式

原型模式

结构型:帮助我们优雅地设计代码结构

适配器模式

外观模式

装饰器模式

行为型:模块之间行为的模式总结,帮助我们组织模式行为

观察者模式(Observer pattern)

一对多的关系

所谓观察者模式,其实就是为了实现松耦合(loosely coupled)。
面向接口编程,实现松耦合

观察者模式里面,changed()方法所在的实例对象,就是被观察者(Subject,或者叫Observable),它只需维护一套观察者(Observer)的集合,这些Observer实现相同的接口,Subject只需要知道,通知Observer时,需要调用哪个统一方法就好了
图片说明

举个例子,这个实现方式就类似于原始的劳动市场,应聘者是订阅者到劳动市场把简历投递到一个个公司的邮箱里,而公司相当与发布者,当有一个hc时,公司就开始一个个联系各个应聘者,完成一次发布

发布订阅模式(Publish–subscribe pattern)

一对多的关系
发布订阅模式其实只是观察者模式中的一种具体的实现方式

大概很多人都和作者一样,觉得发布订阅模式里的Publisher,就是观察者模式里的Subject,而Subscriber,就是Observer。Publisher变化时,就主动去通知Subscriber

在发布订阅模式里,发布者,并不会直接通知订阅者,换句话说,发布者和订阅者,彼此互不相识。

  • 发布者只需告诉Broker,我要发的消息,topic是AAA;

  • 订阅者只需告诉Broker,我要订阅topic是AAA的消息;

于是,当Broker收到发布者发过来消息,并且topic是AAA时,就会把消息推送给订阅了topic是AAA的订阅者。当然也有可能是订阅者自己过来拉取,看具体实现
图片说明
也就是说,发布订阅模式里,发布者和订阅者,不是松耦合,而是完全解耦的。

这样公司就不需要在管理订阅者,完全交由事件中心处理。 订阅者和发布者完全解耦,发布者不需要关注怎么绑定订阅者,和如何发布给订阅者, 订阅时不需要双方都在场直接绑定 。这样能大大让代码逻辑更为清晰。同时可以将事件进行集中管理,可以进行统一的逻辑操作

对比观察者模式和发布

图片说明

观察者模式

发布订阅者模式

  • 从表面上看:

    观察者模式里,只有两个角色 —— 观察者 + 被观察者
    而发布订阅模式里,却不仅仅只有发布者和订阅者两个角色,还有一个经常被我们忽略的 —— 经纪人Broker

  • 往更深层次讲:

    观察者和被观察者,是松耦合的关系
    发布者和订阅者,则完全不存在耦合

  • 从使用层面上讲:

    观察者模式,多用于单个应用内部
    发布订阅模式,则更多的是一种跨应用的模式(cross-application pattern),比如我们常用的消息中间件

技巧型:优化代码的技巧

Object.assign()

策略模式

迭代器模式


src和href的区别

引用css文件时:href="cssfile.css"
网站链接:href="http://www.webpage.com"

引用js文件时:src="myscript.js"
引用图片:src="mypic.jpg"

它们之间的主要区别可以用这样一句话来概括:src用于替代这个元素,而href用于建立这个标签与外部资源之间的关系。

  • href (Hypertext Reference) 超文本引用
    href这个属性指定web资源的位置,从而定义当前元素(如锚点a)或当前文档(如链接)与目标锚点或目标资源之间的联系

  • src (Source)源
    这个属性是将资源嵌入到当前文档中元素所在的位置

Promise

第一问:了解 Promise 吗?

了解Promise,Promise是一种异步编程的解决方案,有三种状态,pending(进行中)、resolved(已完成)、rejected(已失败)。
当Promise的状态由pending转变为resolved或reject时,会执行相应的方法
Promised的特点是只有异步操作的结果,可以决定当前是哪一种状态,任务其他操作都无法改变这个状态,也是“Promise”的名称的由来,同时,状态一旦改变,就无法再次改变状态

第二问:Promise 解决的痛点是什么?

Promise解决的痛点:
1)回调地狱,代码难以维护, 常常第一个的函数的输出是第二个函数的输入这种现象,是为解决异步操作函数里的嵌套回调(callback hell)问题,代码臃肿,可读性差,只能在回调里处理异常
2)promise可以支持多个并发的请求,获取并发请求中的数据
3)promise可以解决可读性的问题,异步的嵌套带来的可读性的问题,它是由异步的运行机制引起的,这样的代码读起来会非常吃力
4)promise可以解决信任问题,对于回调过早、回调过晚或没有调用和回调次数太少或太多,由于promise只能决议一次,决议值只能有一个,决议之后无法改变,任何then中的回调也只会被调用一次,所以这就保证了Promise可以解决信任问题
5)Promise最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了

第三问:Promise 解决的痛点还有其他方法可以解决吗?如果有,请列举。

Promise 解决的痛点还有其他方法可以解决,比如setTimeout、事件监听、回调函数、Generator函数,async/await
2)setTimeout:缺点不精确,只是确保在一定时间后加入到任务队列,并不保证立马执行。只有执行引擎栈中的代码执行完毕,主线程才会去读取任务队列
3)事件监听:任务的执行不取决于代码的顺序,而取决于某个事件是否发生
4)Generator函数虽然将异步操作表示得很简洁,但是流程管理却不方便(即何时执行第一阶段、何时执行第二阶段)。即如何实现自动化的流程管理
5)async/await

第四问:Promise 如何使用?

1)创造一个Promise实例
2)Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数
3)可用Promise的try和catch方法预防异常

第五问:Promise 的业界实现都有哪些?

1) promise可以支持多个并发的请求,获取并发请求中的数据
2)promise可以解决可读性的问题,异步的嵌套带来的可读性的问题,它是由异步的运行机制引起的,这样的代码读起来会非常吃力

 第六问: Promise的问题?解决办法?

promise的问题为:promise一旦执行,无法中途取消promise的错误无法在外部被捕捉到,只能在内部进行预判处理promise的内如何执行,监测起来很难解决办法正是因为这些原因,ES7引入了更加灵活多变的async,await来处理异步

第七问:老旧浏览器没有Promise全局对象增么办?果辛辛苦苦写完代码,测试后发现不兼容IE6、7增么办?难道要推翻用回调函数重写?

当然不是这样,轮子早就造好了。我们可以使用es6-promise-polyfill。es6-promise-polyfill可以使用页面标签直接引入,可以通过es6的import方法引入(如果你是用webpack),在node中可以使用require引入,也可以在Seajs中作为依赖引入。引入这个polyfill之后,它会在window对象中加入Promise对象。这样我们就可以全局使用Promise了。

 第八问:怎么让一个函数无论promise对象成功和失败都能被调用?

  • 笨方法:在两个回调中分别执行一次函数。
  • 推荐方式:扩展一个 Promise.finally(),finally方法用于指定不管Promise对象最后状态如何,都会执行的操作,它与done方法的最大区别在于,它接受一个普通的回调函数作为参数,该函数不管怎样都必须执行。避免同样的语句需要在then()和catch()中各写一次的情况。

```
//添加finally方法
Promise.prototype.finally=function (callback) {
var p=this.constructor;
return this.then(//只要是promise对象就可以调用then方法
value => p.resolve(callback()).then(() => value),
reason => p.resolve(callback()).then(() => {throw reason})
);
}
```

对finally方法的理解:
(1)p.resolve(callback())这句函数callback已经执行
(2)finally方法return的是一个promise对象,所以还可以继续链式调用其他方法
(3)对于Promise.resolve方法Promise.resolve('foo');
等价于
new Promise(resolve => resolve('foo'));所以可以通过then方法的回调函数 接受 实例对象返回的参数 比如:Promise.resolve(function(){console.log(2);}).then(function(cb){cb()})

第九问:红灯3秒亮一次,绿灯1秒亮一次,黄灯2秒亮一次;如何让三个灯不断交替重复亮灯?(用Promise实现)三个亮灯函数已经存在:function red() {

console.log('red');

}
function green() {
console.log('green');
}
function yellow() {
console.log('yellow');
}
解析 红灯3秒亮一次,绿灯1秒亮一次 ,黄灯2秒亮一次,意思就是3秒执行一次red函数,2秒执行一次green函数,1秒执行一次yellow函数,不断交替重复亮灯,意思就是按照这个顺序一直执行这3个函数,这步可以利用递归来实现。 答案:function red() {
console.log('red');
}
function green() {
console.log('green');
}
function yellow() {
console.log('yellow');
}

var light = function (timmer, cb) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
cb();
resolve();
}, timmer);
});
};

var step = function () {
Promise.resolve().then(function () {
return light(3000, red);
}).then(function () {
return light(2000, green);
}).then(function () {
return light(1000, yellow);
}).then(function () {
step();
});
}

step();
第十问:实现 mergePromise 函数,把传进去的数组按顺序先后执行,并且把返回的数据先后放到数组 data 中。const timeout = ms => new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, ms);
});

const ajax1 = () => timeout(2000).then(() => {
console.log('1');
return 1;
});

const ajax2 = () => timeout(1000).then(() => {
console.log('2');
return 2;
});

const ajax3 = () => timeout(2000).then(() => {
console.log('3');
return 3;
});

const mergePromise = ajaxArray => {
// 在这里实现你的代码

};

mergePromise([ajax1, ajax2, ajax3]).then(data => {
console.log('done');
console.log(data); // data 为 [1, 2, 3]
});

// 要求分别输出
// 1
// 2
// 3
// done
// [1, 2, 3]解析 首先 ajax1 、ajax2、ajax3 都是函数,只是这些函数执行后会返回一个 Promise,按题目的要求我们只要顺序执行这三个函数就好了,然后把结果放到 data 中,但是这些函数里都是异步操作,想要按顺序执行,然后输出 1,2,3并没有那么简单,看个例子。function A() {
setTimeout(function () {
console.log('a');
}, 3000);
}

function B() {
setTimeout(function () {
console.log('b');
}, 1000);
}

A();
B();

// b
// a答案// 保存数组中的函数执行后的结果
var data = [];

// Promise.resolve方法调用时不带参数,直接返回一个resolved状态的 Promise 对象。
var sequence = Promise.resolve();

ajaxArray.forEach(function (item) {
// 第一次的 then 方法用来执行数组中的每个函数,
// 第二次的 then 方法接受数组中的函数执行后返回的结果,
// 并把结果添加到 data 中,然后把 data 返回。
// 这里对 sequence 的重新赋值,其实是相当于延长了 Promise 链
sequence = sequence.then(item).then(function (res) {
data.push(res);
return data;
});
})

// 遍历结束后,返回一个 Promise,也就是 sequence, 他的 [[PromiseValue]] 值就是 data,
// 而 data(保存数组中的函数执行后的结果) 也会作为参数,传入下次调用的 then 方法中。
return sequence;第十一问:封装一个异步加载图片的方法function loadImageAsync(url) {
return new Promise(function(resolve,reject) {
var image = new Image();
image.onload = function() {
resolve(image)
};
image.onerror = function() {
reject(new Error('Could not load image at' + url));
};
image.src = url;
});
}

async await

  • await在等什么?

    如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。
    如果它等到的是一个 Promise 对象,await 就忙起来了,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。

ajax,axios

axios是通过promise实现对ajax技术的一种封装,就像jQuery实现ajax封装一样
ajax技术实现了网页的局部数据刷新,axios实现了对ajax的封装
axios是ajax ajax不止axios

优缺点:

ajax:
本身是针对MVC的编程,不符合现在前端MVVM的浪潮
基于原生的XHR开发,XHR本身的架构不清晰,已经有了fetch的替代方案
JQuery整个项目太大,单纯使用ajax却要引入整个JQuery非常的不合理
(采取个性化打包的方案又不能享受CDN服务

axios:
从 node.js 创建 http 请求
支持 Promise API
客户端支持防止CSRF
提供了一些并发请求的接口(重要,方便了很多的操作)

  • 拦截器
    请求发送之前:
    1、比如添加token之类的请求头信息
    2、添加每次请求loading等

响应处理之前:
错误码的处理

为什么vue不使用ajax用axios:

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,本质上也是对原生XHR的封装,
只不过它是Promise的实现版本,符合最新的ES规范,它本身具有以下特征:
从浏览器中创建 XMLHttpRequest
支持 Promise API
客户端支持防止CSRF
提供了一些并发请求的接口(重要,方便了很多的操作)
从 node.js 创建 http 请求
拦截请求和响应
转换请求和响应数据
取消请求
自动转换JSON数据

跨域

JSONP如何接受参数?

nginx部署

CSS

CSS3新特性

在布局方面新增了flex布局
在选择器方面新增了例如first-of-type,nth-child等选择器
在盒模型方面添加了box-sizing来改变盒模型,
在动画方面增加了animation,2d变换,3d变换等,
在颜色方面添加透明,rbga等,在字体方面允许嵌入字体和设置字体阴影,最后还有媒体查讯等

浏览器怎么解析css

link和@import

  • link标签让浏览器知道这是个样式表文件,html的解析和渲染不会暂停,css文件的加载是同时进行的,这不同于在style标签里面的内置样式;

  • 用@import添加的样式是在页面载入之后再加载,这可能会导致页面因重新渲染而闪烁。所以我们建议使用link而不是@import

布局题

三等分响应式布局

flex

flex:flex-grow flex-shrink flex-basis;

文档流

文档流中:内联元素默认从左到右流,遇到阻碍或者宽度不够自动换行,继续按照从左到右的方式布局。块级元素单独占据一行,并按照从上到下的方式布局

脱离文档流

脱离文档流是指,这个标签脱离了文档流的管理。不受文档流的布局约束了,并且更重要的一点是,这个标签在原文档流中所占的空间也被清楚掉了。

那么,这几种脱离文档的的定位机制包括哪些呢?

方法

float
position:absolute

sass

说起 Sass ,我们经常指的是两种事物:一种 css 预处理器和一种语言

Sass (预处理器)有两种不同的语法:

  • Sass,一种缩进语法

    缩进语法有很多有趣的点。首先,它更短并且更易于书写

    .element-a
      color: hotpink
    
      .element-b
          float: left
  • SCSS,一种 CSS-like 语法

    Sassy CSS。这个语法带来了对 CSS 友好的语法,试图弥合 Sass 和 CSS 之间的鸿沟

易于阅读 的,因为它是有语义的,而不是用符号表示。当你读到 @mixin,你就会知道这是一个 mixin 声明;当你看到 @include ,你就是在引用一个 mixin

// Variable
$primary-color: hotpink;

// Mixin
@mixin border-radius($radius) {
    -webkit-border-radius: $radius;
    -moz-border-radius: $radius;
    border-radius: $radius;
}

.my-element {
    color: $primary-color;
    width: 100%;
    overflow: hidden;
}

.my-other-element {
    @include border-radius(5px);
}

HTML

HTML5新特性

语义化标签:header, article, footer, nav, aside, section
增强型表单:日期,颜色等
新增video和audio标签
Canvas绘图
SVG绘图
地理定位
WebSocket

 Canvas 与 SVG 的比较(H5)

下表列出了 canvas 与 SVG 之间的一些不同之处。

Canvas

依赖分辨率
不支持事件处理器
弱的文本渲染能力
能够以 .png 或 .jpg 格式保存结果图像
最适合图像密集型的游戏,其中的许多对象会被频繁重绘
Canvas 是逐像素进行渲染的。

在 canvas 中,一旦图形被绘制完成,它就不会继续得到浏览器的关注。如果其位置发生变化,那么整个场景也需要重新绘制,包括任何或许已被图形覆盖的对象。

SVG

不依赖分辨率
支持事件处理器
最适合带有大型渲染区域的应用程序(比如谷歌地图)
复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
不适合游戏应用

 浏览器怎么解析html

场景题

有三个函数A,B,C,怎么顺序调用,说了promise的链式调用,然后说那100个函数怎么办....

数组保存异步函数,函数里面调用next函数,next函数里面shift数组弹出函数,执行

假设现在有个美国用户访问页面出现故障,你看不见的情况下,怎么在前端体现....

全部评论

相关推荐

影04714:把图书管理系统那个项目经验内容适当的减少掉,然后改成据为己有不要说团队项目,因为图书管理系统这类常见的谁来了都能独立写出来,提问能圆过来即可
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务