一: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處理的邏輯順序。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)
})
}
複製代碼