一:DOM leave1 好比onclick只是一个属性,能够被覆盖,因此一个元素只能有一个onclick事件 写在字符串里至关于运行字符串里的代码javascript
二: DOM L2中,事件注册(事件监听队列)css
false
或者 不传 参数 儿子,爸爸,爷爷true
爷爷,爸爸,儿子
event.stopPropagation()
。stopPropagation,中止传播,不要再告诉父母了,不要再往上执行冒泡事件了aTag.addEventListener("click",function(e){
e.preventDefault();//禁止默认效果
e.stopPropagation();//阻止冒泡
});
复制代码
事件触发通常来讲会按照上面的顺序进行,可是也有特例,若是给一个目标节点同时注册冒泡和捕获事件,事件触发会按照注册的顺序执行。html
// 如下会先打印冒泡而后是捕获
node.addEventListener('click',(event) =>{
console.log('冒泡')
},false);
node.addEventListener('click',(event) =>{
console.log('捕获 ')
},true)
复制代码
四:事件委托(事件代理) 事件代理 若是一个节点中的子节点是动态生成的,那么子节点须要注册事件的话应该注册在父节点上前端
<ul id="ul">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
let ul = document.querySelector('##ul')
ul.addEventListener('click', (event) => {
console.log(event.target);//li
console.log(event.currentTarget)//ul
})
</script>
复制代码
事件代理的方式相对于直接给目标注册事件来讲,有节省内存的优势 event.target和event.currentTarget的区别: event.target是点击到的最底层的那个元素 event.currentTarget是注册事件注册在那个元素上,那个元素就是currentTarget,因此通常是父元素java
什么能够发送请求?不光form表单能够发送请求,a标签(须要点击),link标签,script,图片,均可以发送请求。 解决先后端耦合:前端要作的事:事先写好成功和失败的函数。成功了就返回给我一个成功的提示,而后我根据提示执行成功的函数,若是给个人提示是失败,就执行失败的函数。node
,不能访问。 真名的名字应该是:动态标签跨域请求!即利用动态标签script进行跨域请求的技术。linux
面试官:说说jsonp: 为何要用jsonp? jsonp要解决的是浏览器的跨域数据访问的问题。(两个不一样域名的网站)。 因为同源策略,不一样域名不能发请求。可是HTML的<script>
元素是一个例外,script标签的请求是不受域名限制的,而Ajax是受域名限制的。 如何使用jsonp?webpack
请求方:mataotao.com的前端(浏览器),一个网站的前端 响应方:jack.com的后端(服务器),另外一个网站的后端 过程:ios
<script>
标签。src
指向响应方,同时传一个查询参数?callback=xxxfn
<script>
获得响应后会当即执行响应过来的内容。因此响应方根据查询参数构造形如xxxfn("后台传过来的数据")
这样的响应。把要传的数据写在callback函数的参数里。xxxfn('后台传过来的数据')
来获得后台传过来的数据,并处理。这就是jsonpgit
jsonp为何不能用post请求 jsonp是经过动态建立script实现的,而script标签发送的是get请求。(缺点,get不安全) 优缺点: JSONP 使用简单且兼容性不错,可是只限于 get 请求
返回的状态码: 2开头:成功 3开头:重定向 4开头:客户端错误 5开头:服务器错误
用 form 能够发get或post或其余请求,可是会刷新页面或新开页面 用 a 能够发 get 请求,可是也会刷新页面或新开页面 用 img 能够发 get 请求,可是只能以图片的形式展现 用 link 能够发 get 请求,可是只能以 CSS、favicon 的形式展现 用 script 能够发 get 请求,可是只能以脚本的形式运行。 上面几个均可以发请求,可是各有缺点。
说说Ajax: Ajax 是JS 能够用直接发起 任意HTTP 请求的技术。
具体来讲,AJAX 包括如下几个步骤。
面试问题:请使用原生JS发送Ajax请求 通常面试大几率会问这个问题,写不对必定过不了面试
下面四句代码必定要记住:
myButton.addEventListener("click",(e)=>{
//这四句必定要记住
let request = new XMLHttpRequest();
request.onreadystatechange = ()=>{
request.onreadystatechange = ()=>{
if(request.readyState ===4){//Ajax状态码为4
console.log("请求和响应都完毕了");
if ( request.status>=200&&request.status<300){//响应成功(http状态码)
console.log(request.responseText);//打印响应的第四部分,字符串
}else if(request.status>=400){
console.log("响应失败");
}
}
}
}
request.open('GET','/xxx')//配置request.参数分别为方法和路径
request.setRequestHeader('content-type','x-www-form-urlencoded')//设置响应头必定要写在
request.send("a=1&b=2");//发送请求
//这四句必定要记住
})
复制代码
什么是同源策略? 用 form
、a
、img
、link
、script
、均可以跨域发送请求。 可是只有 协议+域名+端口 如出一辙才容许发 AJAX 请求。 为何要有同源策略? 简单地说就是例如使用form发送请求后,就会刷新页面,因此原页面没有了,就认为是安全的.可是Ajax能够吧响应内容读取了.而且显示在本页面上.因此出现安全性问题。
Ajax没法跨域报的错误:
CORS的英文Cross-Origin Resource Sharing,即跨域(源,站)资源共享(跨域) 那么如何使用CORS突破同源策略解决Ajax的没法跨域发送请求的问题?
只要服务器端设置响应头就能够实现跨域:
response.setHeader('Access-Control-Allow-Origin','http://mataotao.com:8001')
复制代码
这句话是CORS跨域(突破同源策略)的核心,即容许别的网站(例如http://mataotao.com:8001)跨域向我发Ajax请求,而且容许响应。
为何不使用jsonp,而是用CORS来跨域? CORS相对于JSONP,CORS能够发任意请求,而JSONP只能发送get请求
要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: 'Hello', b: 'World'}); //结果是 '{"a": "Hello", "b": "World"}'
复制代码
要实现从 JSON 转换为对象,使用 JSON.parse() 方法:
var obj = JSON.parse('{"a": "Hello", "b": "World"}'); //结果是 {a: 'Hello', b: 'World'}
复制代码
Cookie 是服务器保存在浏览器的一小段文本信息。浏览器每次向服务器发出请求,就会自动附上这段信息。 Cookie的做用过程:
COokie的做用:
HTTP 回应:Cookie 的生成(服务器端生成cookies)
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: yummy_cookie=choco
Set-Cookie: tasty_cookie=strawberry
[page content]
复制代码
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
复制代码
HTTP 请求:Cookie 的发送(浏览器发送Cookie)
浏览器向服务器发送 HTTP 请求时,每一个请求都会带上相应的 Cookie。也就是说,把服务器早前保存在浏览器的这段信息,再发回服务器。这时要使用 HTTP 头信息的Cookie字段。
Cookie: foo=bar
复制代码
上面代码会向服务器发送名为foo的 Cookie,值为bar。
Cookie字段能够包含多个 Cookie,使用分号(;)分隔。
Cookie: name=value; name2=value2; name3=value3
复制代码
下面是一个Http请求的例子。
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: yummy_cookie=choco; tasty_cookie=strawberry
复制代码
读、写、删除、Cookie
读document.cookie
,前提是该 Cookie 不能有HTTPOnly
属性。
document.cookie
写入 Cookie 的例子以下。
document.cookie = 'fontSize=14; '
+ 'expires=' + someDate.toGMTString() + '; '
+ 'path=/subdirectory; '
+ 'domain=*.example.com';
复制代码
expires
属性为一个过去的日期。什么是session?
window.sessionStorage
和window.localStorage
接口用于脚本在浏览器保存数据。
window.sessionStorage.setItem('key', 'value');
window.localStorage.setItem('key', 'value');
复制代码
window.sessionStorage.getItem('key')
window.localStorage.getItem('key')
复制代码
localStorage.removeItem('key');
window.localStorage.clear()
复制代码
注意只能存字符串类型的。
区别:SessionStorage 在用户关闭页面(会话结束)后就失效。其他的和localstorage同样
Cookie和Storage对比:
HTTP缓存有利于web性能优化。HTTP缓存能够重复利用以前获取的资源而不用反复请求,以达到性能优化的目的。 方法
在响应里设置响应头 Cache-Control: max-age=30
意思就是30秒以内,浏览器再访问相同的URL的时候,就不发请求,直接从内存里拿到已经缓存的main.js。 问题:那么js和css更新了怎么办? 浏览器请求时发现是相同的URL才使用缓存,那么能够设置查询参数,例如第二个版本的js能够写<script src="./main.js?v=2"></script>
,来保证URL的不一样,从新获取新的js文件。这样便可以缓存好久,又能够随时更新.(总结:设置查询参数,保证URL的不一样)
Expires 是之前用来控制缓存的http头,Cache-Control是新版的API。
如今首选 Cache-Control。
若是在Cache-Control响应头设置了 "max-age" 或者 "s-max-age" 指令,那么 Expires 头会被忽略。
响应头设置方式: Expires: Wed, 21 Oct 2015 07:28:00 GMT
Expires 响应头包含日期/时间, 即在此时候以后,响应过时。 注意: 由于过时标准的时间用的是本地时间,因此不靠谱,因此要游侠使用Cache-Control代替Expires
答面试官: 与Cache-Control的区别就是:
MD5是消息摘要算法。用于确保信息传输完整一致。能够判断两次信息传输是否完整一致。
例如
304 Not Modified: HTTP 304 未改变说明无需再次传输请求的内容,也就是说能够使用缓存的内容。
HTTP 304 :没有响应体
ETag与 Cache-Control的区别
MVC是一种代码组织形式,只是组织代码的思想.给面试官将MVC
MVC就是把代码分为三块
M,V,C在代码中能够用对象或者类来表示
曾使用 webpack3 用 babel-loader 把 ES6 转译为 ES5 用 sass-loader 把 SCSS 转译为 CSS 做用:
请写出一个符合 W3C 规范的 HTML 文件,要求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>个人页面</title>
<link rel="stylesheet" href="./style.css">
<link rel="stylesheet" href="./print.css" media="print">
<link rel="stylesheet" href="./mobile.css" media="(max-width: 500px)">
<style> body{ padding:0; margin:0; } </style>
</head>
<body>
<svg version="1.1" width="100px" height="100px" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" fill="red"/>
</svg>
<script src="./main.js"></script>
<script src="./gbk.js" charset="GBK"></script>
</body>
</html>
复制代码
2016年腾讯前端面试题: 移动端是怎么作适配的? 回答要点:
(能够参考我写的博客 CSS5:移动端页面(响应式) CSS9:动态 REM-手机专用的自适应方案) 答:
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
复制代码
content="width=device-width
表示宽度等于设备宽度,意思就是不要将页面宽度变成980px,用设备宽度. user-scalable=no
表示用户不以缩放 initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0
初始缩放倍数,最大缩放倍数,最小缩放倍数,都是1.0,即不能缩放
经过媒体查询,根据不一样条件,使用不一样的css样式。 例如:
<style> @media (max-width: 800px){/*若是媒体知足0到800 之间,那么会应用这里面的样式*/ body{ background-color: red; } } </style>
复制代码
由于手机须要兼容不少不一样宽度的手机设备,因此将长度单位依赖于手机设备宽度,使用动态rem方案,那么就能够在不一样手机上实现相同比例的页面缩放而不影响布局。 rem:root em,即<html>
的font-size
. 实现动态rem,主要须要下面两步: 1在<head>
标签里加上以下代码,让10rem等于页面宽度
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<title>动态REM</title>
<script></script>
</head>
复制代码
2使用sass自动将设计稿的px转换为rem 在scss文件里写这样一个函数:
@function px( $px ){
@return $px/$designWidth*10 + rem;
}
$designWidth : 640; // 640 是设计稿的宽度,你要根据设计稿的宽度填写。设计师的设计稿宽度须要统一
复制代码
就可使用px()函数将像素转化为rem。
2017年腾讯前端实习面试题(二面): 用过CSS3吗? 实现圆角矩形和阴影怎么作? (搜索MDN border-radius) 答: 用过。例如阴影,圆角,动画,渐变和过渡 1.圆角: 简写属性border-radius
。例如 border-radius: 30px;
border-radius: 50%;
半径参数能够是长度单位,也能够是百分比单位。
也能够分别设置四个角
border-top-left-radius: 4px 2px;
border-top-right-radius: 3px 4px;
border-bottom-right-radius: 6px 2px;
border-bottom-left-radius: 3px 4px;
复制代码
半径参数能够是一个或两个,一个参数表明圆形圆角,两个参数是椭圆圆角
2.阴影:
语法: box-shadow:inset x-offset y-offset blur-radius spread-radius color
五个参数分别是:投影方式 X轴偏移量 Y轴偏移量 阴影模糊半径 阴影扩展半径 阴影颜色
出处同上(一面二面都问了): 什么是闭包,闭包的用途是什么? JavaScript高程P178 闭包的用途
答:
闭包是指有权访问另外一个函数做用域中的变量的函数。 例如
function foo(){
var local = 1
function bar(){
local++
return local
}
return bar
}
var func = foo()
func()
复制代码
bar函数能够访问变量local,bar就是一个闭包。
function A(num) {
//核心代码
(funnction(){
for(var i = 0; i<num; i++) {
num++;
}
})()
//核心代码结束
console.log(i)//underfined
}
复制代码
匿名自执行函数在内部造成了一个闭包,使i变量只有块级做用域。闭包的本质是函数,其实在这里闭包就是那个匿名函数,这个闭包能够获得函数A内部的活动变量,又能保证本身内部的变量在自执行后直接销毁。
function B(){
var x = 100;
return {
function(){
return x
}
}
}
var m = B()//运行B函数,生成活动变量 x被m引用
复制代码
运行B函数,生成活动变量 x被m引用, 变量x不会被销毁。 运行B函数,返回值就是B内部的匿名函数,此时m引用了变量x,因此B执行后x不会被释放,利用这一点,咱们能够把比较重要或者计算耗费很大的值存在x中,只须要第一次计算赋值后,就能够经过m函数引用x的值,没必要重复计算,同时也不容易被修改。 3. 封装私有变量
function Person(){
var name = 'default';
this.getName:function(){
return name;
}
this.setName:function(value){
name = value;
}
}
console.log(Person.getName())//default
console.log(Person.setName('mike'))
console.log(Person.getName())//mike
复制代码
设置了两个闭包函数来操做Person函数内部的name变量,除了这两个函数,在外部没法再访问到name变量,name也就至关因而私有成员。
阮一峰的javascript教程--this 深刻浅出 妙用Javascript中apply、call、bind
答:
若是在函数中包含多层的this,this的指向是不肯定的。须要把this固定下来,避免出现意想不到的状况。JavaScript提供了call、apply、bind这三个方法,来切换/固定this的指向。
函数实例的call方法,能够指定函数内部this的指向(即函数执行时所在的做用域),而后在所指定的做用域中,调用该函数。
var obj = {};
var f = function () {
return this;
};
f() === window // true
f.call(obj) === obj // true
复制代码
call的第一个参数就是this所要指向的那个对象,后面的参数则是函数调用时所需的参数。
apply方法的做用与call方法相似,也是改变this指向,而后再调用该函数。惟一的区别就是,它接收一个数组做为函数执行时的参数。
apply方法的第一个参数也是this所要指向的那个对象,若是设为null或undefined,则等同于指定全局对象。第二个参数则是一个数组,该数组的全部成员依次做为参数,传入原函数。原函数的参数,在call方法中必须一个个添加,可是在apply方法中,必须以数组形式添加。
function f(x, y){
console.log(x + y);
}
f.call(null, 1, 1) // 2
f.apply(null, [1, 1]) // 2
复制代码
bind方法用于将函数体内的this绑定到某个对象,而后返回一个新函数。
bind方法的参数就是所要绑定this的对象。
var counter = {
count: 0,
inc: function () {
this.count++;
}
};
var func = counter.inc.bind(counter);
func();
counter.count // 1
复制代码
上面代码中,counter.inc方法被赋值给变量func。这时必须用bind方法将inc内部的this,绑定到counter,不然就会出错。
出处同上: 请说出至少 8 个 HTTP 状态码,并描述各状态码的意义。
例如:
状态码 200 表示响应成功。
答:
状态码 202 表示:服务器已接受请求,但还没有处理。 状态码 204 表示:请求处理成功,但没有资源可返回。 状态码 206 表示:服务器已经成功处理了部分 GET 请求。
状态码 301 表示:请求的资源已被永久的分配了新的 URI。 状态码 302 表示:请求的资源临时的分配了新的 URI。
状态码 400 表示:请求报文中存在语法错误。 状态码 401 表示:发送的请求须要有经过 HTTP 认证的认证信息。 状态码 403 表示:对请求资源的访问被服务器拒绝了。 状态码 404 表示:服务器上没法找到请求的资源。
状态码 500 表示:服务器端在执行请求时发生了错误。 状态码 503 表示:服务器暂时处于超负债或正在进行停机维护,如今没法处理请求。
出处同上: 请写出一个 HTTP post 请求的内容,包括四部分。 其中 第四部分的内容是 username=ff&password=123 第二部分必须含有 Content-Type 字段 请求的路径为 /path
看个人博客HTTP入门(一):在Bash中curl查看请求与响应
答: 请求:
1 POST /path HTTP/1.1
2 Host: www.baidu.com
2 User-Agent: curl/7.20.0 (x86_64-unknown-linux-gnu) libcurl/7.20.0 zlib/1.2.8
2 Accept: */*
2 Content-Length: 24
2 Content-Type: application/x-www-form-urlencoded
3
4 username=ff&password=123
复制代码
响应:
1 HTTP/1.1 200 OK
2Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform
2Content-Length: 2443
2Content-Type: text/html(百度返回的时候百度的数据长度和内容的格式)
2Etag: "5886041d-98b"
2Set-Cookie: BDORZ=27315; max-age=86400; domain=.baidu.com; path=/
3
4<!DOCTYPE html> ...
复制代码
1234567890
这三种排序的时间复杂度分别为
O(n*n) O(n log2 n) O(n + max)
答:
O(n*n) 冒泡排序:遍历整个数组,依次比较相邻两个元素,将小的排在前面,大的排后面,这样一遍循环下来就能够将最大的元素排到最后,除去已经排过的最大的数,而后再次循环以上操做,直到最后一个为止。
O(n log2 n) 快速排序:以第一个元素为基准,比这个元素小的元素排在左边,比这个元素大的排右边,再以该元素左边和右边的第一个元素为基准,在子区间重复以上的操做,直到只有一个数字排序为止。
O(n + max) 基数排序:首先根据个位数的数值,将须要排序的一串数值分配到0-9的桶中。接着将这些桶中的数值从新串起来,造成新的数列。接着根据十位数、百位数直至最高位重复以上操做。
著名前端面试题:
一个页面从输入 URL 到页面加载显示完成,这个过程当中都发生了什么? 这一题是在挖掘你的知识边界,因此你知道多少就要答多少。
能够先查阅一些资料再查,可是不要把本身不懂的东西放在答案里,面试官会追问的。
知乎上:从输入 URL 到页面加载完成的过程当中都发生了什么 答:
服务器接到请求后,回想客户端发送HTTP响应报文。HTTP响应报文也是由三部分组成: 状态码, 响应报头和响应报文。服务器会根据 HTTP 请求中的内容来决定如何获取相应的 HTML 文件,并将获得的 HTML 文件发送给浏览器。
浏览器解析渲染页面 浏览器是一个边解析边渲染的过程。在浏览器尚未彻底接收 HTML 文件时便开始渲染、显示网页。在执行 HTML 中代码时,根据须要,浏览器会继续请求图片、CSS、JavsScript等文件,过程同请求 HTML 。
关闭TCP链接或继续保持链接
(1)主机向服务器发送一个断开链接的请求(不早了,我该走了);
(2)服务器接到请求后发送确认收到请求的信号(知道了);
(3)服务器向主机发送断开通知(我也该走了);
(4)主机接到断开通知后断开链接并反馈一个确认信号(嗯,好的),服务器收到确认信号后断开链接;
著名面试题: 如何实现数组去重? 假设有数组 array = [1,5,2,3,4,2,3,1,3,4] 你要写一个函数 unique,使得 unique(array) 的值为 [1,5,2,3,4] 也就是把重复的值都去掉,只保留不重复的值。
要求:
不要作多重循环,只能遍历一次 请给出两种方案,一种能在 ES 5 环境中运行,一种能在 ES 6 环境中运行(提示 ES 6 环境多了一个 Set 对象) 从 JavaScript 数组去重谈性能优化 也谈JavaScript数组去重 答:
ES5: 思路:核心是构建了一个 hash 对象来替代 indexOf. 注意在 JavaScript 里,对象的键值只能是字符串,所以须要 var key = typeof(item) + item 来区分数值 1 和字符串 '1' 等状况。 只循环一遍
function unique(arr) {
var ret = []
var hash = {}
for (var i = 0; i < arr.length; i++) {
var item = arr[i]
var key = typeof(item) + item
if (hash[key] !== 1) {
ret.push(item)
hash[key] = 1
}
}
return ret
}
复制代码
ES6:ES2015引入了一种叫做Set的数据类型。顾名思义,Set就是集合的意思,它不容许重复元素出现。 若是重复添加同一个元素的话,Set中只会存在一个。包括NaN也是这样
function unique(array) {
return Array.from(new Set(array));
}
复制代码
第一个框: object是实例对象,他的模板对象(原型对象)在Object()构造函数里面. 构造函数.prototype
指向的是原型对象,即模板对象. 由构造函数构造出来的实例对象.__proto__
也指向的是原型对象,即模板对象. 因此true.
第二个框: fn是一个实例函数,是由用来构造出函数的构造函数造出来的. 因此fn.__proto__ === Function.prototype
任何构造函数.prototype
都是一个对象. 由于fn.__proto__ === Function.prototype
因此fn.__proto__.__proto__ === Object.prototype
等价于 Function.prototype.__proto__ === Object.prototype
等价于 一个对象.__proto__ === Object.prototype
因此是true
第三个框同理.
第四个框比较难理解: 一个实例函数是由用来构造出函数的构造函数造出来的.
Object,Function,Array都是一个实例函数,函数也是一种类型,就像String是一种类型,Number是一种类型同样,函数这个类型里的实例函数由函数的构造函数造出来!很难理解 因此实例函数.__proto__===构造函数.prototype
实例函数的构造函数就是Function
有点鸡生蛋蛋生鸡的感受.
第五个框同理
function fn(){
console.log(this)
}
new fn()
复制代码
new fn()
会执行 fn
,并打印出 this
,请问这个 this
有哪些属性?这个 this
的原型有哪些属性? 答: 这个this
就是new
建立的新对象. this
(这个新对象)有__protot__
属性,它指向fn
构造函数的原型即fn.prototype
这个原型(即fn.prototype
)有两个属性:
construct
:它的值是构造函数fn
__proto__
: 它指向Object.prototype
解读:
fn()
是构造函数new fn()
就是一个构造函数new
出来的新对象. 他的自有属性为空,共有属性为空,由于都没有设置 由于他的自有属性为空,因此他只有一个__proto__
指向构造函数.prototype
(即原型)了. 共有属性为空,因此他的原型就是只有constructor
指向构造函数和__proto__
指向Object.prototype
(由于原型自己就是对象类型,因此指向对象的构造函数) 例子:JSON 和 JavaScript 是什么关系? JSON 和 JavaScript 的区别有哪些?
关系:JSON 是一门抄袭/借鉴 JavaScript 的语言,同时也是一种数据交互格式,JSON 是 JavaScript 的子集(或者说 JSON 只抄袭了一部分 JavaScript 语法,并且没有新增任何原创的语法)
区别:JSON 不支持函数、undefined、变量、引用、单引号字符串、对象的key不支持单引号也不支持不加引号、没有内置的 Date、Math、RegExp 等。 而 JavaScript 全都支持。
前端 MVC 是什么?(10分) 请用代码大概说明 MVC 三个对象分别有哪些重要属性和方法。(10分)
答一:
MVC 是什么 MVC 是一种设计模式(或者软件架构),把系统分为三层:Model数据、View视图和Controller控制器。 Model 数据管理,包括数据逻辑、数据请求、数据存储等功能。前端 Model 主要负责 AJAX 请求或者 LocalStorage 存储 View 负责用户界面,前端 View 主要负责 HTML 渲染。 Controller 负责处理 View 的事件,并更新 Model;也负责监听 Model 的变化,并更新 View,Controller 控制其余的全部流程。
答二: MVC就是把代码分为三块
V(view)只负责看得见的东西. M(model)只负责跟数据相关的操做,不会出现DOM,不会出现任何的html/css操做.例如model里只会有初始化数据库,获取数据方法fetch(),保存数据的方法save() C(controller)只负责把这些view和model组合起来,找到view,找到model,使用model完成数据修改业务,并修改view的显示 V:视图 M:数据 C:控制器
MVC是一种代码组织形式,不是任何一种框架,也不是任何一种技术,只是组织代码的思想,要作的就是V和M传给C,C去统筹 在js里,MVC分别由三个对象去担任三个职责
代码一:
window.View = function(xxx){
return document.querySelector(xxx);
}
复制代码
window.Model = function(object){
let resourceName = object.resourceName;
return {
init: function () {
},
fetch: function () {
},
save: function (object) {
}
}
}
复制代码
window.Controller = function(options){
var init = options.init;
let object = {
view:null,
model:null,
init:function(view,model){
this.view = view;
this.model = model;
this.model.init();
init.call(this,view,model);
this.bindEvents();
},
bindevnets:function(){},
};
for (let key in options) {
if(key !=='init'){
object[key] = options[key]
}
};
return object;
}
复制代码
代码二:
var model = {
data: null,
init(){}
fetch(){}
save(){}
update(){}
delete(){}
}
view = {
init() {}
template: '<h1>hi</h1'>
}
controller = {
view: null,
model: null,
init(view, model){
this.view = view
this.model = model
this.bindEvents()
}
render(){
this.view.querySelector('name').innerText = this.model.data.name
},
bindEvents(){}
}
复制代码
如何在 ES5 中如何用函数模拟一个类?(10分)
答一:
使用原型对象,构造函数,new来模拟类.
prototype
属性指向原型对象.__proto__
指向原型对象. 这样当构造函数建立一个实例化的对象的时候,就即拥有本身的私有变量和方法,也有公有的变量和方法了,实例化出来的对象的私有方法和变量修改都不会互相有影响,只有在修改公有的变量和方法的时候是对全部实例生效的答二: ES 5 没有 class 关键字,因此只能使用函数来模拟类。
function Human(name){
this.name = name
}
Human.prototype.run = function(){}
var person = new Human('frank')
复制代码
上面代码就是一个最简单的类,Human
构造函数建立出来的对象自身有 name
属性,其原型上面有一个 run
属性。
用过 Promise 吗?举例说明。 若是要你建立一个返回 Promise 对象的函数,你会怎么写?举例说明。
答:
答一: 用过 Promise,好比 jQuery 或者 axios 的 AJAX 功能,都返回的是 Promise 对象。
$.ajax({url:'/xxx', method:'get'}).then(success1, error1).then(success2, error2)
答二: 用过.例如使用jQuery的Ajax()发送请求,成功或失败后的回调函数,就是使用promise封装的
function success(responseText){
console.log("成功")
console.log(responseText);//responseTex
}
function fail(request){
console.log("失败")
console.log(request);
}
myButton.addEventListener("click",(e)=>{
//使用ajax
$.ajax({
method:"post",
url:"/xxx",
data:"username=mtt&password=1",
dataType:'json'//预期服务器返回的数据类型,若是不写,就是响应里设置的
}
).then(success,fail)//$.ajax()返回一个promise
})
复制代码
function xxx(){
return new Promise((f1, f2) => {
doSomething()
setTimeout(()=>{
if(success){
f1();
}else{
f2();
}
},3000)
})
}
调用方法:
xxx().then(success, fail)
复制代码
或者:
function asyncMethod(){
return new Promise(function (resolve, reject){
setTimeout(function(){
成功则调用 resolve
失败则调用 reject
},3000)
})
}
复制代码