媒稱,南京是一座現代化城市,但它有一種古老的蘊味,這座城市的歷史遺韻使建筑與自然環境很和諧。
據英國廣播公司網站5月13日報道,南京首次建都于公元229年,長期以來是中國最重要(和最大)的內河港口之一,也是公認的中國四大古都之一。這里發現了距今約60萬年的直立人化石;明朝時期環繞這座城市的石頭城墻距今已有600年的歷史,而今仍然與現代的摩天大樓屹立在一起,使這座城市跟其復雜多變的過去有了永恒的視覺聯系。
原籍英格蘭設菲爾德、現居住在南京的中學教師弗雷婭·德魯說:“從北京西路附近民國時期的低層建筑、新街口附近高聳的摩天大樓到老浦口蜿蜒的陋屋小巷,南京的建筑千差萬別。”
<iframe data-filtered="filtered" frameborder="0" height="0" src="http://cpro.baidustatic.com/cpro/ui/c.html" width="0"></iframe>
報道稱,雖然這種并列毗鄰在其他城市可能看上去不協調,但在南京行得通。2018年來到這里的蘇格蘭教師埃德·庫勒姆說:“這座城市的道路,往往綠樹成蔭,起起伏伏;老舊居住區緊挨著非常現代化的建筑。南京無疑是一座現代化城市,但它有一種古老的蘊味,這座城市的歷史遺韻使建筑與自然環境很和諧。”
報道還稱,作為一個外來人口不斷增加的大學城,南京的節奏不同于熙熙攘攘的北京,也不同于極其新潮的上海,而是新來者樂于接受的平和折衷。
庫勒姆解釋說,盡管擁有830萬人口,但南京是中國為數不多的很容易讓人獲得安寧和平靜的大城市之一。他說:“在浦口(南京西北部的一個地區),坐30分鐘的公共汽車就能把你送到老山風景區的邊緣。這片大面積的森林覆蓋的丘陵有許多小路和小徑,很容易把喧鬧的人群拋在身后。”
報道稱,就在南京市中心,玄武湖提供了一個躲避喧囂的安靜之處,玄武湖公園內有寺廟、茶館和餐廳。為了更好地了解南京的歷史,庫勒姆建議到老門東走一走,就在秦淮河以北,是一條經過整修的步行街。老門東是該市歷史最悠久的商業街之一,其特色是擁有古典的木結構建筑(修舊如舊),內有紀念品商店,還有供應當地特色美食的小餐館,比如鹽水鴨、肉丸和美味糕點等等。
報道還稱,與北京或西安的城墻不同,南京的老城墻不是幾何形狀的,而是繞著湖和山而建。因此,自然景觀往往出現在意想不到的城區。像長江、鐘山、玄武湖這些處于城市中心的自然景觀給人帶來的驚喜,正是新居民們喜歡生活在這里的原因所在。
庫勒姆說:“對我來說,生活在南京意味著避開熙熙攘攘的大街,轉入老街小巷,可能遇到幾處院落、幾泓碧水或幾片幽林。正是這種巨大的多元性讓南京具有了自己的魅力。”
庫勒姆說,“對于喜歡避開線性基線重擊聲的人們”,這座城市還有許多低調的夜總會和現場音樂演出場所。對于想念老家食物的人來說,這里并不缺少迎合外國人和留學生的外國餐廳和咖啡館。在城市里轉一圈很容易。南京擁有一個覆蓋該市大部分地區的高效、寬敞的地鐵系統,不過自行車也是一個選項,這里有適合騎車的寬闊、筆直的道路。
原標題:外國人眼中的古都南京:歷史文化和現代生活融為一體
優點:
缺點:
HTML 提供了一系列內置的元素(如 <div>、<p> 等),而自定義元素則是由開發者自定義的,可以用來擴展 HTML 語義和功能。
在傳統的 HTML 中,我們只能使用已定義的標簽來創建元素,如 <div>、<p>、<span> 等。但隨著 Web 技術的不斷發展,HTML5 引入了自定義元素的功能,允許開發者創建自己的標簽,并賦予其特定的行為和樣式。
帶你用最簡單的方式理解最全面的BFC嗶哩嗶哩bilibili
BFC,即塊級格式化上下文(Block Formatting Context),是CSS中的一個概念。它是指一個獨立的渲染區域,其中的元素按照一定的規則進行布局和渲染。
BFC的主要作用是控制元素在布局上的行為,包括外邊距的塌陷、浮動元素對周圍元素的影響以及清除浮動等。以下是BFC的一些特性和應用:
創建BFC的方式有多種,包括:
總而言之,BFC是一種控制元素布局行為的機制,它可以解決一些常見的布局問題,如外邊距塌陷、浮動元素重疊等。了解BFC的使用和原理對于前端開發中復雜布局的實現非常有幫助。
① 使用Flexbox:通過將父容器設置為display: flex;,然后使用justify-content: center;和align-items: center;屬性來水平和垂直居中子元素。
.parent {
display: flex;
justify-content: center;
align-items: center;
}
② 使用Grid布局:通過將父容器設置為display: grid;,然后使用place-items: center;屬性來水平和垂直居中子元素。
.parent {
display: grid;
place-items: center;
}
③ 使用絕對定位和transform屬性:將子元素的位置設置為絕對定位,并且使用top: 50%;和left: 50%;將元素的左上角移動到父容器的中心,然后使用transform: translate(-50%, -50%);將元素的中心與父容器的中心對齊。
.parent {
position: relative;
}
.child {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
④ 使用表格布局:將父容器設置為display: table;,然后將子元素設置為display: table-cell;和vertical-align: middle;以實現水平和垂直居中。(文本水平垂直居中)
.parent {
display: table;
}
.child {
display: table-cell;
vertical-align: middle;
text-align: center;
}
⑤父flex + 子margin:auto
⑥絕對定位均設0 + margin:auto
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
/*
思路:
1、容器寬度設為100%來填充整個頁面寬度
2、為左右中三者設置float:left,以此可以顯示在一行
3、為left和right部分設置負的margin值,讓它們移到center行中,但注意,現在的left和right將center左右部分覆蓋了
4、解決覆蓋問題,有兩種方式:
(1) 為center左右設置內邊距,但這時會將頁面撐大,所以我們要將內邊距合并到100%的寬度里,這里我們想到了用怪異盒模型
(2) 用定位的方式解決,為容器wrapper設置內邊距,然后為left和right設置相對定位,并為其移動到左右兩邊
?
擴展:
與雙飛翼布局的區別?
圣杯布局通過設置負邊距與容器內邊距來使三欄顯示于一列,而雙飛翼布局則為中間列額外包裹添加外邊距來防止左右兩側遮擋,兩者實現效果相似
*/
.item {
height: 100px;
/* 這里設置浮動是為了讓三者可以并排顯示 */
float: left;
}
?
.center {
/* 為了防止左右兩塊與center重疊,我們要為其設置內邊距 */
/* padding: 0 300px; */
/* 方式一:將盒子模型設為怪異盒模型,防止padding將左右頂開 */
/* box-sizing: border-box; */
}
?
.center {
width: 100%;
background-color: green;
}
?
.wrap {
padding:0 300px;
}
?
.left {
width: 300px;
background-color: yellow;
/* 為了讓left塊和center在同一行,需要用負的margin值讓它向回移動 */
margin-left: -100%;
/* 方式二:設relative */
position: relative;
left: -300px;
}
?
.right {
width: 300px;
background-color: red;
/* 為了讓right塊和center在同一行,需要用負的margin值讓它向回移動 */
margin-left: -300px;
/* 方式二:設relative */
position: relative;
right: -300px;
}
</style>
</head>
<body>
<!-- 圣杯布局分左右中三部分 -->
<div class="wrap">
<!-- 為了讓中間內容先渲染,寫在上面 -->
<div class="item center"></div>
<div class="item left"></div>
<div class="item right"></div>
</div>
</body>
</html>
.clearfix::after {
content: "";
clear: both;
display: block;
}
clearfix通過為父元素添加偽元素,并為其添加清除浮動效果來解決浮動元素引起的高度塌陷問題,這里設置display:table主要有兩方面作用:
對于軸線:
對于其中的每一項:
浮動的原理是讓圖片脫離文檔流,直接浮在桌面上。我們一般布局的時候都是只設置寬度不設置高度,讓內容來自動填充高度。但使用浮動后會讓原本填充的高度消失,父元素高度為0,后續添加內容布局會產生混亂,造成高度塌陷,這時候就可以利用清除浮動來解決父元素高度塌陷的問題。
浮動導致的問題及其解決方案:
.clearfix:after{/*偽元素是行內元素 正常瀏覽器清除浮動方法*/
content: "";
display: block;
height: 0;
clear:both;
visibility: hidden;
}
.clearfix{
*zoom: 1;/*ie6清除浮動的方式 *號只有IE6-IE7執行,其他瀏覽器不執行*/
}
①定義grid布局:
②設置行與列的布局
③劃分區域自定義放置元素
grid-template-columns: 120px 120px 120px;
grid-template-rows: repeat(3, 300px);
grid-template-areas:
". header header"
"sidebar content content"
"sidebar . .";
.sidebar {
grid-area: sidebar;
}
?
.content {
grid-area: content;
}
?
.header {
grid-area: header;
}
④劃分區域自動填充元素
⑤自由安排元素位置
⑥所有元素在單元格內的對齊方式
⑦單個元素在單元格內的對齊方式
⑧單元格在容器內的對齊方式
⑨多出來的東西怎么放?隱式網格
一些面試題
基本選擇器:id class 標簽 層次選擇器:后代、子代、兄弟、通用 結構選擇器:第一個、最后一個、奇數偶數個、偽類、偽元素 屬性選擇器:屬性
CSS 的 animation 屬性用于為元素添加動畫效果。以下是 animation 屬性的一些常用子屬性:
1、animation-name: 定義動畫的名稱。
.animation {
animation-name: myAnimation;
}
?
@keyframes myAnimation {
0% { opacity: 0; }
100% { opacity: 1; }
}
2、animation-duration: 定義動畫的持續時間。
.animation {
animation-name: myAnimation;
animation-duration: 2s;
}
3、animation-timing-function: 定義動畫的時間函數(即動畫進度的加速度)。
.animation {
animation-name: myAnimation;
animation-timing-function: ease-in-out;
}
4、animation-delay: 定義動畫開始之前的延遲時間。
.animation {
animation-name: myAnimation;
animation-delay: 1s;
}
5、animation-iteration-count: 定義動畫的播放次數,infinite為永不停止。
.animation {
animation-name: myAnimation;
animation-iteration-count: 3;
}
6、animation-direction`: 定義動畫的播放方向。
.animation {
animation-name: myAnimation;
animation-direction: reverse;
}
7、animation-fill-mode: 定義動畫在播放之前和之后如何應用樣式。
.animation {
animation-name: myAnimation;
animation-fill-mode: forwards;
}
8、animation-play-state: 定義動畫的播放狀態。
.animation {
animation-name: myAnimation;
animation-play-state: paused;
}
這些是 animation 屬性的一些常用子屬性,它們可以用來控制動畫的各個方面,從而創建出豐富多樣的動畫效果。使用這些屬性可以自定義動畫的外觀、持續時間、延遲等。要實現動畫效果,還需要定義動畫的關鍵幀(@keyframes)規則,包含動畫在不同百分比時的樣式。
在 CSS 中,可以使用 @keyframes 規則來定義動畫的關鍵幀(即動畫的不同階段)。@keyframes 規則定義了動畫的每個關鍵幀以及相應的樣式。
下面是一個使用 @keyframes 定義動畫關鍵幀的示例:
@keyframes slide {
0% {
transform: translateX(0);
}
50% {
transform: translateX(100px);
}
100% {
transform: translateX(200px);
}
}
在這個例子中,我們創建了一個名為 slide 的動畫。通過 @keyframes 規則,我們定義了三個關鍵幀:0%、50% 和 100%。
你可以在關鍵幀中定義任意數量的狀態,并根據需要設置不同的樣式屬性。使用百分比來表示關鍵幀的時間點,動畫會根據關鍵幀之間的插值進行平滑過渡。
定義完關鍵幀后,你可以使用 animation-name 屬性將動畫應用到具體的元素上,如下所示:
.element {
animation-name: slide;
animation-duration: 2s;
}
通過將 animation-name 設置為關鍵幀名稱,你可以將定義好的動畫應用于元素,并設置動畫的持續時間(在此示例中為 2 秒)。
請注意,在實際使用中,除了設置關鍵幀的樣式,你還可以使用其他屬性調整動畫的速度、延遲、重復次數等。根據具體需求,你可以進一步完善動畫效果。
CSS 的 transition 屬性用于在元素發生狀態變化時,平滑地過渡(或動畫)到新的樣式。它允許你控制一個或多個 CSS 屬性的變化過程,使得元素的變化更加柔和和可控。
transition 屬性由以下幾個子屬性組成:
1、transition-property:指定要過渡的 CSS 屬性名稱,可以是單個屬性,也可以是多個屬性。 當 transition 屬性只設置了 transition-duration 值時,沒有指定 transition-property 值,默認情況下所有可過渡的 CSS 屬性都會應用過渡效果。
.element {
transition-property: width;
}
2、transition-duration:指定過渡的持續時間,以秒(s)或毫秒(ms)為單位。
.element {
transition-duration: 0.5s;
}
3、transition-timing-function:指定過渡的時間函數,用于控制過渡的速度曲線。常見的值包括 ease(默認值)、linear、ease-in、ease-out 和 ease-in-out,也可以使用貝塞爾曲線來定義自定義的速度曲線。
.element {
transition-timing-function: ease-in-out;
}
4、transition-delay:指定過渡開始之前的延遲時間,以秒(s)或毫秒(ms)為單位。
.element {
transition-delay: 0.2s;
}
通過使用這些子屬性,你可以控制元素的過渡效果,從而實現例如懸停時顏色漸變、尺寸變化、透明度漸變等效果。
例如,下面的代碼演示了一個當鼠標懸停在元素上時,背景顏色發生漸變過渡的效果:
.element {
background-color: blue;
transition-property: background-color;
transition-duration: 0.5s;
transition-timing-function: ease-in-out;
}
?
.element:hover for(let [key, value] of map) {
if(largeStr.indexOf(key)!==-1) {
}
}
background-color: red;
}
以上代碼將使元素的背景顏色在懸停時從藍色平滑地過渡到紅色,過渡時間為 0.5 秒,速度曲線為先加速后減速。這只是 transition 屬性的一個簡單示例,你可以根據需要調整和組合這些子屬性來實現更復雜的過渡效果。
外邊距塌陷是指在垂直方向上,兩個相鄰元素的外邊距(margin)合并成一個外邊距的現象。以下是幾種常見的外邊距塌陷情況及其解決方案:
這些解決方案的原理都是通過改變元素的布局特性來創建新的塊級格式化上下文(BFC),從而阻止外邊距的合并。BFC 可以獨立地控制元素的布局行為,使得外邊距不再發生塌陷。
偽類: 用于已有元素處于某種狀態時為其添加對應的樣式,這個狀態是根據用戶行為而動態變化的
例如:當用戶懸停在指定元素時,可以通過:hover來描述這個元素的狀態,雖然它和一般css相似,可以為 已有元素添加樣式,但是它只有處于DOM樹無法描述的狀態下才能為元素添加樣式,所以稱為偽類
偽元素: 用于創建一些不在DOM樹中的元素,并為其添加樣式
例如,我們可以通過:before來在一個元素之前添加一些文本,并為這些文本添加樣式,雖然用戶可以看見 這些文本,但是它實際上并不在DOM文檔中
綜上所述,<link> 更適合引入外部資源,而 @import 更適合在 CSS 文件中嵌入其他 CSS 文件。如果需要同時加載多個 CSS 文件,最好使用 <link>,以提高頁面的性能和可訪問性。
對象(Object):JavaScript 的對象是一種復合數據類型,用于存儲鍵值對。對象由一組屬性(properties)組成,每個屬性都有一個鍵(key)和對應的值(value)。對象可以通過字面量表示法或構造函數來創建。
函數(Function):JavaScript 是一門函數式編程語言,函數在 JavaScript 中是一等公民。函數是可執行的代碼塊,可以接收參數并返回一個值。可以通過函數聲明或函數表達式的方式定義函數。
數組(Array):JavaScript 數組是一種有序、可變的數據集合,可以存儲多個值。數組可以包含不同類型的數據,并且長度是動態的。可以使用字面量表示法或構造函數來創建數組。
隱式類型轉換是指 JavaScript 在比較或計算操作中自動將一個數據類型轉換為另一個數據類型。這種類型轉換是根據 JavaScript 的類型轉換規則進行的,以下是一些常見的隱式類型轉換規則:
==
運算
補充問題:
當a為多少時,if判斷成立
let a
if(a == 1&&a == 2&&a == 3) {
console.log('success!')
}
答案:
a = {
a:1,
valueOf() {
return a++
}
}
var c = 1;
function c(c) {
console.log(c)
}
c(2)
//函數作?域:局部作?域
var a = 1;
function b() {
a = 10;
return;
//a函數聲明,提前變量a,將a認為是函數b作?域的變量,具有局部效果
function a(){}
}b();
console.log(a); // 1
var m= 1, j = k = 0;
function add(n) {
return n = n+1;
}
y = add(m);
function add(n) {
return n = n + 3;
}
z = add(m);
跨域請求是指在瀏覽器中,當請求的源地址與請求地址的協議、域名、端口號不一致時,會被瀏覽器的同源策略所限制,這是為了保護用戶的信息安全。
響應式設計(Responsive Design)是一種網頁設計和開發的方法,旨在使網站能夠適應不同設備、屏幕尺寸和瀏覽器窗口大小,以提供更好的用戶體驗。響應式設計通過使用靈活的布局、彈性的圖像和媒體查詢等技術,讓網頁能夠根據用戶設備的特性進行自適應和優化。
在開發響應式網站時,需要考慮以下幾個方面:
以下是一些常用的技術和方法來實現響應式設計:
單頁面應用(Single Page Application,SPA)是一種Web應用程序的架構模式,它在加載初始HTML頁面后,通過JavaScript動態地更新頁面的內容,而不需要每次頁面切換時重新加載整個頁面。
與傳統的多頁面應用相比,SPA有以下優勢:
然而,SPA也存在一些劣勢:
原型關系:
? 原型: 在 JS 中,每當定義一個對象(函數也是對象)時,對象中都會包含一些預定義的屬性。其中每個函數對象都有一個prototype 屬性,這個屬性指向函數的原型對象。
原型鏈:函數的原型對象上的constructor默認指向函數本身,原型對象除了有原型屬性外,為了實現繼承,還有一個原型鏈指針_proto_ ,該指針是指向上一層的原型對象,而上一層的原型對象的結構依然類似。因此可以利用_proto_ 一直指向Object的原型對象上,而Object原型對象用Object.prototype.__ proto__ = null表示原型鏈頂端。如此形成了js的原型鏈繼承。同時所有的js對象都有Object的基本方法
特點: JavaScript對象是通過引用來傳遞的,我們創建的每個新對象實體中并沒有一份屬于自己的原型副本。當我們修改原型時,與之相關的對象也會繼承這一改變。
事件委托(或稱事件代理)是一種在前端開發中常用的技術,它利用了事件冒泡機制,將事件處理程序綁定到一個父元素上,而不是直接綁定到每個子元素上。當事件觸發時,事件會經過冒泡階段依次向上傳播至父元素,父元素可以根據事件的目標元素來判斷應該執行哪個事件處理函數。
事件委托的作用主要有以下幾點:
舉個例子,假設有一個列表的父元素,里面包含了多個子元素(項),我們需要為每個子元素綁定點擊事件,實現點擊子元素時改變其樣式。使用事件委托可以這樣處理:
// 獲取父元素
const parentElement = document.getElementById('parent');
?
// 綁定點擊事件到父元素
parentElement.addEventListener('click', function(event) {
// 判斷事件目標是否是子元素(項)
if (event.target && event.target.nodeName === 'LI') {
// 執行事件處理邏輯,例如改變樣式
event.target.classList.toggle('active');
}
});
通過將點擊事件綁定到父元素上,無論新增或刪除了子元素,甚至是動態生成的子元素,都會自動觸發相應的事件處理邏輯,大大簡化了代碼的管理和維護。
Codeconst [a, b] = [1, 2];
也可以通過以下方式提取對象屬性:
Codeconst { name, age } = { name: 'Alice', age: 18 };
Codeconst name = 'Alice';
console.log(`Hello, ${name}!`);
Codeconst arr = [1, 2, 3];
console.log(...arr); // 輸出:1 2 3
Codeclass Person {
constructor(name) {
this.name = name;
}
?
sayHello() {
console.log(`Hello, my name is ${this.name}!`);
}
?
static getInfo() {
console.log('This is a person class.');
}
}
?
const person = new Person('Alice');
person.sayHello(); // 輸出:Hello, my name is Alice!
Person.getInfo(); // 輸出:This is a person class.
Codeconst name = 'Alice';
const age = 18;
?
const person = { name, age };
console.log(person); // 輸出:{ name: 'Alice', age: 18 }
// moduleA.js
export function greet(name) {
console.log(`Hello, ${name}!`);
}
?
// moduleB.js
import { greet } from './moduleA.js';
greet('Alice'); // 輸出:Hello, Alice!
function fetchData() {
return new Promise((resolve, reject) => {
// 異步操作...
if (/* 異步操作成功 */) {
resolve('Data fetched successfully!');
} else {
reject('Failed to fetch data!');
}
});
}
?
fetchData()
.then(data => console.log(data)) // 成功時執行
.catch(error => console.error(error)) // 失敗時執行
.finally(() => console.log('Done')); // 不論成功與否都執行
javascript Codeconst numbers = [1, 2, 3, 4];
?
numbers.forEach(num => console.log(num)); // 遍歷輸出每個元素
const doubledNumbers = numbers.map(num => num * 2); // 對每個元素進行操作并返回新數組
const evenNumbers = numbers.filter(num => num % 2 === 0); // 過濾出符合條件的元素
const sum = numbers.reduce((acc, num) => acc + num, 0); // 對數組進行累加
apply、call 和 bind 都是 JavaScript 中用于改變函數執行上下文(this)的方法,它們的區別如下:
總結:
在 JavaScript 中,基本數據類型(Primitive Types)和引用數據類型(Reference Types)在處理和操作時有所不同。當我們對基本數據類型值進行屬性訪問或方法調用時,JavaScript 會將基本數據類型自動轉換為對應的包裝對象,這個過程稱為裝箱(Boxing)。
下面以數字類型(Number)為例,簡要說明基本數據類型裝箱的過程:
裝箱的過程是自動發生的,JavaScript 引擎會在需要時自動執行裝箱和拆箱操作,使得開發者能夠像操作引用類型一樣操作基本類型。而這種裝箱和拆箱的過程在后臺進行,對于開發者來說是透明的。
需要注意的是,由于裝箱過程涉及到對象的創建和數據拷貝,相比于直接操作基本類型,使用包裝對象會帶來額外的開銷。因此,在不必要的情況下,最好直接操作基本類型,而不是通過裝箱和拆箱操作。
JavaScript中的最大安全整數是 9007199254740991。它可以使用 Number.MAX_SAFE_INTEGER 常量來表示。這個值是由 JavaScript 中的雙精度浮點數表示法決定的,在進行數值運算時不會丟失精度。
超過最大安全整數的數值會導致精度丟失,可能會引發意外的結果。如果需要處理超過最大安全整數范圍的大整數,可以使用第三方的大數庫或者 BigInt 類型(ES2020 新增)來處理。BigInt 類型可以表示任意精度的整數,但是在進行數值計算時需要特別注意性能和兼容性的問題。
CommonJS(簡稱CJS)和ES Modules(簡稱ESM)是兩種不同的模塊化規范,有以下不同:
補充:相同點——CJS和ESM導入時,都會將整個模塊的代碼執行一遍,然后緩存執行的結果
每個node.js文件在執行時都會隱式的、自動的創造一個module對象,同時,module對象會創建一個名叫exports,初始值為{}的屬性:
var module = {
exports:{}
}
為了可以更好的導出對應功能模塊里的內容,它會又隱式的創建一個變量exports:
//隱式的創建了一個變量exports
var exports = module.exports
?
//此時exports和module.exports 引用的是同一個對象
console.log(exports === modules.exports) //true
所以我們通過exports.xxx = xxx的方式進行導出,它最終也是被加到了modules.exports對象中
最終導出的是modules.exports對象,這就意味著如果我們將exports的指向改變,那么通過exports.xxx = xxx添加的導出就不會再添加到modules.exports對象中,xxx也就不會被導出
JS是一門單線程語言,因為它運行在瀏覽器的渲染主線程中(當遇到JS代碼時,渲染主線程會將控制權交給js引擎來處理),而渲染主線程只有一個。
而渲染主線程承擔著諸多工作,渲染頁面,執行js都在其中執行。
如果用同步的方式,極有可能導致主線程產生阻塞,從而導致消息隊列中很多任務無法及時執行。
所以瀏覽器就采取了異步措施,當某些異步任務觸發時,如定時器、網絡請求、事件監聽器等,主線程就會將任務交給其他線程去處理,自身立即結束任務執行,轉而執行后續任務,等到異步任務執行完畢,將事先傳遞的回調函數包裝成任務,加入到對應隊列(延時隊列、微任務隊列、交互隊列)的末尾排隊,等待主線程調度執行。
在這種異步模式下,瀏覽器就不會發生阻塞,保證了單線程的流暢運行。
事件循環又叫消息循環,是瀏覽器渲染主線程的工作方式。
在Chrome的底層實現中,它開啟了一個for的死循環,每次循環從消息隊列中取出第一個任務執行,而其他線程只需要在合適的時機將任務放到消息隊列中。
以前我們會將消息隊列簡單分為宏任務隊列和微任務隊列,現在隨著瀏覽器環境愈發復雜,瀏覽器采用了更加靈活多變的處理方式。
根據W3C官方解釋,每個任務都有不同的類型,同類型的任務須在同一個隊列。不同的隊列有不同的優先級(例如交互隊列優先級大于延時隊列),在一次事件循環中,由瀏覽器自行決定取哪一個隊列的任務,但瀏覽器必須有一個微任務隊列,且其優先級是最高的,必須優先調度執行。
不可以
如果使用常規的Object.getOwnPropertyNames()來判斷,雖然可以將一般的不可枚舉類型屬性也判斷出來,但無法判斷繼承的屬性以及Symbol類型值定義的屬性。所以我們需要使用Reflect.ownKeys()來進行轉換,這樣通過它返回的數組長度就能精準判斷出對象是否為空。
1、正則
String.prototype.trim = function() {
return this.replace(/(^\s*)|(\s*$)/g, "")
}
2、雙指針法
.精靈圖(CSS Sprites)的優點和缺點
精靈圖是一種網頁圖片應用處理方式。就是把網頁中很多小背景圖片整合到一張圖片文件中,再利用CSS的“background-image”,“background-repeat”,“background-position”的組合進行背景圖顯示及定位,達到顯示某一部分背景圖的效果。
精靈圖的優點:
1、減少圖片的體積,因為每個圖片都有一個頭部信息,把多個圖片放到一個圖片里,就會共用同一個頭部信息,從而減少了字節數。
2、減少了網頁的http請求次數,從而加快了網頁加載速度,提高用戶體驗。
3、解決了網頁設計師在圖片命名上的困擾,只需對一張集合的圖片上命名就可以了,不需要對每一個小元素進行命名,從而提高了網頁的制作效率。
4、更換風格方便,只需要在一張或少張圖片上修改圖片的顏色或樣式,整個網頁的風格就可以改變。維護起來更加方便。
精靈圖的缺點:
1.在圖片合并的時候,你要把多張圖片有序的合理的合并成一張圖片,還要留好足夠的空間,防止板塊內出現不必要的背景;這些還好,最痛苦的是在寬屏,高分辨率的屏幕下的自適應頁面,你的圖片如果不夠寬,很容易出現背景斷裂;
2.在開發的時候比較麻煩,你要通過photoshop或其他工具測量計算每一個背景單元的精確位置,這是針線活,沒什么難度,但是很繁瑣;
3.在維護的時候比較麻煩,如果頁面背景有少許改動,一般就要改這張合并的圖片,無需改的地方最好不要動,這樣避免改動更多的css,如果在原來的地方放不下,又只能(最好)往下加圖片,這樣圖片的字節就增加了,還要改動css。
4.精靈圖不能隨意改變大小和顏色。精靈圖改變大小會失真模糊,降低用戶體驗,css3新屬性可以改變精靈圖顏色,但是比較麻煩,并且新屬性有兼容問題。現在一般都是用web字體(圖標字體)來代替精靈圖。
2.什么是vue全家桶
Vue + vue-router + vuex + axios + es6 + sass
3.doctype是什么,網頁常見doctype及特點
DOCTYPE是document type(文檔類型)的簡寫,在web設計中用來說明你用的XHTML或者HTML是什么版本。
常見類型:
1.過渡型(Transitional):要求非常寬松,它允許你繼續使用HTML4.01的標識(但是要符合xhtml的寫法),完整代碼如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2.嚴格型(Strict):要求非常嚴格,你不能使用任何表現層的標識和屬性,例如<br>,完整代碼如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3.框架型(Frameset):專門針對框架頁面設計使用,如果你的頁面中包含有框架(frameset),完整代碼如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
3.什么是web語義化,有什么好處
Web語義化簡單來說就是為了讓頁面對人和機器更友好,讓人和機器更容易理解頁面內容。
1.對機器來說,語義化能讓機器更精確的知道頁面中的重點和關鍵點。讓機器更容易為人篩選出想要的部分。
2.對開發人員來說,更容開發和易維護頁面。根據頁面中的標簽名和類名就能知道哪個部分放置了哪些內容,從而提高了開發和維護的效率。
4.你知道的HTTP 請求方式有幾種
HTTPRequestMethod共計17種
1.GET 請求指定的頁面信息,并返回實體主體。
2.HEAD 類似于get請求,只不過返回的響應中沒有具體的內容,用于獲取報頭
3.POST 向指定資源提交數據進行處理請求(例如提交表單或者上傳文件)。數據被包含在請求體中。POST請求可能會導致新的資源的建立和/或已有資源的修改。
4.PUT 從客戶端向服務器傳送的數據取代指定的文檔的內容。
5.DELETE 請求服務器刪除指定的頁面。
6.CONNECT HTTP/1.1協議中預留給能夠將連接改為管道方式的代理服務器。
7.OPTIONS 允許客戶端查看服務器的性能。
8.TRACE 回顯服務器收到的請求,主要用于測試或診斷。
9.PATCH 實體中包含一個表,表中說明與該URI所表示的原內容的區別。
10.MOVE 請求服務器將指定的頁面移至另一個網絡地址。
11.COPY 請求服務器將指定的頁面拷貝至另一個網絡地址。
12.LINK 請求服務器建立鏈接關系。
13.UNLINK 斷開鏈接關系。
14.WRAPPED 允許客戶端發送經過封裝的請求。
15.LOCK 允許用戶鎖定資源,比如可以再編輯某個資源時將其鎖定,以防別人同時對其進行編輯。
16.MKCOL 允許用戶創建資源
17.Extension-mothed 在不改動協議的前提下,可增加另外的方法。
5.css選擇器有哪些
1.簡單選擇器
通配符選擇器 *
id選擇器 #id
class選擇器 .class
標簽選擇器 element
2.復合選擇器
后代選擇器 element element
子代選擇器 element>element
兄弟選擇器 element+element
并列選擇器 element,element
偽類選擇器 :link
屬性選擇器 [attribute]
6.css hack原理及常見hack
原理:CSS hack是一種類似作弊的手段,以欺騙瀏覽器的方式達到兼容的目的,是用瀏覽器的兼容性差異來解決瀏覽器的兼容性問題。
常見hack:
1.利用瀏覽器對相同代碼的解析和支持的不同實現的hack
比如div{ _width:80px },在ie6中能識別并解析帶下劃線的屬性,但是ie7及以上版本中識別不了。
2.以Firefox或Webkit特有的擴展樣式實現的hack
如Firefox支持以-moz-開頭的屬性
Webkit內核支持以-webkit-開頭的屬性
3.以IE特有的條件注釋為基礎的hack
<!--[ifIE8]> <style type="text/css"> #test{ color:red; } </style><![endif]-->
比如這個樣式,可以在ie8中生效,但是其他瀏覽器則不會生效
7.css中有哪些常見的繼承屬性
文本
color(顏色,a元素除外)
direction(方向)
font(字體)
font-family(字體系列)
font-size(字體大小)
font-style(用于設置斜體)
font-variant(用于設置小型大寫字母)
font-weight(用于設置粗體)
letter-spacing(字母間距)
line-height(行高)
text-align(用于設置對齊方式)
text-indent(用于設置首航縮進)
text-transform(用于修改大小寫)
visibility(可見性)
white-space(用于指定如何處理空格)
word-spacing(字間距)
列表
list-style(列表樣式)
list-style-image(用于為列表指定定制的標記)
list-style-position(用于確定列表標記的位置)
list-style-type(用于設置列表的標記)
表格
border-collapse(用于控制表格相鄰單元格的邊框是否合并為單一邊框)
border-spacing(用于指定表格邊框之間的空隙大小)
caption-side(用于設置表格標題的位置)
empty-cells(用于設置是否顯示表格中的空單元格)
頁面設置(對于印刷物)
orphans(用于設置當元素內部發生分頁時在頁面底部需要保留的最少行數)
page-break-inside(用于設置元素內部的分頁方式)
widows(用于設置當元素內部發生分也是在頁面頂部需要保留的最少行數)
其他
cursor(鼠標指針)
quotes(用于指定引號樣式)
8.sessionStorage,localStorage,cookie區別
·共同點:都是保存在瀏覽器端,且同源的。
·區別:cookie數據始終在同源的http請求中攜帶(即使不需要),即cookie在瀏覽器和服務器間來回傳遞;cookie數據還有路徑(path)的概念,可以限制cookie只屬于某個路徑下。存儲大小限制也不同,cookie數據不能超過4k,同時因為每次http請求都會攜帶cookie,所以cookie只適合保存很小的數據,如會話標識。
·而sessionStorage和localStorage不會自動把數據發給服務器,僅在本地保存。sessionStorage和localStorage 雖然也有存儲大小的限制,但比cookie大得多,可以達到5M或更大。
·數據有效期不同,sessionStorage:僅在當前瀏覽器窗口關閉前有效,自然也就不可能持久保持;localStorage:始終有效,窗口或瀏覽器關閉也一直保存,因此用作持久數據;cookie只在設置的cookie過期時間之前一直有效,即使窗口或瀏覽器關閉。
·作用域不同,sessionStorage不在不同的瀏覽器窗口中共享,即使是同一個頁面;localStorage 在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的。WebStorage 支持事件通知機制,可以將數據更新的通知發送給監聽者。WebStorage的 api 接口使用更方便。
9.JavaScript有哪些數據類型
原始類型有6種 object,number,string,boolean,null,undefined
10.輸出今天是星期幾
var str = "今天是星期" + "日一二三四五六".charAt(new Date().getDay());alert(str);
11.如何判斷一個變量是否為數組
arr.constructor === Array 為true說明是數組類型
arr instanceof Array 為true則是數組類型
Object.prototype.toString.call(arr) === '[object Array]'; 為true為數組類型
Array.isArray(arr) 為true則為數組類型
12.實現一個js深度克隆函數
//深度克隆
function deepClone(obj){
var result={},oClass=isClass(obj);
for(key in obj){
var copy=obj[key];
if(isClass(copy)=="Object"){
result[key]=arguments.callee(copy);
}else if(isClass(copy)=="Array"){
result[key]=arguments.callee(copy);
}else{
result[key]=obj[key];
}
}
return result;
}
function isClass(o){
if(o===null) return "Null";
if(o===undefined) return "Undefined";
return Object.prototype.toString.call(o).slice(8,-1);
}
//克隆一個數組
var arr=["a","b","c"];
var oNew=deepClone(arr);
console.log(oNew);//Object {0: "a", 1: "b", 2: "c"}
13.給定一個日期,頁面打印倒計時
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>倒計時</title>
</head>
<body>
<input type="text" name="time" id="time" value="2017-09-22" />
<input type="button" name="okbtn" id="okbtn" value="確認" />
<br />
<p id="textp">這里顯示倒計時</p>
</body>
<script type="text/javascript">
var okbtn=document.getElementById("okbtn");
textp=document.getElementById("textp");
okbtn.onclick=function(){
var time=document.getElementById("time");
var timevalue=time.value;
//通過正則表達式確認輸入格式是否正確
var patt=/^(\d{1,4})(-)(\d{1,2})(\d{1,2})$/;
if(patt.test(timevalue)==false){
//如果不正確
textp.innerHTML="輸入格式不滿足YYYY-MM-DD";
return false;
}else{
textp.innerHTML="這里顯示倒計時";
}
//獲取輸入的年月日
var timearray=timevalue.split("-");
//ShowLeftTime(timearray[0],timearray[1],timearray[2]);
setInterval(function(){ShowLeftTime(timearray[0],timearray[1],timearray[2]);},1000);
}
function ShowLeftTime(year,month,date){
//得出剩余時間
var now=new Date();
var endDate=new Date(year,month-1,date);
var leftTime=endDate.getTime()-now.getTime();
var leftsecond=parseInt(leftTime/1000);
var day=Math.floor(leftsecond/(60*60*24));
var hour=Math.floor((leftsecond-day*24*60*60)/3600);
var minute=Math.floor((leftsecond-day*24*60*60-hour*3600)/60);
var second=Math.floor(leftsecond-day*60*60*24-hour*60*60-minute*60);
//顯示剩余時間
textp.innerHTML="距離"+year+"年"+month+"月"+date+"日"
+"還有"+day+"天"+hour+"小時"+minute+"分"+second+"秒";
}
</script>
</html>
14.數組去重
//利用indexOf
var aa=[1,3,5,4,3,3,1,4]
function arr(arr) {
var result=[]
for(var i=0; i<arr.length; i++){
if(result.indexOf(arr[i])==-1){
result.push(arr[i])
}
}
console.log(result)
}
arr(aa)
//循環嵌套
function fn(arr) {
var result = [];
var flag;
for (var i = 0, len = arr.length; i < len; i++) {
flag = false;
for (var j = 0, len = result.length; j < len; j++) {
if (arr[i] == result[j]) {
flag = true;
break;
}
}
if (!flag) {
result.push(arr[i]);
}
}
return result;
}
15.求數組中最大值,最小值和重復次數最多的數值
var arr = [1,2,2,3,5,5,5,6];
var max = arr[0]; // 數組中的最大值
var min = arr[0]; // 數組中的最小值
var mostCount; // 數組中出現次數最多的元素
var temp = {};
var num = 0;
for(var i=arr.length-1; i>=0; i--){
if(max<arr[i]){ // 得到最大值
max = arr[i]
}
if(min>arr[i]){ // 得到最小值
min = arr[i]
}
if(temp[arr[i]]){ // 得到元素出現的次數,并組成obj
temp[arr[i]] = tempObj[arr[i]]+1;
}else{
temp[arr[i]] = 1;
}
}
for(var key in temp){ // 從對象中得到數組中出現最多的元素
if(!mostCount){
mostCount = key;
}else if(temp[mostCount]<temp[key]){
mostCount = key;
}
}
console.log("最大值為"+max+"; 最小值為"+minVal+"; 次數最多的為"+mostCount);
17.請概括什么情況下打印控制臺會提示undefined
1.當打印的變量聲明未賦值時
2.當打印的執行函數沒有返回值時
18.原生實現數組快速排序
var times=0;
var quickSort=function(arr){
//如果數組長度小于等于1無需判斷直接返回即可
if(arr.length<=1){
return arr;
}
var midIndex=Math.floor(arr.length/2);//取基準點
var midIndexVal=arr.splice(midIndex,1);//取基準點的值,splice(index,1)函數可以返回數組中被刪除的那個數arr[index+1]
var left=[];//存放比基準點小的數組
var right=[];//存放比基準點大的數組
//遍歷數組,進行判斷分配
for(var i=0;i<arr.length;i++){
if(arr[i]<midIndexVal){
left.push(arr[i]);//比基準點小的放在左邊數組
}
else{
right.push(arr[i]);//比基準點大的放在右邊數組
}
console.log("第"+(++times)+"次排序后:"+arr);
}
//遞歸執行以上操作,對左右兩個數組進行操作,直到數組長度為<=1;
return quickSort(left).concat(midIndexVal,quickSort(right));
};
console.log(quickSort(arr));
19.原生實現二分查找法
var arr = [5,0,-56,90,12];
var flag = false;//標志位進行優化,數組本來就是有序序列的話,無需再排序
//先進行大的排序
for(var i=0;i<arr.length-1;i++){
//小的排序
for(var j=0;j<arr.length-1-i;j++){
//比較
if(arr[j]>arr[j+1]){
//交換
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
flag = true;
}
}
//此部分為優化,已排序的話,無需再次排序
if(flag){
flag=false;
}else{
break;//已排序,無需交換
}
}
//輸出新數組
for(var i=0;i<arr.length;i++){
document.write(arr[i]+' ');
}
20.正則表達式,清楚字符串前后空格
var str=" hello ";
str=str.replace(/^s*|s*$/g,'');
alert(str);
21.簡述http協議中get和post方法的區別
1、 GET主要用于從服務器查詢數據,POST用于向服務器提交數據
2、 GET通過URL傳遞數據,POST通過http請求體傳遞數據
3、 GET傳輸數據量有限制,不能大于2kb,POST傳遞的數據量較大,一般大量的數據提交都是通過POST方式
4、 GET安全性較低,容易在URL中暴漏數據,POST安全性較高
22.什么是csrf攻擊,如何阻止
CSRF(Cross-site request forgery),中文名稱:跨站請求偽造,也被稱為:one click attack/session riding,縮寫為:CSRF/XSRF。
從上圖可以看出,要完成一次CSRF攻擊,受害者必須依次完成兩個步驟:
1.登錄受信任網站A,并在本地生成Cookie。
2.在不登出A的情況下,訪問危險網站B。
防止方式
(1).Cookie Hashing(所有表單都包含同一個偽隨機值)
(2).驗證碼
(3).One-Time Tokens(不同的表單包含一個不同的偽隨機值)
23.服務器推送數據到前端有哪些解決方案
一、Ajax輪詢
用定時器不斷發送請求
優點:實現簡單。
缺點:這是通過模擬服務器發起的通信,不是實時通信,不顧及應用的狀態改變而盲目檢查更新,導致服務器資源的浪費,且會加重網絡負載,拖累服務器。
二、comet
基于 HTTP 長連接的 "服務器推" 技術,能使服務器端主動以異步的方式向客戶端程序推送數據,而不需要客戶端顯式的發出請求,目前有兩種實現方式:
1. 基于 AJAX 的長輪詢(long-polling)方式
優點
客戶端很容易實現良好的錯誤處理系統和超時管理,實現成本與Ajax輪詢的方式類似。
缺點
需要服務器端有特殊的功能來臨時掛起連接。當客戶端發起的連接較多時,服務器端會長期保持多個連接,具有一定的風險。
2. 基于 Iframe 及 htmlfile 的流(streaming)方式
Comet的優缺點
優點: 實時性好(消息延時小);性能好(能支持大量用戶)
缺點: 長期占用連接,喪失了無狀態高并發的特點。
三、websocket
WebSocket是HTML5開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議。WebSocket通訊協議于2011年被IETF定為標準RFC 6455,WebSocketAPI被W3C定為標準。在WebSocket API中,瀏覽器和服務器只需要做一個握手的動作,然后,瀏覽器和服務器之間就形成了一條快速通道。兩者之間就直接可以數據互相傳送。
24.h5c3有哪些新增特性
h5新增的標簽
新增元素 | 說明 |
video | 表示一段視頻并提供播放的用戶界面 |
audio | 表示音頻 |
canvas | 表示位圖區域 |
source | 為video和audio提供數據源 |
track | 為video和audio指定字母 |
svg | 定義矢量圖 |
code | 代碼段 |
figure | 和文檔有關的圖例 |
figcaption | 圖例的說明 |
main | |
time | 日期和時間值 |
mark | 高亮的引用文字 |
datalist | 提供給其他控件的預定義選項 |
keygen | 秘鑰對生成器控件 |
output | 計算值 |
progress | 進度條 |
menu | 菜單 |
embed | 嵌入的外部資源 |
menuitem | 用戶可點擊的菜單項 |
menu | 菜單 |
template | 模板 |
section | 區塊 |
nav | 導航 |
aside | 側邊欄 |
article | 文章 |
footer | 底部 |
header | 頭部 |
- css3
css3被劃分為模塊,最重要的幾個模塊包括:選擇器、框模型、背景和邊框、文本效果、2D/3D 轉換、動畫、多列布局、用戶界面
選擇器
框模型
背景和邊框
border-radius、box-shadow、border-image、
background-size:規定背景圖片的尺寸
background-origin:規定背景圖片的定位區域
background-clip:規定背景的繪制區域
文本效果(常用)
text-shadow:設置文字陰影
word-wrap:強制換行
word-break
css3提出@font-face規則,規則中定義了font-family、font-weight、font-style、font-stretch、src、unicode-range
2/3D轉換
transform:向元素應用2/3D轉換
transition:過渡
動畫
@keyframes規則:
animation、animation-name、animation-duration等
用戶界面(常用)
box-sizing、resize
css3新增偽類
:nth-child()
:nth-last-child()
:only-child
:last-child
:nth-of-type()
:only-of-type()
:empty
:target 這個偽類允許我們選擇基于URL的元素,如果這個元素有一個識別器(比如跟著一個#),那么:target會對使用這個ID識別器的元素增加樣式。
:enabled
:disabled
:checked
:not
25.正則驗證郵箱
由于郵箱的基本格式為“名稱@域名”,需要使用“^”匹配郵箱的開始部分,用“$”匹配郵箱結束部分以保證郵箱前后不能有其他字符,所以最終郵箱的正則表達式為
^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$
26.標準模式與怪異模式下盒子模型的計算方式
兩種模式的區別:
標準模式會被設置的padding撐開,而怪異模式則相當于將盒子的大小固定好,再將內容裝入盒子。盒子的大小并不會被padding所撐開。
標準模式:盒子總寬度/高度 = 設置寬度/高度+padding+border。
怪異模式:盒子總寬度/高度= 內容寬度/高度 + padding + border + margin;
27.你用到了es6中哪些新特性
默認參數
模版表達式
箭頭函數
Promise
塊級作用域的let和const
模塊化
28.描述一個閉包
function A(){
var x = 1;
return function(){
return ++x;
}
}
1.存在一個函數A
2.在函數A內部返回一個函數
3.返回的函數引用A函數的私有變量
4.這個返回的函數是A函數的閉包函數
29.一個箭頭函數,如何獲取傳入的所有實參
用無限參數
var fn = (…args)=>{
console.log(args);
}
這樣就可以打印傳入的所有參數
注意:在箭頭函數中不能使用arguments
30.通訊協議知道哪些?講講websocket協議。
http、https、websocket、tcp/ip
webSocket是H5的新協議,它先通過http請求的tcp層3次握手建立連接,然后通過請求帶的update:webSocket信息將http協議轉換成webSocket協議,再然后就可以服務端向客戶端推送信息了。Websocket建立的是長連接,它是雙工通信,允許服務器端主動推送信息到客戶端。http建立的是短連接,無狀態單工通信。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。