前端知识总结

1、position:relative 脱离正常的文本流中,但其在文本流中的位置依然存在。
定位为absolute的层脱离正常文本流,但与relative的区别是其在正常流中的位置不再存在。
2、var a= new Person(); new一个方法都干了些什么

  1. 创建一个类的实例:创建一个空对象obj,然后把这个空对象的__proto__设置为构造函数的prototype
  2. 初始化实例:构造函数Person被传入参数并调用,关键字this被设定指向该实例obj;
  3. 返回实例obj。
    例:function New(F){
    var obj = {‘proto’: F.prototype}; /第一步/ 指定父对象为F的原型对象
    return function() {
    F.apply(obj, arguments); /第二步/
    return obj; /第三步/
    }
    }
    原型链原型对象解析https://blog.csdn.net/cc18868876837/article/details/81211729
    我们需要牢记两点:①__proto__和constructor属性是对象所独有的;② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性。
    __proto__属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(父对象)里找,一直找,直到__proto__属性的终点null,然后返回undefined,通过__proto__属性将对象连接起来的这条链路即我们所谓的原型链。
    prototype属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,即f1.proto === Foo.prototype。
    constructor属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function。

3、js引用对象深拷贝 浅拷贝
function deepClone(obj) { //递归拷贝
if(obj === null) return null; //null 的情况
if(obj instanceof RegExp) return new RegExp(obj);
if(obj instanceof Date) return new Date(obj);
if(typeof obj !== ‘object’) {
//如果不是复杂数据类型,直接返回
return obj;
}
/**
* 如果obj是数组,那么 obj.constructor 是 [Function: Array]
* 如果obj是对象,那么 obj.constructor 是 [Function: Object]
*/
let t = new obj.constructor();
for(let key in obj) {
//如果 obj[key] 是复杂数据类型,递归
t[key] = deepClone(obj[key]);
}
return t;
}

4、webpack
分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,ES6等),并将其转换和打包为合适的格式供浏览器使用。
Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。
Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。

5、改变input的placeholder的字体颜色
-webkit-text-fill-color:#333;
6、深度优先遍历和广度优先遍历

7、网络处理跨域的预检请求
cors(跨来源资源共享)的预检请求:可以使用 OPTIONS 方法发起一个预检请求(一般都是浏览检测到请求跨域时,会自动发起),以检测实际请求是否可以被服务器所接受。预检请求报文中的 Access-Control-Request-Method 首部字段告知服务器实际请求所使用的 HTTP 方法;Access-Control-Request-Headers 首部字段告知服务器实际请求所携带的自定义首部字段。服务器基于从预检请求获得的信息来判断,是否接受接下来的实际请求。服务器所返回的 Access-Control-Allow-Methods 首部字段将所有允许的请求方法告知客户端。该首部字段与 Allow 类似,但只能用于涉及到 CORS 的场景中。

8、js判断数据类型的三大方法以及优缺点
typeof 无法判断 array object date 这些其实都属于object(
对于基本类型,除 null 以外,均可以返回正确的结果。
对于引用类型,除 function 以外,一律返回 object 类型。
对于 null ,返回 object 类型。
对于 function 返回 function 类型。);
instanceof/constructor:无法判断准确判断Object类型(Object 类型、Array 类型、Date 类型、RegExp 类型、Function 类型 ),都属于object,同样在继承的时候会产生bug,只要当前的这个类在实例的原型链上(可以通过原型链__proto__找到它),检测出来的结果都是true;
基本数据类型的值是不能用instanceof来检测的
console.log(1 instanceof Number);//->false ;
Object.prototype.toString.call(value) ->找到Object原型上的toString方法,让方法执行,并且让方法中的this变为value(value->就是我们要检测数据类型的值)
Object.prototype.toString常用来判断对象值属于哪种内置属性,它返回一个JSON字符串——"[object 数据类型]";
https://blog.csdn.net/zuggs_/article/details/82150114
9、搞懂eventLoop
首先要从js是单线程说起,因为js是来处理和用户的交互、网络以及dom的操作,假如有两个线程,一个是在这个dom上添加内容,一个是删除dom,这时浏览器应该以谁为准,所以决定了js只能单线程,那么假如要加载一个耗时的高清图片等,浏览器要一直等着吗,这时就出现了异步和同步
栈:后进先出、队列:先进先出
宏任务:script(整体代码)、setTimeout、setInterval、I/O、事件、postMessage、 MessageChannel、setImmediate (Node.js)
微任务:Promise.then、 MutaionObserver、process.nextTick (Node.js)
微任务优先级高于宏任务
https://juejin.im/post/5cbc0a9cf265da03b11f3505 详细的解析
所有同步任务都在主线程上执行,形成一个执行栈 (Execution Context Stack)。
而异步任务会被放置到 Task Table,也就是上图中的异步处理模块,当异步任务有了运行结果,就将该函数移入任务队列。
一旦执行栈中的所有同步任务执行完毕,引擎就会读取任务队列,然后将任务队列中的第一个任务压入执行栈中运行。
主线程不断重复第三步,也就是 只要主线程空了,就会去读取任务队列,该过程不断重复,这就 是所谓的 事件循环
promise和 async/await
EventLoop不可怕,可怕的是遇上promise
https://juejin.im/post/5c9a43175188252d876e5903
10、vue路由的实现:hash和history
hash是浏览器#以及#后面的字符,用来指导浏览器动作,切换不会刷新页面,及时找不到 也不会报404错误
history模式下 前端的url和浏览器地址一致,如果服务器对路由没做处理,将会报404

11、vue的生命周期

update 更新之前更新之后
keep-alive的组件激活与移除
destroy 组件销毁前后
12、vue的数据双向绑定原理
https://www.jianshu.com/p/4aa858026fe5

13、array的map、filter、reduce
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进行检测。
注意: map() 不会改变原始数组。
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
注意: filter() 不会对空数组进行检测。
注意: filter() 不会改变原始数组。
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce() 可以作为一个高阶函数,用于函数的 compose。
注意: reduce() 对于空数组是不会执行回调函数的
14、get、post的区别
get没有body,get的参数在url中,body的参数在body里,所以get没有post安全,决定了get的参数长度有限制,而post没有;
15、本域指的是
同协议:比如都是http或者https()
同域名:比如都是ttp://baidu.com/a和http://baidu.com/b
同端口:比如都是80端口
16、常用状态码
1xx:指示信息–表示请求已接收,继续处理。
2xx:成功–表示请求已被成功接收、理解、接受。
3xx:重定向–要完成请求必须进行更进一步的操作。
4xx:客户端错误–请求有语法错误或请求无法实现。
5xx:服务器端错误–服务器未能实现合法的请求。
常见状态代码、状态描述的说明如下。
200 OK:客户端请求成功。
304:用于浏览器缓存,如果发送的表示资源没有变化,返回304,告诉浏览器使用缓存
400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
401 Unauthorized:没有提供正确的证书,请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用。
403 Forbidden:服务器收到请求,但是拒绝提供服务。
404 Not Found:请求资源不存在,举个例子:输入了错误的URL。
500 Internal Server Error:服务器发生不可预期的错误。
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常,举个例子:HTTP/1.1 200 OK(CRLF)。
17、http缓存原理
强缓存:
强缓存是利用http的返回头中的Expires或者Cache-Control两个字段来控制的,用来表示资源的缓存时间,cache-control的优先级更高。
Cache-Control是一个相对时间,例如Cache-Control:3600,代表着资源的有效期是3600秒。由于是相对时间,并且都是与客户端时间比较,所以服务器与客户端时间偏差也不会导致问题。
Expires该字段标识缓存到期时间,是一个绝对时间—服务器时间+缓存有效时间。
缺点:如果客户端修改了本地时间,会造成缓存失效。如果本地时间与服务器时间不一致,也会导致缓存失效。
比较缓存:若未命中强缓存,则浏览器会将请求发送至服务器。服务器根据http头信息中的Last-Modify(服务器返回)/If-Modify-Since()或Etag/If-None-Match来判断是否命中协商缓存。如果命中,则http返回码为304,浏览器从缓存中加载资源。
https://www.cnblogs.com/ranyonsue/p/8918908.html
18、vue的slot的使用
插槽就是slot,是组件的一块HTML模板,这块模板显示不现实、以及怎样显示由父组件来决定。
父组件将替换所指的slot的html片段
作用域插槽:(多用于列表遍历)
插槽可以控制html模板的显示与不显示。作用域插槽其实就是带数据的插槽。
原来父组件可以通过绑定数据传递给子组件。作用域插槽可以通过子组件绑定数据传递给父组件

https://blog.csdn.net/willard_cui/article/details/82469114
19、数组扁平化的方法
function flatten(arr) {
return arr.reduce((result, item)=> {
return result.concat(Array.isArray(item) ? flatten(item) : item);
}, []);
}

function flatten(arr) {
return arr.toString().split(’,’).map(function(item) {
return Number(item);
})
}

function flatten(arr) {
return arr.join(’,’).split(’,’).map(function(item) {
return parseInt(item);
})
}

function flatten(arr) {
var res = [];
arr.map(item => {
if(Array.isArray(item)) {
res = res.concat(flatten(item));
} else {
res.push(item);
}
});
return res;
}
//es6的扩展运算符 …
[].concat(…[1, 2, 3, [4, 5]]); // [1, 2, 3, 4, 5]
20、移动端适配原理
SASS
@function px2rem ($value) {
$para: 75px;
@return $value / $para + rem;
}

JS
let idealViewWidth = window.screen.width;
document.documentElement.style.fontSize = idealViewWidth / 10 + 'px';

解决1px像素问题
根绝dpr进行缩放以及根绝屏幕宽度来设置rem
21、XSS跨站脚本攻击原理、示例以及防护方法
它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意用户的特殊目的。
示例:
反射型:页面进行表单提交,获取到表单填写的值,后台将其打印出来,假如填写的是一段代码,后台将会翻译这段代码将其呈现
存储型:后台涉及到将填写数据添加到数据库,只要发送一段代码,就存到数据库,每次查询就会执行
dom-xss:用户将输入的值赋值给dom元素里,将其显示在页面
针对XSS跨站脚本漏洞,建议过滤”<” 、”>” 并将用户输入放入引号间,基本实现数据与代码隔离;过滤双引号防止用户跨越许可的标记,添加自定义标记;过滤TAB和空格,防止关键字被拆分;过滤script关键字;过滤&#,防止HTML属性绕过检查
22、CSRF攻击的原理以及防护
它指的是攻击者利用用户的身份来进行操作、例如银行转账、购物等,在用户访问的网站添加一个恶意诱导因素让用户点击,就会获取用户的cookie,发送到服务器,服务器会认为就是用户操作,因此形成攻击
防护:(1)验证 HTTP Referer 字段 ,该字段记录了请求的来源地址,所以判断是否是正常的地址,如果不是则拒绝该请求
(2)在请求地址中添加 token 并验证
在指定表单或者请求头的里面添加一个随机值做为参数
在响应的cookie里面也设置该随机值
那么用户C在正常提交表单的时候会默认带上表单中的随机值,浏览器会自动带上cookie里面的随机值,那么服务器下次接受到请求之后就可以取出两个值进行校验
而对于网站B来说网站B在提交表单的时候不知道该随机值是什么,所以就形成不了攻击
22、for循环里的setTimeOut打印出来的是最后一个值,如果想避免此情况用let或者用闭包

23、cookie、localStorage、sessionStorage的区别
cookie的大小限制为不超过4k,在浏览器和服务器之间来回传递,每次http请求都会携带cookie,所以一般是保存很小的数据,例如验证是否登录等
localStorage和sessionStorage区别在同一个浏览器窗口
25、重绘与回流
reflow:改变dom结构或者当render树中的一部分或者全部因为大小边距等问题发生改变而需要重建的过程叫做回流
repaint:当元素的一部分属性发生变化如外观背景色不会引起布局变化而需要重新渲染的过程叫做重绘
如果页面有大量数据的时候,可以采用DocumentFragment,减少 DOM 操作次数,降低回流对性能的影响
createDocumentFragment()的作用,就是可以创建一个文档碎片,把所有的新节点附加其上,然后把文档碎片的内容一次性添加到document中。
26、http的请求头、响应头信息
http报文结构为起始行、头部、主体;
请求报文

常见的请求头包含:
accept:浏览器可识别的内容类型
user-accept:产生请求的浏览器类型
host:请求的主机名
cache-control:是否开启缓存
cookie:携带服务器返回的cookie信息
如果是post的话会携带数据信息
起始行一般包括:请求方法、url、协议类型及版本
此处了解一下get和post的区别
GET方法的数据参数是暴露在起始行的URL中的,而POST方法的数据参数是在报文主体中的。
GET方法相对来说没有POST安全,因为它的数据参数可以直接从URL中获取,但是GET的效率更高。
GET方法的数据参数大小有一定的限制(1024)(原因也是因为它的数据参数是放在URL中的),而POST对数据大小是没有限制的。

响应报文

起始行包括协议类型版本、状态码、状态码文字描述
常见的响应头
server:使用服务器名称
Content-Type 用来指明发送给接收者的实体正文的媒体类型,如Content-Type:text/html;charset=GBK
Content-Encoding 与请求报头Accept-Encoding对应,告诉浏览器服务端采用的是什么压缩编码
Content-Language 描述了资源使用的自然语言,与Accept-Language对应
Content-Length 指明实体正文的长度,用以字节方式存储的十进制数字来表示
Keep-Alive 保持连接的时间,如Keep-Alive:timerout=5,max=120
27、手动实现bind函数
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== ‘function’) {
return
}

let self = this
let args = Array.prototype.slice.call(arguments, 1) //这个arguments指的是bind传入的参数
return function () {
  return self.apply(oThis, args.concat(Array.prototype.slice.call(arguments))) //这里的arguments是执行绑定函数时的实参
}

}
}
此处插入bind、call、apply的区别
call和apply都是立即执行的,区别就是call传入的参数是单一的,而apply传入的是数组
bind的返回值是函数,并不会立即执行
28、防抖与节流
// 函数节流(通常用于点击按钮频繁的操作)
var canRun = true;
document.getElementById(“throttle”).onscroll = function(){
if(!canRun){ // 判断是否已空闲,如果在执行中,则直接return return; }
canRun = false;
setTimeout(function(){ console.log(“函数节流”); canRun = true; }, 300);
};
//函数防抖(通常用于避免模糊查询时由于网速慢导致服务器返回慢而查询结果混乱)
var timer = false;
document.getElementById(“debounce”).onscroll = function(){
clearTimeout(timer); // 清除未执行的代码,重置回初始化状态

        timer = setTimeout(function(){
            console.log("函数防抖");
        }, 300);
   	 }; 

29、手写实现sleep函数
function stop(ms){
return new Promise(function(resolve){
setTimeout(resolve,ms)
})
}
async function sleep(){
await stop(3000);
console.log(‘3s以后了呀’)
}
30、React/Vue项目中的列表为什么要用key?
在列表不带key的情况下会对节点旧地复用,这样看来确实提高了diff速率,但是有一些隐藏的副作用,比如删除某个节点后该节点有绑定的的数据状态(如表单checkbox选中状态),会出现错乱,会选中删除完以后的第二个节点。key的作用是为了在diff算法执行时更快的找到对应的节点。
31、[‘1’, ‘2’, ‘3’].map(parseInt) what & why ?
打印出来是【1,NAN,NAN】;
这是因为parseint有两个参数(string、radix),由于parseInt(string, radix) 的参数radix必须介于2~36之间,而且字符串string中的数字不能大于radix才能正确返回数字结果值。因此上述的参数其实为【‘1’,0】、【‘2’,1】、【‘3’,2】radix为0时,且string参数不以“0x”和“0”开头时,按照10为基数处理。这个时候返回1,后两者的数字比radix大因此不合法
32、https协议的加密原理
https经由http通信,通过SSL/TLS建立加密通道,HTTPS使用的主要目的是提供对网站服务器的身份认证,同时保护交换数据的隐私与完整性。
1、服务端必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面,这套证书其实就是一对公钥和私钥。
2、传送证书
这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间、服务端的公钥,第三方证书认证机构(CA)的签名,服务端的域名信息等内容。
3、客户端解析证书
这部分工作是由客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值(秘钥)。然后用证书对该随机值进行加密。
4、传送加密信息
这部分传送的是用证书加密后的秘钥,目的就是让服务端得到这个秘钥,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。
5、服务段加密信息
服务端用私钥解密秘密秘钥,得到了客户端传过来的私钥,然后把内容通过该值进行对称加密。
6、传输加密后的信息
这部分信息是服务端用私钥加密后的信息,可以在客户端被还原。
7、客户端解密信息
客户端用之前生成的私钥解密服务端传过来的信息,于是获取了解密后的内容。
33、输入url到页面渲染的过程
1、浏览器的地址栏输入URL并按下回车。
2、浏览器查找当前URL是否存在缓存,并比较缓存是否过期。
3、DNS解析URL对应的IP。
4、根据IP建立TCP连接(三次握手)。
5、HTTP发起请求。
6、服务器处理请求,浏览器接收HTTP响应。
7、渲染页面,构建DOM树。
8、关闭TCP连接(四次挥手)。
其中在发送请求涉及到五大协议:
DNS解析URL地址、生成HTTP请求报文(前两个应用层)、构建TCP连接(传输层)、使用IP协议选择传输路线(网络层)、数据链路层保证数据的可靠传输(数据链路层)、物理层将数据转换成电子、光学或微波信号进行传输(物理层);
服务器接受到地址后反向来解析:服务器接收到这个比特流,把比特流转换成帧格式,上传到数据链路层,服务器发现数据帧中的目的MAC地址与本网卡的MAC地址相同,服务器拆除数据链路层的封装后,把数据包上传到网络层。服务器的网络层比较数据包中的目的IP地址,发现与本机的IP地址相同,服务器拆除网络层的封装后,把数据分段上传到传输层。传输层对数据分段进行确认、排序、重组,确保数据传输的可靠性。数据最后被传到服务器的应用层
34、前后端鉴权方式
1、session-cookie
1,服务器在接受客户端首次访问时在服务器端创建seesion,然后保存seesion(我们可以将seesion保存在内存中,也可以保存在redis中,推荐使用后者),然后给这个session生成一个唯一的标识字符串,然后在响应头中种下这个唯一标识字符串。
2.签名。这一步只是对sid进行加密处理,服务端会根据这个secret密钥进行解密。(非必需步骤)
3.浏览器中收到请求响应的时候会解析响应头,然后将sid保存在本地cookie中,浏览器在下次http请求de 请求头中会带上该域名下的cookie信息,
4.服务器在接受客户端请求时会去解析请求头cookie中的sid,然后根据这个sid去找服务器端保存的该客户端的session,然后判断该请求是否合法。
2、token验证

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
    3、OAuth(开放授权)
    第一步. 向用户请求授权,现在很多的网站在登陆的时候都有第三方登陆的入口,当我们点击等第三方入口时,第三方授权服务会引导我们进入第三方登陆授权页面。
    第二步. 当用户点击授权并登陆后,授权服务器将生成一个用户凭证(code)。这个用户凭证会附加在重定向的地址redirect_uri的后面
    第三步. 请求授权服务器授权:
    第四步. 授权服务器同意授权后,返回一个资源访问的凭证(Access Token)。
    第五步. 第三方应用通过第四步的凭证(Access Token)向资源服务器请求相关资源。
    第六步. 资源服务器验证凭证(Access Token)通过后,将第三方应用请求的资源返回
    35、函数柯里化(Currying)

实际上就是把add函数的x,y两个参数变成了先用一个函数接收x然后返回一个函数去处理y参数。
优点是:
1、优点复用

30、排序算法
一、冒泡排序
function bubbleSort(arr) {
var len = arr.length;
for (var i = 0; i < len; i++) {
for (var j = 0; j < len - 1 - i; j++) {
if (arr[j] > arr[j+1]) { //相邻元素两两对比
var temp = arr[j+1]; //元素交换
arr[j+1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
}
二、选择排序
function selectionSort(arr) {
var len = arr.length;
var minIndex, temp;
for (var i = 0; i < len - 1; i++) {
minIndex = i;
for (var j = i + 1; j < len; j++) {
if (arr[j] < arr[minIndex]) { //寻找最小的数
minIndex = j; //将最小数的索引保存
}
}
temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
return arr;
}
三、插入排序
四、快速排序
function quickSort(arr) {
if (arr.length <= 1) return ;

//取数组最接近中间的数位基准,奇数与偶数取值不同,但不印象,当然,你可以选取第一个,或者最后一个数为基准,这里不作过多描述
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
//左右区间,用于存放排序后的数
var left = [];
var right = [];
console.log('基准为:' + pivot + ' 时');
for (var i = 0; i < arr.length; i++) {
    console.log('分区操作的第 ' + (i + 1) + ' 次循环:');
    //小于基准,放于左区间,大于基准,放于右区间
    if (arr[i] < pivot) {
        left.push(arr[i]);
        console.log('左边:' + (arr[i]))
    } else {
        right.push(arr[i]);
        console.log('右边:' + (arr[i]))
    }
}
//这里使用concat操作符,将左区间,基准,右区间拼接为一个新数组
//然后递归1,2步骤,直至所有无序区间都 只剩下一个元素 ,递归结束
return quickSort(left).concat([pivot], quickSort(right));

}
31、vuex的一些方法
state:最基本的状态
getters: 相当于计算属性
当我们得到state的值之后, 使用getters, 将这些基本的值进行组合加工, 得到我们需要的值
mutations:
他的作用就是来改变state的值, 并且是唯一的方法
actions:
假如你有好几个mutation需要提交, 一个一个的写就太傻逼了. 可以用 actions 来封装 mutations.
32、vue的子路由

33、vue和angular、react的区别
vue对于数据变动采用的是虚拟dom数的diff算法来实现双向数据绑定
angular采用的是脏检查机制,例如用户点击了 button,angular 执行了一个叫 onClick 的方法。这个 onClick 的方法体对于 angular 来说是黑盒,它到底做了什么不知道。可能改了 $scope.content1 的值,可能改了 s c o p e . c o n t e n t 2 的 值 , 也 可 能 两 个 值 都 改 了 , 也 可 能 都 没 改 。 那 么 a n g u l a r 到 底 应 该 怎 样 得 知 o n C l i c k ( ) 这 段 代 码 后 是 否 应 该 刷 新 U I , 应 该 更 新 哪 个 D O M 元 素 ? a n g u l a r 必 须 去 挨 个 检 查 这 些 元 素 对 应 绑 定 表 达 式 的 值 是 否 有 被 改 变 。 这 就 是 脏 数 据 检 查 的 由 来 。 r e a c t 也 是 采 用 虚 拟 d o m 来 更 新 视 图 、 与 v u e 最 大 的 区 别 在 于 双 向 数 据 绑 定 , r e a c t 虽 然 也 可 以 实 现 双 向 数 据 绑 定 , 但 是 需 要 通 过 调 用 s e t S t a t e 去 触 发 更 新 视 图 , 反 过 来 视 图 如 果 要 更 新 也 需 要 监 听 视 图 变 化 然 后 调 用 s e t S t a t e 去 同 步 s t a t e 状 态 34 、 v u e 的 传 参 方 式 1 、 父 传 子 父 组 件 在 子 组 件 标 签 写 上 所 要 传 的 n a m e 和 v a l u e , 子 组 件 用 p r o p s 来 接 收 2 、 子 传 父 父 组 件 定 义 事 件 @ m y E v e n t = " c a l l b a c k " , 回 调 函 数 可 以 接 受 参 数 子 组 件 触 发 父 组 件 自 定 义 事 件 并 传 参 t h i s . scope.content2 的值,也可能两个值都改了,也可能都没改。那么 angular 到底应该怎样得知 onClick() 这段代码后是否应该刷新 UI,应该更新哪个 DOM 元素?angular 必须去挨个检查这些元素对应绑定表达式的值是否有被改变。这就是脏数据检查的由来。 react也是采用虚拟dom来更新视图、与vue最大的区别在于双向数据绑定,react虽然也可以实现双向数据绑定,但是需要通过调用setState去触发更新视图,反过来视图如果要更新也需要监听视图变化 然后调用setState去同步state状态 34、vue的传参方式 1、父传子 父组件在子组件标签写上所要传的name和value,子组件用props来接收 2、子传父 父组件定义事件 @myEvent=" callback",回调函数可以接受参数 子组件触发父组件自定义事件 并传参 this. scope.content2angularonClick()UIDOMangularreactdomvuereactsetStatesetStatestate34vue1namevalueprops2@myEvent="callback"this. emit(‘父组件中的自定义事件’,参数)
3、组件之间
①建立一个公共的通信组件(Vue),需要传值的组件里引入该通信组件
②在一个中绑定一个事件this.on(‘eventname’, this. id)
③在另一个组件中触发事件this.$ emit(‘eventname’,( options)=>{})
或者vuex
4、vue-router传参
// r o u t e r : 是 路 由 操 作 对 象 , 只 写 对 象 / / router : 是路由操作对象,只写对象 // router://route : 路由信息对象,只读对象
例如:this.$router.push({
name:‘hello’,
params:{
name:‘word’,
age:‘11’
}
})

//读取 路由参数接收
this.name = this. r o u t e . p a r a m s . n a m e ; t h i s . a g e = t h i s . route.params.name; this.age = this. route.params.name;this.age=this.route.params.age;
①传递:this. r o u t e r . p u s h ( n a m e : ′ n e w s ′ , p a r a m s : u s e r I d : 123 接 受 参 数 : t h i s . router.push({ name: 'news', params: { userId: 123 }} 接受参数:this. router.push(name:news,params:userId:123this.route.params.userId
②传参:this. r o u t e r . p u s h ( p a t h : ′ / n e w s ′ , q u e r y : u s e r I d : 123 ) ; 接 收 参 数 : t h i s . router.push({ path: '/news', query: { userId: 123 }}); 接收参数:this. router.push(path:/news,query:userId:123);this.route.query.userId
区别在于name和path之分,还有query是将数据拼接在url之后,所以刷新页面并不会丢失数据,而params想要不丢失数据,必须在router.js里的路由上添加上所需传的参数
35、原生js实现ajax
// 第一步: 获得XMLHttpRequest对象
var ajax = new XMLHttpRequest();
// 第二步: 设置状态监听函数
ajax.onreadystatechange = function(){
console.log(ajax.readyState);
console.log(ajax.status);
// 第五步:在监听函数中,判断readyState=4 && status=200表示请求成功
if(ajax.readyState4 && ajax.status200){
// 第六步: 使用responseText、responseXML接受响应数据,并使用原生JS操作DOM进行显示
console.log(ajax.responseText);
console.log(ajax.responseXML);// 返回不是XML,显示null
console.log(JSON.parse(ajax.responseText));
console.log(eval("("+ajax.responseText+")"));
}
}
// 第三步: open一个链接
ajax.open(“GET”,“h51701.json”,false);//true异步请求,false同步

        // 第四步: send一个请求。 可以发送对象和字符串,不需要传递数据发送null
        ajax.send(null);

36、MVC和MVVM的区别
如果前端没有框架,只使用原生的html+js,MVC模式可以这样理解。将html看成view;js看成controller,负责处理用户与应用的交互,响应对view的操作(对事件的监听),调用Model对数据进行操作,完成model与view的同步(根据model的改变,通过选择器对view进行操作);将js的ajax当做Model,也就是数据层,通过ajax从服务器获取数据(多少有点强行MVC,因为Model层被弱化了)。
MVVM与MVC最大的区别就是:它实现了View和Model的自动同步,也就是当Model的属性改变时,我们不用再自己手动操作Dom元素,来改变View的显示,而是改变属性后该属性对应View层显示会自动改变。
36、面试中的一些坑
(1)连等运算的顺序以及为a赋值对象的意义
var a={
‘hh’:2
}
var b=a;
a.m=a={‘ss’:22};
console.log(a);//{‘ss’:22}
console.log(b);//{hh: 2, m: {ss: 22}};
需要注意的是连等运算时从右到左,上述表达式可以拆分为a={‘ss’:22};a.m=a;而且两个表达式是相互隔离的,a.m的中的a还是指向原来的a,为a新赋值的相当于开辟了一个新的地址,所以改变不会影响b
(2)var obj={
fun:function(){
console.log(this)
}
}
var f1=obj.fun;
fi();
obj.fun();
这两个的this的区别
(3)

你可能感兴趣的:(javascript)