1. AJAX相关知识点
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
ajax文件上传(提交):
1.serialize() 方法:序列化表单值,创建 URL 编码文本字符串。
2.封装FormData 对象,直接用$.ajax提交。FormData 对象可以把form中所有表单元素的name与value组成一个queryString,提交到后台,在使用Ajax提交时,使用FormData对象可以减少拼接queryString的工作量。
var form = $('#form1');
var formdata = new FormData(form);
2.行内元素与块级元素
- 块级元素:
总是在新行上开始;
高度,行高以及外边距和内边距都可控制;
宽度缺省是它的容器的100%,除非设定一个宽度。
它可以容纳内联元素和其他块元素
<div> <form> <h1> to <h6> <ul> <ol> <li> <p> <table>
- 行内元素
和其他元素都在一行上;
设置宽高无效,可以通过line-height来设置。
宽度就是它的文字或图片的宽度,不可改变
内联元素只能容纳文本或者其他内联元素
<a> <button> <em> <img> <input> <label> <select> <span>
3.options预检
OPTIONS方法请求web服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。
OPTIONS 方法,可以询问服务器具体支持哪些方法,或者服务器会使用什么样的方法来处理一些特殊资源。可以说这是一个探测性的方法,客户端通过该方法可以在不访问服务器上实际资源的情况下就知道处理该资源的最优方式。
复杂请求在发送真正的请求前会提前发送一次Options请求(嗅探、预检请求),XHR会根据返回的Access-Control-*等头信息判断是否有对指定站点的访问权限,检查该请求是否是可靠安全的。如果options获得的回应是拒绝性质的(或者没有权限),会停止发送实际请求信息。
4.头条面试题(事件循环机制)
5.跨域问题
最常用的跨域方式有以下三种:JSONP、CORS、postMessage。
-
jsonp(需前后端配合)
虽然因为同源策略的影响,不能通过XMLHttpRequest请求不同域上的数据(Cross-origin reads)。但是,在页面上引入不同域上的js脚本文件却是可以的(Cross-origin embedding)。因此在js文件载入完毕之后,触发回调,可以将需要的data作为参数传入。
缺点:
1.JSONP只支持GET请求;
2.XMLHttpRequest相对于JSONP有着更好的错误处理机制 -
CORS(跨域资源共享)
能使服务器支持 XMLHttpRequest 的跨域请求。CORS 实现起来非常方便,只需要增加一些 HTTP 头,让服务器能声明允许的访问来源。
普通跨域请求:只用服务端设置Access-Control-Allow-Origin.
XMLHttpRequest 请求可以发送凭证请求(HTTP Cookies 和验证信息)
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
-
postMessage
window.postMessage(message,targetOrigin) 方法是html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个window对象是属于同源或不同源。 -
nginx反向代理
通过nginx配置一个代理服务器(域名与domain1相同,端口不同),反向代理访问domain2,并且可以修改cookie中的domain信息,可实现跨域登录。 -
WebSocket协议实现跨域
它是H5一种新的协议,实现了浏览器与服务器全双工通信,可以实现服务端推送。
6.call的理解
- 可以使用 call() 方法调用父构造函数。
function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
//调用了父构造函数,拓宽了字段
Product.call(this, name, price);
this.category = 'food';
}
let food1 = new Food('chees', 5);
food1; // Food {name: "chees", price: 5, category: "food"}
- 使用 call() 方法调用匿名函数。
- 使用 call() 方法调用函数并且指定上下文的 this。
fn.call(obj); // 通过 call(),将 obj 的 this 指向了 fn 中
箭头函数的this指向
箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
箭头函数的this指向的是谁调用箭头函数的外层function,箭头函数的this就是指向该对象,如果箭头函数没有外层函数,则指向window。
7.移动端适配
- meta viewport
- 媒体查询
- 动态 rem 方案
- flexible.js布局
8.CSS解析原则
尽量少使用层级关系,CSS选择器是从右往左解析的。
提高解析效率
dom树和css会合成为render树,这个操作实际上就是是需要将css附着到dom树上,因此需要根据选择器提供的信息对dom树进行遍历,才能将样式成功附着到对应的dom元素上。当dom树比较复杂的时候,可以发现从右到左解析能够有效减少回溯次数提升性能。
9.Generator函数
形式上,Generator 函数是一个普通函数,但是有两个特征。一是,function关键字与函数名之间有一个星号;二是,函数体内部使用yield表达式,定义不同的内部状态。
function* helloWorldGenerator() {
yield 'hello';
yield 'world';
return 'ending';
}
var hw = helloWorldGenerator();
调用 Generator 函数后,该函数并不执行,返回的也不是函数运行结果,而是一个指向内部状态的指针对象。
调用遍历器对象的next方法,使得指针移向下一个状态。
hw.next()
// { value: 'hello', done: false }
hw.next()
// { value: 'world', done: false }
hw.next()
// { value: 'ending', done: true }
hw.next()
// { value: undefined, done: true }
10.路由组件懒加载
路由和组件的常用两种懒加载方式:
1、vue异步组件实现路由懒加载:
component:resolve => ([‘需要加载的路由的地址’,resolve])
2、es提出的import(推荐使用这种方式):
const HelloWorld = ()=> import(‘需要加载的模块地址’)
11.js对象的深、浅拷贝
基本数据类型:单独可以存在栈中.
引用数据类型(数组和对象):放在堆中存储的
基本数据类型存储在栈(stack)中,引用数据类型存储在堆(heap)中。
对于引用数据类型,在栈中存储了指针,该指针指向堆中具体的对象。
1.深拷贝:
- JSON.parse(JSON.stringify( )):当值为undefined、function、symbol 会在转换过程中被忽略。
- 循环递归:
function deepClone(obj) {
var objClone = Array.isArray(obj) ? [] : {}
if (obj && typeof obj === "object") {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === "object") {
objClone[key] = deepClone(obj[key]) // 递归复制
} else {
objClone[key] = obj[key]
}
}
}
}
return objClone;
}
2.浅拷贝:
- Object.assign(): 不适用于嵌套引用类型
- es6解构赋值:不适用于嵌套引用类型
12.flexible.js布局
如果css里面没有设定html的font-size,则默认浏览器以1rem=16px来换算。1rem等于html根元素设定的font-size的px值。
Flexible会将视觉稿分成100份(主要为了以后能更好的兼容vh和vw),而每一份被称为一个单位a。同时1rem单位被认定为10a。针对我们这份视觉稿可以计算出:(设计稿为750px为例):
1a = 7.5px
1rem = 75px
那么我们这个示例的稿子就分成了10a,也就是整个宽度为10rem,对应的font-size为75px。