前端扫盲3,希望早日恢复视力

js基础知识

JS的变量类型

共八个大类!

  • String
  • Number
  • Boolean
  • Null
  • undefined
  • object
    • Data
    • function
    • Array
  • symbol
  • bigInt
    获取变量类型的最佳方法:Object.prototype.toString.call(temp).slice(8,-1)

日期问题

先定义一个Date对象let date=new Date()
获取一周的第几天date.getDay()
获取一月的第几天date.getDate()
获取一年第几个月date.getMonth()
年份值 date.getFullYear()
小时date.getHours()
分钟date.getMinutes()
秒钟date.getSeconds()
毫秒date.getMilliseconds()
返回总的毫秒值date.getTime()

怎么改变一个函数的this作用域

apply()

function bindThis(f,oTarget){
	return function(){
		return f.apply(oTarget,arguments)
	}
}

call()

function bindThis(f,oTarget){
	return function(){
		return f.call(oTarget,...arguments)
	}
}

bind()

function bindThis(f, oTarget) {
    return f.bind(oTarget)
}

字符串问题

获取字符串长度 str.length
删除一个字符串的左边空白字符 str.leftTrim()
获取字符串的后3位 str.substr(-3)

原型链

Javascript只有一种结构,那就是:对象。在Javascript中,每个对象都有一个指向它的原型(prototype)对象的内部链接。这个原型对象又有自己的原型,直到某个对象的原型为null为止(也就是不再有原型指向)。这种一级一级的链结构就成为原型链(prototype chain)

原型链的继承

代码仓库地址

优点:能通过instanceOf和isPrototypeOf的检测

缺点:

  • 1.SuperType中的属性页变成了SubType的prototype中的公用属性,如上面例子中的color属性,可以同时被instance1和instance2修改
  • 2.创建子类型的时候,不能向父类型的构造函数中传递参数
function SuperType(){
    this.colors=["red","blue","green"]
}
SuperType.prototype.Fun=function(){

}
function SubType(){

}

SubType.prototype = new SuperType()
let instance1= new SubType()
instance1.colors.push("black")
console.log(instance1.colors);
let instance2=new SubType()
console.log(instance2.colors);

在这里插入图片描述

借用构造函数继承

原理:在子类型构造函数的内部调用超类型构造函数
优点:解决了superType私有属性变共有的问题,可以传递参数了
缺点:方法在函数中定义,无法得到复用

function SuperType(){
    this.colors=["red","blue","green"]
}
function SubType(){
    SuperType.call(this)
}
let instance1=new SubType()
instance1.colors.push("black")
console.log(instance1.colors);
let instance2=new SubType()
console.log(instance2.colors);
-------------------------------------------
function SuperType2(name){
    this.name=name
}
function SubType2(){
    SuperType2.call(this,"41")
    this.age=24
}
let instance =new SubType2()
console.log(instance.name);
console.log(instance.age);

在这里插入图片描述

组合继承

优点:继承前两者的优点,能通过instanceOf和isPrototypeOf的检测
缺点:两次调用父构造器函数,浪费内存

// 组合继承
function SuperType(name){
    this.name=name
    this.colors=["red","blue","green"]
}

SuperType.prototype.sayName=function(){
    console.log(this.name);
}

function SubType(name,age){
    SuperType.call(this,name)  // 构造函数继承属性,二次调用
    this.age=age
}

SubType.prototype = new SuperType(); // 原型链继承,一次调用
SubType.prototype.constructor=SubType // 二次调用
SubType.prototype.sayAge=function(){
    console.log(this.age);
}

let instance1= new SubType("41",24)
instance1.colors.push("black")
console.log(instance1.colors);
instance1.sayName()
instance1.sayAge()
let instance2= new SubType("42",25)
console.log(instance2.colors);
instance2.sayName()
instance2.sayAge()

在这里插入图片描述

原型式继承

// 原型式继承
function object(o){
    function F(){}
    F.prototype=o
    return new F()
}

没必要使用构造函数的时候!我们只需要一个对象可以这么写!

寄生继承

缺点:方法在函数中定义,无法得到复用

function createAnother(orginal){
    let clone=orginal // 创建一个新对象
    clone.sayHi=function(){ //寄生
        console.log("hi!");
    }
    return clone
}
let person={
    name:"41",
    friends:["41","42","43"]
}
let anotherPerson=createAnother(person)
anotherPerson.sayHi()

在这里插入图片描述

寄生组合继承

function inheritPrototype(son,father){
    let temp=Object.create(father.prototype)
    temp.constructor=son
    son.prototype=temp
}
function SuperType(name){
    this.name=name
    this.colors=["red","blue","green"]
}
function SubType(name,age){
    SuperType.call(this,name)
    this.age=age
}
SuperType.prototype.sayName=function(){
    console.log(this.name);
}
inheritPrototype(SubType,SuperType) //实现继承
SubType.prototype.sayAge=function(){
    console.log(this.age);
}



let sub1=new SubType("41",24)
sub1.colors.push("black")
console.log(sub1.colors);
sub1.sayAge()
sub1.sayName()

let sub2=new SubType("41",24)
console.log(sub2.colors);
sub2.sayAge()
sub2.sayName()

在这里插入图片描述

算法

把一个字符串里面的所有小写变成大写

function ans(str){
    return str.toUpperCase()
}
str='123456asdsav'
console.log(ans(str));

在这里插入图片描述

把一个字符串里面所有的数字+1

function addone(str){
    let newStr=''
    str.split('').forEach(item=>{
        if(item>-1&&item<10) newStr+=(+item)+1
        else newStr+=item
    })
    return newStr
}
str='abc123456'
console.log(addone(str));

在这里插入图片描述

快排

function quick(arr,left,right){
    if(arr.length>1){
        let index=partition(arr,left,right)
        if(left<index-1){
            quick(arr,left,index-1)
        }
        if(index<right){
            quick(arr,index,right)
        }
    }
    return arr
}
function partition(arr,left,right){
    let i=left,j=right,goal=arr[left]
    while(i<=j){
        while(arr[i]<goal) i++
        while(arr[j]>goal) j--
        if(i<=j){
            [arr[i],arr[j]]=[arr[j],arr[i]]
            i++
            j--
        }
    }
    return i
}
Array.prototype.mySort=function(){ //挂载到数组上!
    return quick(this,0,this.length-1)
}
let arr=[12132,12,54654,8789,1212]
console.log(arr.mySort());

在这里插入图片描述

二分查找

求平方根

服务端知识

cookie和session

cookie和session都是用来跟踪浏览器用户身份的会话方式

Cookie工作原理

  • 1.浏览器端第一次发送请求到服务器端
  • 2.服务器端创建Cookie,该Cookie中包含用户的信息,然后将该Cookie发送到浏览器端
  • 3.浏览器端再次访问服务器端时会携带服务器端创建的Cookie
  • 4.服务器端通过Cookie中携带的数据区分不同的用户

Session工作原理

  • 1.浏览器端第一次发送请求到服务器端,服务器端创建一个Session,同时会创建一个特殊的Cookie(name为JSESSIONID的固定值,value为session对象的ID),然后将该Cookie发送至浏览器端
  • 2.浏览器端发送第N(N>1)次请求到服务器端,浏览器端访问服务器端时就会携带该name为JSESSIONID的Cookie对象
  • 3.服务器端根据name为JSESSIONID的Cookie的value来查询Session对象,从而区分不同用户

区别

CookieSession
Cookie数据存放在客户的浏览器上Session数据放在服务器上
Cookie不是很安全,别人可以分析存放在本地的Cookie进行Cookie欺骗如果考虑到安全应当使用Session
如果主要考虑到减轻服务器性能,应当使用CookieSession会在一定事件内保存在服务器上。当访问增多,会比较占用你服务器的性能
单个Cookie在客户端的限制是3K,一个站点在客户端存放的Cookie不能超过3K

所以:将登录信息等重要信息存放为SESSION;其他信息如果需要保留,可以放在Cookie中

Linux基础命令

Linux基础命令

NodeJS框架

如Express,Sail,KOA,Derby,Flatiron,Hapi,Mean.IO,Mojito,Egg.js,Midway,NEST等

MYSQL的索引类型

  • 1.普通索引
  • 2.唯一索引(值需要唯一)
  • 3.主键索引(一张表只能有一个主键)
  • 4.组合索引(最左前缀集合)
  • 5.全文索引(搭配match,against使用)

Web Server

Webserver能够解析HTTP协议。当Webserver接收到一个HTTP请求,会返回一个HTTP响应,比如送回一个HTML页面。为了处理一个请求Webserver能够响应一个静态页面或图片,进行页面跳转或者把动态响应的产生托付给一些其他的程序比如CGI脚本,JSP脚本,servlets,ASP脚本,server端JavaScript,或者一些其他的server端技术。

这些server端的程序通常产生一个HTML的响应来让浏览器能够浏览。


常用的web服务器有Apache,Nginx,Lighttpd,Tomcat,IBM websphere等,其中应用最广泛的是Apache。而Windows NT/2000/2003平台下最常用的服务器则是IIS

Apache服务器

Apache仍然是世界上用的最多的Web服务器,市场占有率达60%;
它的优势在开源代码开放,可以运行在几乎所有的Unix,Linux,Windows系统平台上;
缺点在于消耗的内存页比其他的web服务器要高。

Nginx服务器

Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-like协议下发行。
特点是:占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好,中国大陆使用nginx网站用户有:京东,新浪,网易,腾讯,淘宝等

Lighttpd服务器

Lighttpd服务器其目标是提供一个专门针对高性能网站,安全,快速,兼容性好并且灵活的Web Server环境。它具有内存开销低,CPU占用率低,效能好,以及模块丰富等特点。

Tomcat服务器

Tomcat服务器是一个开放源代码,运行servlet和JSP Web应用软件的基于java的Web应用软件容器。

IIS

IIS是一种web服务组件,其中包括Web服务器,FTP服务器,NNTP服务器和SMTP服务器,分别用于网页浏览,文件传输,新闻服务和邮件发送等方面,它使得在网络上发送信息成为一件很容易的事。但IIS只能运行在Windows平台,Linuex/Unix平台上

流行的框架

RequireJS和SeaJS的区别

  • 1.相同之处
    RequireJS和SeaJS都是模块加载器,倡导的是一种模块化开发理念,核心价值是让JavaScript的模块化开发变得更加简单自然
  • 2.不同之处
区别RequireJSSeaJS
定位有差异RequireJS想成为浏览器端的模块加载器,同时也想成为Rhino/Node等环境的模块加载器SeaJS则专注于Web浏览器端,同时通过Node扩展的方式可以很方便跑在Node服务器端
遵循的规范不同RequireJS遵循的是AMD(异步模块定义)规范SeaJS遵循的是CMD(通用模块定义)规范SeaJS的API更简洁优雅,更贴近CommonJS Modules/1.1 和Node Modules规范
社区理念有差异RequireJS在尝试让第三方类库修改自身来支持RequireJS,目前只有少数社区采纳SeaJS不强推,采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略
代码质量有差异RequireJS是没有明显的bugSeaJS是明显没有bug
对调试等的支持有差异无支持SeaJS通过插件,可以实现Fiddler中自动映射的功能,还可以实现自动combo等功能,非常方便
插件机制不同RequireJS采取的是在源码中预留接口的形式,源码中留有为插件而写的代码SeaJS采取的是插件机制则与JavaScript语言以及Node的方式一致:开放自身,让插件开发者可直接访问或修改,从而非常灵活,可以实现各种类型的插件

amd和cmd的区别

AMDCMD
AMD是在RequireJS推广过程中对模块定义的规范化产出CMD式SeaJS在推广过程中对模块定义的规范化产出
对于依赖的模块,AMD提前执行(2.0开始页可以延迟执行)CMD延迟执行
推崇依赖前置推崇依赖就近
AMD的API默认是一个当多个用CMD的API严格区分,推崇职责单一

如何理解的reactJS和vueJS?

Vue和React存在着很多的共同点:

  • 数据驱动试图
  • 组件化
  • 都使用Virtual DOM
共同点详细
数据驱动视图在jquery时代,我们需要频繁的操作DOM来实现页面效果与交互;而Vue和React解决了这一痛点,采用数据驱动视图方式,隐藏操作DOM的频繁操作。所以我们在开发时,值需要关注数据变化即可,但是二者实现方式不尽相同
组件化React与Vue都遵循组件化思想,它们把注意力放在UI层,将页面分成一些细块,这些块就是组件,组件之间的组合嵌套就形成最后的网页界面。所以在开发时都有相同的套路,比如都有父子组件传递,都有数据状态管理,前端路由,插槽等。
Virtual DOMVue与React都使用了Virtual DOM+Diff算法,不管是Vue的Template模板+option api写法,还是React的Class或者Function写法最后都是生成render函数,而render函数执行返回VNode(虚拟DOM的数据结构,本质上是颗树)

不同点

Vue和React两者虽然都是用于构建用户界面的框架,但是也有很大的差异,首先二者核心的思想就不同

  • 核心思想不同
  • 组件写法差异
  • diff算法不同
  • 响应式原理不同
1.核心思想不同

Vue定位就是尽可能降低前端开发的门槛,让更多的人能够更快速地上手开发。这就有了vue的主要特点:灵活易用的渐进式框架,进行数据拦截/代理,它对侦测数据的变化更敏感,更精确。

React从一开始的定位就是提出UI开发的新思路。React推崇函数式编程(纯组件),数据不可变以及单向数据流,当然需要双向的地方页可以手动实现,比如借助onChange和setState来实现。

由于两者核心思想的不同,所以导致Vue和React在后续设计产生了许多的差异

2.组件写法差异

React推荐的做法是JSX+inline style,也就是把HTML和CSS全都写进JavaScript中,即all in js
Vue推荐的做法是template的单文件组件格式(简单易懂,从传统前端转过来易于理解),即html,css,JS写在同一个文件(vue也支持JSX写法)

这个差异一定程序上也是由于二者核心思想不同而导致的

3.diff算法不同

diff算法入门

两者流程思路上是类似的:

  • 不同的组件产生不同的DOM结构。当type不相同时,对应DOM操作就是直接销毁老的DOM,创建新的DOM
  • 同一层次的一组子节点,可以通过唯一的key区分
React的Diff算法核心

在这里插入图片描述

  • react首先对新集合进行遍历,for( name in nextChildren)。

  • 通过唯一key来判断老集合中是否存在相同的节点。如果没有的话创建

  • 如果有的话,if (preChild === nextChild )

    • 会将节点在新集合中的位置和在老集合中lastIndex进行比较

    • 如果if (child._mountIndex < lastIndex) 进行移动操作,否则不进行移动操作。

    • 如果遍历的过程中,发现在新集合中没有,但在老集合中有的节点,会进行删除操作

Vue的Diff算法核心
  • 旧children和新children各有两个头尾的变量StartIdx和EndIdx,它们的2个变量相互比较,一共有4种比较方式。

  • 如果4种比较都没匹配,如果设置了key,就会用key进行比较,在比较的过程中,变量会往中间靠,一旦StartIdx>EndIdx表明旧children和新children至少有一个已经遍历完了,就会结束比较。
    在这里插入图片描述
    Vue2的核心Diff算法采用了双端比较的算法,同时从新旧children的两端开始进行比较,借助key值找到可复用的节点,再进行相关操作。相比React的Diff算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅。

4.响应式原理不同

Vue

  • Vue依赖收集,自动优化,数据可变
  • Vue递归监听data的所有属性,直接修改
  • 当数据改变时,自动找到引用组件重新渲染

React
React基于状态机,手动优化,数据不可变,需要setState驱动新的state替换老的state。当数据改变时,以组件为根目录,默认全部重新渲染,所以React中会需要shouldComponentUpdate这个声明周期函数方法来进行控制

5.其他不同点

Vue为了更加简单易用,引入了指令,filter等概念以及大量的option API,比如watch,computed等都是非常好用的。

而React的API比较少,如果你的JS基础比较好,上手也是比较容易的

性能优化

性能优化常用的方式方法

懒加载,cdn加速,打包之类的,防抖节流

网页内容服务器JavaScriptcssCookie移动客户端图片
减少http请求次数使用CDN将脚本置底将样式表置顶减少Cookie大小保持单个内容小于25kb优化图像
减少DNS查询次数添加Expires或Cache-Control报文头使用外部Javascript和css文件避免css表达式页面内容使用无cookie域名打包组建成符合文档优化CSS Sprite
避免页面跳转Gzip压缩传输文件精简Javascript和css用<\link>代替@import使用小且可缓存的favicon.ico
缓存Ajax配置ETags去除重复脚本避免使用Filters
延迟加载尽早flush输出减少DOM访问
提前加载使用GET Ajax请求使用智能事件处理
减少DOM元素数量避免空的图片src
根据域名划分内容
减少iframe数量
避免404

设计模式

单例模式

关键点有4个:

  • 1.私有构造函数
  • 2.声明静态单例对象
  • 3.构造单例之前要加锁
  • 4.需要2次检查单例实例是否为空,分别在锁之前和所之后

为何要检测2次?

有可能延迟或者缓存的原因,造成构造了多个实例,违反了单例的初衷

构造函数能否公有化?

不,单例类的构造函数必须私有化,单例类不能被实例化,只能被静态调用

lock住的对象为什么要是object对象,可以是int型吗?

不行,锁住的必须是个引用类型,如果每个不同的线程在声明的时候值类型变量的地址都不一样,那么上个线程锁住的东西,下个线程进来会认为根本没有锁,相当于每次都锁了不同的们。而引用类型的变量地址是相同的,每个线程进来判断锁都是判断同一个地址,相当于锁在同一扇门,起到了锁的作用

工厂模式

核心功能:根据 需求 生产 产品
核心思想:解耦 需求 工厂 和 产品
实际上根据业务情景不同分为不同的实现方式。一般分为3中:简单工厂,工厂,抽象工厂

工厂模式中,一个工厂生产一个产品,所有产品派生于同一个抽象产品(或产品接口);而抽象工厂模式中,一个工厂生产多个产品,它们是一个产品族,不同的产品族的产品派生于不同的抽象产品(或产品接口)。

观察者模式

两个角色:观察者和被观察者
就像:守卫们盯着囚犯,一旦囚犯动,守卫们就必须马上采取行动。(守卫:观察者)。

  • 关键点1:每个观察者需要被保存到被观察者的集合中,并且被观察者提供添加和删除的方式
  • 关键点2:被观察者把自己传给观察者,当状态改变后,通过遍历或循环的方法诸葛通知列表中的观察者
  • 关键点3:虽然解耦了观察者和被观察者的依赖,让各自的变化不怎么影响另一方的变化,但是这种解耦并不是很彻底,没有完全接触两者之间的耦合
  • 关键点4:在事件中,订阅者和发布者之间是通过把事件处理程序绑定到委托,并不是把自身传给对方。所以解决了观察者模式中不完全解耦的问题

通过委托绑定方法来实现观察者模式,会有什么隐患?

有的,通过+=方法绑定到委托,很容易忘记-=。 如果只绑定不移除,这个方法会一直被引用。我们知道GC去回收的时候,只会处理没有被引用的对象,只要是还被引用的对象就不会被回收掉。所以如果在长期不关闭的系统中(比如监控系统),大量的代码使用+=而不-=,运行事件长以后可能会内存溢出。

事件,委托,观察者之间的关系

委托是一种类型,事件是一种特殊的委托,观察者模式是一种设计模式,事件的机制是观察者模式的一种实现,其中订阅者和发布者通过委托实现协同工作。

安全

什么是XSS漏洞,怎么防御?

全称:Cross SiteScript 跨站脚本攻击
简写:CSS看起来和我们熟知的CSS是一样的,有些温柔了,就把C换成了X,增强文字对这种攻击的强度描述

XSS是一种网站应用程序的安全漏洞攻击,是代码注入的一种,它允许恶意用户将代码注入到网页上,其他用户在观看网页时就会受到影响。这类攻击通常包含了HTML以及用户端脚本语言。这种类型的漏洞由于被黑客用来编写危害性更大的网络钓鱼攻击而变得广为人知。

XSS攻击的主要目是是,想办法获取目标攻击网站的cookie,因为有了cookie相当于有了session,有了这些信息就可以在任意能接进互联网的pc登录该网站,并以其他人的身份登录,做一些破坏。

XSS的危害

  • 1.盗取各类用户账号,如及其登录账号,用户网银账号,各类管理员账号
  • 2.控制企业数据,包括读取,篡改,添加,删除企业敏感数据的能力
  • 3.盗窃企业重要的具有商业价值的资料
  • 4.非法转账

如何防御?

方法解释
HttpOnly防止劫取CookieHttpOnly最早由微软提出,至今已经成为一个标准。浏览器将禁止页面的Javascript访问带有HttpOnly属性的Cookie。目前主流浏览器都支持,HttpOnly解决是XSS后的Cookie支持攻击。
输入检查例如网站注册经常用户名只允许字母和数字的组合,或者邮箱电话,我们会在前端用js进行检查,但在服务器端代码必须再次检查一次,因为客户端的检查很容易绕过。
输出检查大多人都知道输入需要做检查,但却忽略了输出检查。
处理富文体设置好白名单,严格控制标签
防御DOM Based XSSDOM Based XSS是从javascript中输出数据到HTML页面里。

什么是CSRF攻击?怎么防御?

CSRF:Cross Site Request Forgery(跨站点请求伪造)。

CSRF 攻击者在用户已经登录目标网站之后,诱使用户访问一个攻击页面,利用目标网站对用户的信任,以用户身份在攻击页面对目标网站发起伪造用户操作的请求,达到攻击目的。

如何防御?

  • CSRF 漏洞进行检测的工具,如 CSRFTester、CSRF Request Builder…
  • 验证 HTTP Referer 字段
  • 添加并验证 token
  • 添加自定义 http 请求头
  • 敏感操作添加验证码
  • 使用 post 请求
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值