web前端常見二十道面試題
阿新 • • 發佈:2018-12-31
01 作用域
var num1 = 55;
var num2 = 66;
function f1(num, num1){
// var num = 55;
// var num1 = 66;
num = 100;
num1 = 100;
num2 = 100;
console.log(num) // 100
console.log(num1) // 100
console.log(num2) // 100
}
f1(num1, num2)
console.log(num1) // 100
console.log(num2) // 66
console.log(num) // 報錯 Uncaught ReferenceError: num is not defined
02 值型別和引用型別的傳遞
function Person(name,age,salary){
this.name = name;
this.age = age;
this.salary = salary;
}
function f1(person){
// var person = p
person.name = "ls"
person = new Person("aa", 23, 10)
}
var p = new Person("zs" , 18, 1000)
console.log(p.name) // zs
f1(p)
console.log(p.name) // ls
03 封裝函式進行字串駝峰命名的轉換
已知有字串foo = "get-lement-by-id"
,寫一個function將其轉化成駝峰命名錶示法"getElementById"
// 已知有字串foo = "get-lement-by-id",寫一個function將其轉化成駝峰命名錶示法"getElementById"
// var foo = "get-element-by-id";
function toUppercaseMessage(foo){
// 根據某個字串進行切割
var arr = foo.split('-');
// 獲取元素中的第一個字元並轉換成大寫
for(var i = 0 ; i < arr.length ; i++){
// arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substr(1, arr[i].length-1)
// arr[i] = arr[i][0].toUpperCase() + arr[i].substring(1, arr[i].length)
//arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substr(1)
arr[i] = arr[i].charAt(0).toUpperCase() + arr[i].substring(1)
}
// 根據某個字元將陣列轉換成字串
return arr.join('')
}
console.log(toUppercaseMessage("get-element-by-id"));
04 氣泡排序
var arr = [5,43,32,20,122];
// 輪數
for(var i = 0 ; i < arr.length ; 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
}
}
}
console.log(arr)
05 翻轉陣列
var arr =[0,1,2,3,4,5,6,7,8,9];
for(var i = 0 ; i < arr.length / 2 ; i++){
// arr[0] arr[arr.length-1-0]
// arr[1] arr[arr.length-1-1]
// arr[2] arr[arr.length-1-2]
// arr[3] arr[arr.length-1-3]
// 藉助第三方變數交換兩個變數的值
var temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
console.log(arr)
06 去掉陣列中重複的資料
/**
* 1. 建立一個新陣列,把原陣列中的第一個元素插入到新陣列中
* 2. 遍歷原陣列中的每一個元素分別和新陣列中的每一個元素進行比較
*/
// 原陣列
var arr =[0,1,2,3,3,5,6,9,8,9];
// 新陣列
var temp = [];
temp[0] = arr[0]
// arr中的每個元素
for(var i = 0 ; i < arr.length ; i++){
// t中的每個元素
for(var j = 0 ; j < temp.length ; j++){
// 當原陣列中的值和新陣列中的值相同的時候,就沒必要在進行比較了,跳出內迴圈。
if(temp[j] == arr[i]){
break;
}
// 拿原陣列中的某個元素比較到新陣列中的最後一個元素還沒有重複
if(j == temp.length-1){
// 將資料插入新陣列
temp.push(arr[i]);
}
}
}
console.log(temp)
07 1物理畫素的實現
物理畫素 和 css畫素的關係:畫素比 = 物理畫素 / css畫素
- 方法一
<style>
* {
margin: 0;
padding: 0;
}
#box {
width: 0.5rem;
height: 0.5rem;
border-bottom: 1px solid #000;
}
</style>
<meta name="viewport" content="width=1, user-scalable=no, initial-scale=1.0">
<div id="box"></div>
window.onload = function(){
// 畫素比
var dpr = window.devicePixelRatio;
// 縮放比例
var scale = 1 / dpr;
var width = document.documentElement.clientWidth;
// 獲取meta標籤
var metaNode = document.querySelector('meta[name="viewport"]');
metaNode.setAttribute('content','width=1, user-scalable=no, initial-scale='+ scale)
// 頁面中元素寬度、高度、比例反向乘回來
var htmlNode = document.querySelector('html');
htmlNode.style.fontSize = width * dpr + 'px';
}
- 方法二
* {
margin: 0;
padding: 0;
}
#box {
width: 200px;
height: 200px;
padding: relative;
}
#box::before {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background: #000;
}
@media screen and (-webkit-min-device-pixel-ratio: 2){
#box::before {
transform: scaleY(0.5)
}
}
@media screen and (-webkit-min-device-pixel-ratio: 3){
#box::before {
transform: scaleY(0.333333)
}
}
<meta name="viewport" content="width=1, user-scalable=no, initial-scale=1.0">
<div id="box"></div>
* {
margin: 0;
padding: 0;
}
#box {
width: 200px;
height: 200px;
padding: relative;
}
#box::before {
content: "";
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 1px;
background: #000;
}
@media screen and (-webkit-min-device-pixel-ratio: 2){
#box::before {
transform: scaleY(0.5)
}
}
@media screen and (-webkit-min-device-pixel-ratio: 3){
#box::before {
transform: scaleY(0.333333)
}
}
08 元素的水平垂直居中
* {
margin: 0;
padding: 0;
}
#wrap {
width: 500px;
height: 500px;
background: grey;
position: relative;
}
<div id="wrap">
<div class="box"></div>
</div>
- 方法一
#wrap .box {
width: 200px;
height: 200px;
background: pink;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
margin: auto;
}
- 方法二
#wrap .box {
width: 200px;
height: 200px;
background: pink;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
}
- 方法三
#wrap .box {
width: 200px;
height: 200px;
background: pink;
position: absolute;
left: 50%;
top: 50%;
margin-left: -100px;
margin-top: -100px;
}
- 方法四
#wrap {
width: 500px;
height: 500px;
background: grey;
display: flex;
justify-content: center;
align-items: center;
}
#wrap .box {
width: 200px;
height: 200px;
background: pink;
}
09 用純css建立一個三角形
#box {
width: 0px;
height: 0px;
border: 100px solid;
border-top-color: red;
border-right-color: transparent;
border-bottom-color: transparent;
border-left-color: transparent;
}
<div id="box"></div>
10 rem的適配
適配解決的問題是同一個元素在不同螢幕上呈現同樣的效果。
html根元素的字型大小設定為螢幕區域的寬
* {
margin: 0;
padding: 0;
}
#box {
width: 0.5rem;
height: 0.5rem;
background: red;
}
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<div id="box"></div>
window.onload = function(){
// 獲取螢幕區域的寬度
var width = document.documentElement.clientWidth;
// 獲取html
var htmlNode = document.querySelector('html');
// 設定字型大小
htmlNode.style.fontSize = width + 'px';
}
11 求背景圖片左邊到#box盒子左邊框外側的距離
* {
margin: 0;
padding: 0;
}
#box {
width: 400px;
height: 200px;
background: pink;
padding: 100px; # 100px
border: 100px solid blue; # 100px
background-image: url("bg.jpg"); # 預設是從content開始的,即背景圖覆蓋padding
background-repeat: no-repeat;
background-origin: content-box; # 設定讓從padding開始
background-position: -50px 0; # 向左便宜50
}
# 計算最終的值為 100 + 100 - 50 = 150px
<div id="box"></div>
12 js綜合面試題
/* function Foo(){
getName = function(){
alert(1);
return this;
}
}
Foo.getName = function(){
alert(2)
}
Foo.prototype.getName = function(){
alert(3)
}
var getName = function(){
alert(4)
}
function getName(){
alert(5)
}*/
// 變數提升後
function Foo(){
getName = function(){
alert(1);
return this;
}
}
// var getName;
function getName(){
alert(5)
}
/***************************************/
Foo.getName = function(){
alert(2)
}
Foo.prototype.getName = function(){
alert(3)
}
getName = function(){
alert(4)
}
// 請寫出下列的輸出結果 .運算子優先順序最高
Foo.getName(); // 2
getName(); // 4
// Foo().getName(); // (Foo()).getName() => window.getName() 1
getName(); // 1
new Foo.getName(); // new (Foo.getName)() ——> new (function(){alert(2)})() 2
new Foo().getName(); // (new Foo()).getName() ——> foo.getName() 3
new new Foo().getName(); // new ((new Foo()).getName)() ——> ——> new (function(){alert(3)})() 3
13 什麼是函式節流和函式防抖
-
函式節流:一個函式執行一次後,只有大於設定的執行週期才會執行第二次
-
有個需要頻繁觸發函式,處於優化效能角度,在規定時間內,只讓函式觸發的第一次生效,後面不生效
-
# 節流函式 @param fn 要被節流的函式 @param delay 規定的時間 function throttle(fn, delay){ // 記錄上一次函式觸發的時間 var lastTime = 0; return function (){ // 記錄當前函式觸發的時間 var nowTime = Date.now() ; if(nowTime - lastTime > delay){ // 修改this的指向問題 fn.call(this); fn() // 同步時間 lastTime = nowTime; } } } document.onscroll = throttle(function(){ console.log("scroll事件被觸發了"+Date.now()) }, 200)
-
-
防抖函式:一個需要頻繁觸發的函式,在規定的時間內,只讓最後一次生效,前面的不生效
-
function debounce(fn, delay){ // 記錄上一次的延時器 var timer = null; return function(){ // 清除上一次延時器 clearTimeouit(timer); // 重新設定新的延時器 timer = setTimeout(function(){ fn().apply(this); }, delay); } } document.getElementById('btn').onclick = debounce(function(){ console.log("防抖函式被觸發了" + Date.now()) },1000)
-
14 什麼是跨域 ?解決跨域的辦法有哪些?
- 同源策略
- 是瀏覽器安全策略
- 協議、域名、埠號必須完全一致
- 跨域
- 違背同源策略就會產生跨域
- 解決跨域
- jsonp cors 伺服器代理
// 建立script標籤
var script = document.createElement('script')
// 設定回撥函式
function getData(data){
// 資料請求回來會被觸發的函式
}
// 設定script的src屬性,設定請求地址
script.src = 'http://localhost:3000?callback=getData';
// 讓script生效
document.body.appendChild(script)
15 從一個url地址到最終頁面渲染完成,發生了什麼?
- DNS解析: 將域名地址解析為ip地址
- 瀏覽器DNS快取
- 系統DNS快取
- 路由器DNS快取
- 網路運營商DNS快取
- 遞迴搜尋:blog.baidu.com
- .com域名下查詢DNS解析
- .baidu
- blog
- 出錯
- TCP連線: TCP三次握手
- 第一次握手,由瀏覽器發起,告訴伺服器我要傳送請求了
- 第二次握手,由伺服器發起,告訴瀏覽器我準備接收了,你趕緊傳送吧
- 第三次握手,由瀏覽器傳送,告訴伺服器,我馬上就發了準備接受吧
- 傳送請求
- 請求報文:HTTP協議的通訊內容
- 接受響應
- 響應報文
- 渲染頁面
- 遇見HTML標記,瀏覽器呼叫HTML解析器解析成Token並構建成dom樹
- 遇見style/link標記,瀏覽器呼叫css解析器,處理css標記構建cssom樹
- 遇到script標記,呼叫javascript解析器,處理script程式碼(繫結事件、修改dom樹、cssom樹)
- 將dom樹和cssom樹 合併成一個渲染樹
- 根據渲染