本文内容来源于网络,个人归纳整理,只为理解记忆方便
1.JavaScript对象与类
1,创建对象的方式?
创建对象的方式与类型继承指的是同一个问题
1,工厂模式
用函数来封装创建对象的细节,从而通过调用函数来达到复用的目的。但是存在一个很大的问题是不能建立对象与类型的联系。
2,构造函数
JavaScript中的每个函数都可以作为构造函数,只要是通过new来新建一个对象,就可以称这个函数为构造函数。
构造函数新建对象的过程:
- 首先是新建一个对象
- 将对象的原型指向构造函数的prototype(注:只有构造函数才有prototype属性)。
- 将执行上下文中的this指向这个对象,然后执行函数。
- 返回新建的对象。 通过构造函数新建对象的有缺点: 优点是建立了对象和类型间的联系,但是还存在一个问题,就是假如构造函数中也有函数的时候,每次新建对象的时候,内部函数也会被作为一个对象新建,这样就增加了内存消耗,实际上内部函数可以被所有实例共享
2,对象的拷贝
- 1,浅拷贝
3,JS获取对象原型的方法
- 1,p.proto
- 2,p.construct.prototype
- 3,Object.getPrototypeOf(p)
3,JavaScript内置对象
2,JavaScript的继承
参考文档:恐怖如斯的 4W 字 JavaScript 面试知识点
1,通过构造函数实现继承
es5实现:
function Person () {
this.head = '脑袋瓜子';
this.emotion = ['喜', '怒', '哀', '乐']; //人都有喜怒哀乐
}
function Student(studentID) {
this.studentID = studentID;
Person.call(this);
}
var stu1 = new Student(1001);
console.log(stu1.emotion); //['喜', '怒', '哀', '乐']
stu1.emotion.push('愁');
console.log(stu1.emotion); //["喜", "怒", "哀", "乐", "愁"]
var stu2 = new Student(1002);
console.log(stu2.emotion); //["喜", "怒", "哀", "乐"]
通过call()调用了父类的构造函数。
es6实现:
通过构造函数实现继承的优缺点: 因为在子类的构造函数中调用了父类的构造函数,这就导致了通过new新建的子对象都会有一份自己的变量和函数,其实函数是可以多个实例共享的,每个对象都有自己的函数造成内存的浪费,而且后期需要功能有变动时,已经新建了的对象中的函数是不能反应这个变化的。好处就是每个子对象的实例都维护了自己一份的变量,修改其中一个对象,不会影响其他对象。
2,通过原型实现继承
因为每个函数都有一个prototype属性,这个属性是一个对象,这个对象包含了通过构造函数创建的所有实例共享的属性和方法。还能通过这个属性添加公用属性和方法,实现代码的复用。但是这种方式不能传入参数来初始化值,
function object(o){
function F(){};
F.prototype = o;
return new F();
}
3,组合式继承
4,寄生式组合继承
function Person(name) {
this.name = name;
}
Person.prototype.sayName = function() {
console.log("My name is " + this.name + ".");
};
function Student(name, grade) {
Person.call(this, name);
this.grade = grade;
}
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;
Student.prototype.sayMyGrade = function() {
console.log("My grade is " + this.grade + ".");
};
3,防抖和节流
1,防抖
2,节流
4, cookie,localstorage,indexdb, token,session
1,cookie
1,什么是cookie?
http协议是无状态的,需要特定的信息来保持客户端与服务器的连接状态。cookie实际上是一小段的文本信息(key-value),当客户端向服务器请求数据的时候,返回的数据中包括一个cookie,当客户端再次发起请求时,会带上这个cookie,服务器通过这个cookie来辨别客户端的身份。用来管理用户状态以及一些个性化设置。
前端可以使用document.cookie来方位cookie。
2,浏览器处理cookie的流程?
服务器返回一个Set-Cookie字段,其中包含子字段 --->(mcrwayfun, Max-Age, Expires, )
3,cookie的属性项?
键值对,Expires,Domain, Path, Secure。
4,Expires的可能取值?
cookie的有效时间,是一个时间点,标志过了这个时间点之后,cookie就会失效。在JS中使用MaxAge来表示这个属性,单位是秒。maxage有三种值,分别是正,负和0。正值表示过了一段时间之后失效,浏览器会将正值的cookie持久化(就是将这个cookie存入cookie文件),无论浏览器是否关闭,有效期内cookie都会存在。负值表示这个cookie是临时cookie,不会被持久化,仅在本窗口或本窗口打开的子窗口打开的时候才有效,窗口关闭,立即失效。当值为0时,表示这个cookie需要立即删除。
5,如何修改cookie?
相同name,Domain和Path的cookie可以通过直接覆盖来修改。
6,cookie的大小?
cookie的大小在一般的浏览器中都是4M。
7,cookie与csrf
cookie 如何避免 csrf
cookie增加了一个新属性 (samesite),表示只能当前域名的HTTP请求才能携带这个cookie。
cookie如何防止XSS
- 1,cookie的http-only属性,表示只能被HTTP请求携带,攻击者无法通过document.cookie获取cookie。
2,token
token是服务器生成的一串字符串,在客户端第一次登陆时从服务器返回,后续客户端向服务器发送请求时,就可以通过token来验证客户端。
#### 1,使用token的两种方式
使用设备号或者设备的Mac地址作为token。
使用session值作为token。
1,token解决的问题
Token 完全由用户管理,所以可以避开同源策略。
token可以避免CSRF。
token可以是无状态的,可以在多个服务间共享。
5,web安全
1,XSS
跨站脚本攻击与跨站请求伪造(csrf)的区别在于,csrf通过伪造HTTP请求来达到攻击的目的,但是XSS是通过盗取用户的敏感信息来攻击。
1,DOM型XSS
- 1,通过document.cookie, 获取用户信息。
- 2,通过localStorage, 获取本地存储的敏感信息。
,如何预防XSS
-
1,正则校验 xss的来源是不安全的数据,一个重要的来源是表单的提交,对于表单提交的数据进行正则校验,之后才能提交数据。
-
2,数据转义
6,js类型
1, 0.1 + 0.2 !== 0.3
进制转换和对阶运算会导致精度丢失。 0.1和0.2转换为二进制时会发生无限循环,进行对阶运算时,js引擎会对二进制进行截断,造成精度丢失。
2,使 a===1&&a===2&&a===3 为 true 成立
1,== 可以利用隐式类型转换
class A {
constructor(value) {
this.value = value;
}
valueOf() {
return this.value++;
}
}
const a = new A(1);
if (a == 1 && a == 2 && a == 3) {
console.log("Hi Libai!");
}
2,=== 利用数据劫持
let value = 1;
Object.defineProperty(window, 'a', {
get() {
return value++
}
})
if (a === 1 && a === 2 && a === 3) {
console.log("Hi Libai!")
}
7,JS定时器
1,为什么定时器的定时不准
因为setTimeout,setInterval是异步任务,调用之后不会立即进入执行栈,而是被放入任务队列,只有当执行栈中没有其他任务时,才会被推入执行栈。
8,JS函数
9, DOM操作
10,css盒子模型
1,标准盒子模型和IE盒子模型
- 1,标准盒子模型(content-box)的宽度只包括content的宽度。
- 2,IE盒子模型(border-box)的宽度包括content,padding,border。
11,BFC(块格式化上下文)
最常见的上下文有BFC和IFC.
1,BFC的主要应用场景
- 1,阻止margin重叠
- 2,清除浮动
- 3,阻止元素被浮动元素覆盖
12,层叠上下文
13,回流和重绘
1,回流
当渲染树部分或者全部的元素的尺寸、结构、或者某些属性发生变化时,浏览器重新渲染部分或者全部文档的过程称为回流。每次回流会将页面清空,从左上角第一个色素到右下角最后一个元素一点一点渲染。
1,会导致回流的操作
- 1,页面的首次渲染
- 2,浏览器的窗口大小发生改变
- 3,元素的尺寸(外边距,内边距,边框厚度,高度,宽度)或者位置改变。
- 4,元素的内容改变(input输入框中输入文字,文字的数量发生改变,图片大小)
- 5,文字的大小发生改变。
- 6,添加或者删除可见的DOM元素
- 7,激活css伪类(:hover)
- 8,查询某些属性或者调用某些方法
2,一些常用的会导致回流的属性和方法
clientWidth, clientHeight, clientTop, clientLeft,
offsetWidth, offsetHeight, offsetTop, offsetLeft,
scrollWidth, scrollHeight, scrollTop, scrollLeft,
scrollIntoView(), scrollIntoViewIfNeeded(),
getComputedStyle()(currentStyle in IE) ,
getBoundingClientReact(),
scrollTo(),
每次回流都会产生计算消耗,大多数浏览器通过队列化修改并批量执行来优化回流过程。
使用一些方法的时候会强制刷新队列并要求计划任务立即执行。
使用getComputedStyle()方法获取布局信息时,浏览器会为了获取最新的布局信息,会要求渲染队列里面的待处理变化立即执行,从而触发了一次回流。
2,重绘
当元素的外观发生改变(color, background-color,visibility, outline),但是没有改变布局,浏览器会将新的样式赋予元素并重新绘制。
1,常见的引起重绘的属性
- color,visibility
- border-style,border-radius,text-decoration, outline-color, outline, outline-style, outline-width, box-shadow
- backgroud, backgroud-color, backgroud-image, background-position, background-repeat, background-size
3,如何避免回流和重绘
14 跨域
什么是跨域?
- 协议,域名,端口不一致就是跨域。 浏览器的跨域会导致什么情况?
- 1,ajax请求不能发送。
- 2,不能获取DOM元素。
- 3,不能获取cookie,localstorage,indexdb 为什么需要同源策略?
- 保护用户信息安全,可以分为ajax同源策略和DOM同源策略。ajax同源策略的目的是限制不同域的网站不能发起ajax请求,可以一定程度防止CSRF攻击。DOM同源策略限制不同源的页面不能获取DOM,防止在IFrame中嵌入正常的网站,窃取用户信息。
为什么需要跨域? - 1,前后端服务部署在不同的云服务器上
- 2, 如何解决跨域问题? :1,设置代理Nginx。 :2,使用jsonp。 :3,使用cors. :4,postmessage 如何使用Nginx解决跨域问题?
- 使用Nginx的反向代理是最简单的跨域方式,支持所有浏览器,支持session,不需要改变代码,不影响服务器性能。
- 如何使用jsonp解决跨域问题? :利用不受同源策略限制的条件,网页可以动态获取到其他来源产生的动态数据,但是需要服务器的支持。 使用jsonp解决跨域问题的代码实现?
- 手写jsonp ,
jsonp解决跨域问题的优缺点?
- 优点1,兼容性好,能够解决主流浏览器的跨域问题。缺点1,仅支持get请求。缺点2,容易受到XSS攻击。 如何使用cors解决跨域问题?
- 关键在于服务器端设置了Access-control-allow-origin,就可以开启cors。浏览器的请求头中下发一个Origin头,value值与Access-control-allow-origin一样时,服务器验证通过,可以从服务器跨域得到资源。简单请求和复杂请求在使用cors时,服务器返回的响应头不一样。 什么是复杂请求和简单请求?
- 简单请求:1,请求方式:get,post,head。2,请求头:Accept, Accept-language, Content-language, Last-Event-ID, Content-type(只能是这三者:application/x-www-form-urlencoded、multipart/form-data、text/plain)。复杂请求:除了简单请求的都是复杂请求。 复杂请求的预检请求和简单请求在cors时有什么不同?
- 在简单请求时,服务器只返回Access-control-allow-origin和Access-control-allow-credentials这两个响应头。预检请求时增加Access-control-allow-Methods和Access-control-allow-headers,主要明确复杂请求可以下发的方法和自定义请求头,还有一个Access-control-max-age,标识预检请求的缓存时间。 复杂请求的预检请求?
- 复杂请求第一次发出时会首先发出一个预检请求,再根据预检请求返回头中的methods和headers来确定是否需要发出这个复杂请求,如果预检请求的max-age还没到期,就不需要发出预检请求。 access-control-allow-origin的可能取值?
- 1,,标识所有的域都可以向服务器所在的这个域发出跨域请求,但是服务器出于安全考虑不会设置为这个值,如果设置为这个值,即使credentials的值设置为true,客户端也不需要向服务器发送cookie。2,指定域,一般是指中间的Nginx代理服务器。3,动态设置为请求域。 access-control-allow-credentials的可能取值?
- true或者false,为true时表示允许客户端向服务器发送cookie等验证信息,为false时,首先是浏览器不会保存cookie(即使设置了set-cookie),其次是浏览器中有cookie,也不会发送。 HTML中其它不受同源策略显示的标签?
1,<image>加载图片。
2,<link>,加载CSS。
3,<iframe>,加载任意资源
2,cors
cors 会限制那些网络行为?
- 1,cookie,localstorage,indexdb访问受阻。
- 2,无法操作跨域DOM(常见于Iframe)
- 3, ajax请求受限。