javascript
作為junior developer,僅僅以為這些題目經常在我口試的時刻被問到,好記性不如爛筆頭,本身整頓紀錄一遍~~~
1.javascript怎樣完成繼續?
三種體式格局:
1. 原型繼續
// 長處:既繼續了父類的模板,又繼續了父類的原型對象
// 瑕玷:父類實例化傳參,而不是子類實例化傳參(不符合通例言語的寫法)
function Parent(work, drink) {
this.work = function() {
console.log(work);
}
this.drink = drink;
}
Parent.prototype.draw = function() {
alert("I can draw");
}
function Child() {
this.cry = function() {
console.log("the best ability is to cry");
}
}
Child.prototype = new Parent('code', 'beer');
var xiaoLi = new Child();
xiaoLi.work(); // code
xiaoLi.draw(); // I can draw
xiaoLi.cry(); // the best ability is to cry
關於原型鏈的詮釋:https://www.cnblogs.com/chengzp/p/prototype.html
2. 類繼續(借用組織函數的體式格局繼續)
// 長處:繼續了父類的模板,輕易經由歷程子類實例化傳參
// 瑕玷:不能繼續父類的原型對象
function Parent(work, drink) {
this.work = function() {
console.log(work);
}
this.drink = drink;
}
Parent.prototype.draw = function() {
alert("I can draw");
}
function Child(work, drink, sex) {
Parent.call(this, work, drink);
this.sex = sex;
}
var xiaoLi = new Child('code', 'beer', 'male');
alert(xiaoLi.drink); // code
xiaoLi.work(); // beer
// xiaoLi.draw(); //沒有繼續父類的原型對象,所以,會報錯:xiaoLi.draw() is not a function
console.log(xiaoLi.sex); // male
3. 夾雜繼續(原型繼續和類繼續)
// 夾雜繼續(原型繼續和類繼續(借用組織函數的體式格局繼續))
function Parent(eat, sleep) {
this.eat = function() {
console.log("function 1" + eat);
}
this.sleep = function() {
console.log("function 2" + sleep);
}
}
Parent.prototype.other = "work";
function Child(eat, sleep, age) {
Parent.call(this, eat, sleep);
this.age = age;
}
Child.prototype = new Parent();
var xiaoLi = new Child("cake", "want to sleep", "10");
xiaoLi.eat();
xiaoLi.sleep();
console.log(xiaoLi.age);
console.log(xiaoLi.other);
2.原生ajax是怎樣完成的?
特徵:
在不從新加載全部網頁的情況下,對頁面部分舉行革新。
XMLHttpRequest對象是完成ajax的基本,XMLHttpRequest有許多要領,經常運用的有open(),send()等
ajax請求共包括五個步驟:
1.建立XMLHttpRequest對象(一個異步挪用對象)
2.設置HTTP請求的參數(請求要領,url,是不是異步)
3.設置響應HTTP請求狀況變化的回調函數
4.發送HTTP請求
5.獵取異步挪用返回的數據
6.部分更新頁面
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && (xhr.status == 200 || xhr.status == 304)) {
fn.call(this, xhr.responseText);
}
};
xhr.send(data);
post要領肯定要用setRequestHeader("header","value");
3.作用域
塊級作用域:ES6才支撐,在{}大括號內的就是塊級作用域
(塊級作用域的湧現處置懲罰了:for輪迴定義的變量形成的全局污染;不必再經由歷程閉包來保留必要的變量了)
函數作用域:在函數中完成的
全局作用域:在外部聲明的,假如沒有用var關鍵字聲明,在非嚴厲情勢下,也為全局作用域
注重:
在es6之前沒有塊級作用域這個觀點,所以在{}塊級作用域中聲明的變量實在就是全局變量(舉個栗子)
for (var i = 1; i <= 10; i++) {
console.log (i); // outputs 1, 2, 3, 4, 5, 6, 7, 8, 9, 10;
};
// The variable i is a global variable and it is accessible in the following function with the last value it was assigned above
function aNumber () {
console.log(i);
}
// The variable i in the aNumber function below is the global variable i that was changed in the for loop above. Its last value was 11, set just before the for loop exited:
aNumber (); // 11
關於es6的let和const:
let和const沒有變量聲明的提拔;
let和const不許可在雷同作用域內反覆聲明;
4.怎樣明白閉包?
比較經常運用的情形:
在A函數里返回B函數,B函數能夠挪用A函數的部分變量;
特徵:
1.函數嵌套
2.函數內部能夠援用外部的參數和變量
3.閉包函數里的參數和變量不會被渣滓接納機制接納(閉包會使變量一直保留在內存中,假如運用不當會增大內存斲喪)
閉包的優點:
1.願望變量歷久保留在內存中
2.防止全局變量的污染
3.私有變量的存在
5.回調函數
定義:
函數A作為參數通報給函數B,在函數B中實行函數A,此時函數A就叫做回調函數。假如函數沒有名稱(函數表達式),就叫做匿名回調函數。
回調函數不肯定用於異步,同步(壅塞)場景下也會用到回調函數。比如說請求在實行完某些操縱后實行回調函數。
舉幾個栗子:
同步(壅塞)回調:
fn1實行完后實行fn2
在同步場景下,回調函數末了實行
異步回調:
ajax請求
在異步回調中,回調函數有可能不實行,因為時候沒有被觸發或許前提不滿足
回調函數的應用場景:
動態加載js后,圖片加載完成后,ajax請求等
別的,最好保證回調存在且必需是函數援用或許函數表達式:
(callback && typeof(callback) === "function") && callback();
6.es6經常運用新特徵:
1.let和const(新的變量聲明體式格局,許可把變量作用域控制在塊級內里)
2.解構賦值(對象和數組都實用)
3.promise
一個對象,用來示意並通報異步操縱的終究效果
交互體式格局:將回調函數傳入then要領獵取終究效果或失足緣由
以鏈式挪用替代回調函數層層嵌套
//天生promise實例
var promise = new Promise(function(resolve, reject) {
//...other code...
if (/* 異步操縱勝利 */){
resolve(value);//resolve函數將Promise對象的狀況從Pending變成Resolved
} else {
reject(error);//reject函數將Promise對象的狀況從Pending變成Rejected
}
});
//Promise實例天生今後,用then要領離別指定Resolved狀況和Reject狀況的回調函數。
promise.then(function(value) {
// success
}, function(err) {
// failure
});
jQuery.ajax()要領中應用promise:
var http = {
get: function(url) {
var promise = new Promise(function(resolve, reject) {
$.ajax({
url: url,
method: 'get',
success: function(data) {
resolve(data);
},
error: function(xhr, statusText) {
reject(statusText);
}
});
});
return promise;
}
};
http.get('data.php').then(function(data) {
document.write(data);
}, function(err) {
document.write(err);
});
這裡是獵取的data值:
/* data.php文件 */
<?php
echo '{"name":"Tom","age":"22"}';
4.箭頭函數(簡化函數的寫法、修復this的指向,箭頭函數里this指向要領本來的作用域,即要領綁定在哪一個對象上,this就指向哪一個對象)
5.多行字符串
6.類(要領名不再須要function關鍵字)
7.模板對象(${xxx})
8.默許參數(把默許值放在函數聲明裡)
9.iterable範例(Map):具有iterable範例的鳩合都能夠用for...of來輪迴遍歷
舉個栗子:
var m = new Map();
m.set("name", "lysa");//增加新的key-value;
Map對象對應許多的要領,如.set(),.has(),.delete()
10.modules(模塊):
舉個栗子:
在a.js中,
export var aa="test";
export function bb(){
do something;
}
在b.js中導入a.js的某個變量並援用:import {aa, bb} from 'a'
console.log(aa);
在b.js中導入a.js全部文件並援用:import * as xxx from 'a'
console.log(xxx.aa);
7.cookie和web storage的區分?
1.與服務器的交互上
cookie一直會在http同源請求頭上照顧(縱然不須要),在瀏覽器端和客戶端之間傳來傳去
localStorage和sessionStorage不會主動發送給服務器,僅保留在當地
2.貯存大小
cookie因為差別瀏覽器的限定,大小在4KB擺布
localStorage和sessionStorage貯存大小達5MB或以上
3.逾期時候
cookie與設置的有效期時候有關
localStorage存儲耐久數據,除非主動刪除
sessionStorage在瀏覽器封閉后自動刪除
8.cookie和session的區分?
cookie數據寄存在客戶的瀏覽器,session存儲在服務器上
考慮到安全性
發起:
將上岸等主要信息寄存為session
別的信息能夠放在cookie中
9.一個頁面從輸入url到頁面加載,這個歷程都發生了什麼?
簡約版:
1.瀏覽器依據請求的url向服務器發送請求
2.服務求處置懲罰完成后返回數據,瀏覽器吸收文件
3.瀏覽器對加載到的資本(html, css, js, image等)舉行語法剖析
4.載入剖析到的資本,襯着頁面
10.事宜委派
長處:削減事宜註冊;簡化DOM更新時,響應事宜的更新
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul id="lists"></ul>
</body>
<script>
var oUl=document.getElementById("lists");
var fragment=document.createDocumentFragment();
for(i=0;i<10;i++){
var oLi=document.createElement("li");
oLi.innerHTML="this is an item";
oLi.index=i;
fragment.appendChild(oLi);
}
oUl.appendChild(fragment);
// oUl.onclick=function(ev){
// console.log("ev是:",ev)
// var src=ev.target||ev.srcElement;
// if(src.tagName==="LI"){
// console.log(src.index)
// }
// }
oUl.addEventListener("click",function(ev){
var src=ev.target||ev.srcElement;
if(src.tagName==="LI"){
console.log(src.index);
}
},false)//默許false,事宜句柄在冒泡階段實行
</script>
</html>
11.拖拽
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<style>
body{margin:0;}
.box{width:100px;height: 100px;background: red;position: relative;cursor: move;}
</style>
</head>
<body>
<div class="box"></div>
<script>
var oBox=document.getElementsByClassName("box")[0];
oBox.onmousedown=function(ev){
// 鼠標按下的狀況
var ev=ev||window.event;//兼容ie瀏覽器
// 元素的x坐標和y坐標
var l_dis=oBox.offsetLeft;
var t_dis=oBox.offsetHeight;
// 1.紀錄下鼠標的x坐標和y坐標
// 2.盤算鼠標離元素邊距的間隔
var disX=ev.clientX-l_dis;
var disY=ev.clientY-t_dis;
var that=this;
// 鼠標挪動的狀況
document.documentElement.onmousemove=function(ev){
var ev=ev||window.event;
// 這裏的ev.pageX值是不是和ev.clientX值一致?
// 盤算元素如今的位置
let new_l_dis=ev.pageX-disX;
let new_t_dis=ev.pageY-disY;
// 最大可拖動的間隔
let max_l_dis=window.innerWidth-oBox.offsetWidth;
let max_t_dis=window.innerHeight-oBox.offsetHeight;
// 邊界題目
if(new_l_dis<0){
new_l_dis=0;
}
if(new_l_dis>max_l_dis){
new_l_dis=max_l_dis;
}
if(new_t_dis<0){
new_t_dis=0;
}
if(new_t_dis>max_t_dis){
new_t_dis=max_t_dis;
}
oBox.style.left=new_l_dis+"px";
that.style.top=new_t_dis+"px";
document.documentElement.onmouseup=function(){//鼠標抬起,不再挪動
this.onmousemove=null;
this.onmouseup=null;
}
}
}
</script>
</body>
</html>
12.DOM事宜
DOM事宜(3個級別):DOM0;DOM2;DOM3;
DOM0特徵:js與html強耦合;綁定的速度快,不須要操縱dom,可直接在元素上綁定
dom.onclick=function(){
do something;
}
DOM2特徵:能夠在一個元素中增加差別的事宜,事宜不會掩蓋;
dom.addEventListener("click",function(){},false)
DOM3特徵:在dom2的基本上,增加更多的事宜範例;可自定義事宜;
var event=new Event("test");
dom.addEventListener("test",function(){},false);
setTimeout(function(){
oBox.dispatchEvent(event);
},2000)
DOM事宜捕捉的詳細流程:
window->document->html->body->...->目的元素
事宜流:
捕捉->目的階段->冒泡
一個節點上註冊多個事宜:
處置懲罰響應優先級:event.stopImmediatePropagation();
13.javascript怎樣完成一個類,怎樣實例化這個類?
1.組織函數法
// 組織函數法(this + prototype)
// 用new關鍵字天生實例 對象
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.info = function() {
alert(this.name + this.age);
}
var xiaoLi = new Person("李佳", 26);
xiaoLi.info();
2.es6語法糖
// es6語法糖
// 用new關鍵字天生實例化對象
// 長處:防止了運用prototype
class Person {
constructor(x, y) {
this.x = x;
this.y = y;
}
info() {
alert(this.x + this.y);
}
}
var xiaoLi = new Person("李佳", 26);
xiaoLi.info();
14.詮釋作用域鏈
1.全局函數沒法檢察部分函數的細節,部分函數能夠接見全局函數的屬性
2.當前作用域沒有找到屬性或要領,能夠向上層以致全局尋覓,這類情勢就是作用域鏈
15. .call()和.apply()的區分?
.call()和.apply()是每一個函數都包括而非繼續來的要領,用於轉變函數的作用域
兩要領作用雷同
區分在吸收參數的體式格局差別,call()請求明白傳入每一個參數;
擴大作用域,舉個栗子:
window.color = "red";
var o = {color: "blue"};
function sayColor() {
alert(this.color);
}
sayColor(); // red
sayColor.call(this); // red
sayColor.call(window); //red
sayColor.call(o); // blue
15.jsonp的道理
應用script標籤能夠跨域接見的特徵,動態建立script標籤,給標籤設置src屬性。
經由歷程script標籤接見跨域的地點,返回一個參數為請求數據的callback的回調函數,而不再直接是json數據。
詳細完成步驟:
原生:
$(document).ready(function(){
var url = "http://www.practice-zhao.com/student.php?id=1&callback=jsonhandle";
var obj = $('<script><\/script>');
obj.attr("src",url);
$("body").append(obj);
});
jquery:
$(document).ready(function(){
$.ajax({
type : "get",
async: false,
url : "http://www.practice-zhao.com/student.php?id=1",
dataType: "jsonp",
jsonp:"callback", //請求php的參數名
jsonpCallback: "jsonhandle",//要實行的回調函數
success : function(data) {
alert("age:" + data.age + "name:" + data.name);
}
});
});
16.jquery鏈式挪用
道理:對象要領上末了加上return this;語句
長處:節約代碼,代碼看起來更文雅
17.原型和原型鏈
先記兩個乾巴巴的結論:
舉個栗子:
function Person(name, age, job) {
this.name = name;
this.age = age;
this.job = job;
this.sayName = function() { alert(this.name) }
}
var person1 = new Person('Zaxlct', 28, 'Software Engineer');
var person2 = new Person('Mick', 23, 'Doctor');
console.log(person1.constructor == Person); //true
console.log(person2.constructor == Person); //true
1.實例的組織函數屬性(constructor)指向組織函數。
var A = new Person();
Person.prototype = A;
2.原型對象(Person.prototype)是 組織函數(Person)的一個實例。