EP12-zake搞Interview之JavaScript 1

191 阅读11分钟

本文内容来源于网络,个人归纳整理,只为理解记忆方便

1.JavaScript对象与类

1,创建对象的方式?


创建对象的方式与类型继承指的是同一个问题


1,工厂模式

用函数来封装创建对象的细节,从而通过调用函数来达到复用的目的。但是存在一个很大的问题是不能建立对象与类型的联系。

2,构造函数

JavaScript中的每个函数都可以作为构造函数,只要是通过new来新建一个对象,就可以称这个函数为构造函数。
构造函数新建对象的过程:

  1. 首先是新建一个对象
  2. 将对象的原型指向构造函数的prototype(注:只有构造函数才有prototype属性)。
  3. 将执行上下文中的this指向这个对象,然后执行函数。
  4. 返回新建的对象。 通过构造函数新建对象的有缺点: 优点是建立了对象和类型间的联系,但是还存在一个问题,就是假如构造函数中也有函数的时候,每次新建对象的时候,内部函数也会被作为一个对象新建,这样就增加了内存消耗,实际上内部函数可以被所有实例共享

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请求受限。

3,JavaScript模块化