還有部分沒更新完...
var、let、const區(qū)別
1. var存在變量提升,而let、const沒有
2. let、const有塊級作用域,而var沒有
3. var 在同一塊作用域可以重復(fù)聲明多個相同的變量,后者覆蓋前者,let、const重
復(fù)聲明會報錯
4.let、var聲明變量后可以進(jìn)行改變值,const聲明不能修改([對象、數(shù)組]的屬性和方法可以改變
合并對象的方法可以寫幾種
const obj1 = {a:'a',b:'b',c:'c'};
const obj2 = {c:'c',d:'d',e:'e'};
方式一:使用ES6的拓展運(yùn)算符
{...obj1,...obj2}
方式二:Object.assign(obj1,obj2);
方式三:手寫遍歷
function assign(obj1,obj2){
for(let key in obj2){
obj1[key] = obj2[key];
}
return obj1;
}
assign(obj1,obj2);
find和filter的區(qū)別
1. find 條件符合就找到第一個符合的元素返回,否則返回 undefined
2. filter 如果條件符合 就返回一個新的數(shù)組(多個元素),否則返回空數(shù)組[]
some和every的區(qū)別
1. every()是對數(shù)組中每一項運(yùn)行給定函數(shù),如果該函數(shù)對每一項返回true,則返回true。 有點(diǎn)&&的意思
2. some()是對數(shù)組中每一項運(yùn)行給定函數(shù),如果該函數(shù)對任一項返回true,則返回true。有點(diǎn)||的意思
深拷貝和淺拷貝
箭頭函數(shù)和普通函數(shù)有什么區(qū)別
1. 箭頭函數(shù)不能用于構(gòu)造函數(shù),如果使用會報錯
2. 箭頭函數(shù)沒有 arguments對象、prototype 原型對象
3. 箭頭函數(shù)的this在定義時就已經(jīng)指定,而普通函數(shù)是調(diào)用時才指定,如果普通函數(shù)用于構(gòu)造函數(shù)this的指向就是當(dāng)前實例
Promise有幾種狀態(tài)
1. pending(初始狀態(tài))
pending的意思是“待定的,發(fā)生的”,相當(dāng)于是一個初始狀態(tài)。創(chuàng)建[Promise]對象時,且沒有調(diào)用resolve或者是reject方法,相當(dāng)于時初始狀態(tài)。這個初始狀態(tài)會隨著你調(diào)用resolve,或者是reject函數(shù)而切換到另一種狀態(tài)。
2 . resolved(成功態(tài))
resolved表示成功了。當(dāng)[Promise]實例對象中異步任務(wù)順利完成且返回結(jié)果值時,就調(diào)用了resolved這個參數(shù)
3. rejected(失敗狀態(tài))
rejected 失敗,當(dāng)[Promise]實例對象中異步任務(wù)執(zhí)行失敗時,就調(diào)用了resolved這個參數(shù)
localstorage、sessionstorage、cookie的區(qū)別
一、存儲的時間有效期不同
1、cookie的有效期是可以設(shè)置的,默認(rèn)的情況下是關(guān)閉瀏覽器后失效
2、sessionStorage的有效期是僅保持在當(dāng)前頁面,關(guān)閉當(dāng)前會話頁或者瀏覽器后就會失效
3、localStorage的有效期是在不進(jìn)行手動刪除的情況下是一直有效的
二、存儲的大小不同
1、cookie的存儲是4kb左右,存儲量較小,一般頁面最多存儲20條左右信息
2、localStorage和sessionStorage的存儲容量是5Mb(官方介紹,可能和瀏覽器有部分差異性)
三、與服務(wù)端的通信
1、cookie會參與到與服務(wù)端的通信中,一般會攜帶在http請求的頭部中,例如一些關(guān)鍵密匙驗證等。
2、localStorage和sessionStorage是單純的前端存儲,不參與與服務(wù)端的通信
JS數(shù)據(jù)類型有哪些
基本類型:String、Number、Boolean、Undefined、Null、Symbol、Bigint
引用類型:Object(Array、Function、Date、RegExp)
注意:typeof null 返回的是 'object'
NaN是一個Number類型,但是不是一個具體的數(shù)字
typeof NaN 返回的是 'number'
null和undefined的區(qū)別
1. 作者在設(shè)計js的都是先設(shè)計的null(為什么設(shè)計了null:最初設(shè)計js的時候借鑒了java的語言)
2. null會被隱式轉(zhuǎn)換成0,很不容易發(fā)現(xiàn)錯誤。
3. 先有null后有undefined,出來undefined是為了填補(bǔ)之前的坑。
具體區(qū)別:JavaScript的最初版本是這樣區(qū)分的:null是一個表示"無"的對象(空對象指針),轉(zhuǎn)為數(shù)值時為0;undefined是一個表示"無"的原始值,轉(zhuǎn)為數(shù)值時為NaN。
==和===有什么不同
== : 比較的是值
string == number || boolean || number ....都會隱式轉(zhuǎn)換
通過valueOf轉(zhuǎn)換(valueOf() 方法通常由 JavaScript 在后臺自動調(diào)用,并不顯式地出現(xiàn)在代碼中。)
=== : 除了比較值,還比較類型
JS微任務(wù)和宏任務(wù)
1. js是單線程的語言。
2. js代碼執(zhí)行流程:同步執(zhí)行完==>事件循環(huán)
同步的任務(wù)都執(zhí)行完了,才會執(zhí)行事件循環(huán)的內(nèi)容
進(jìn)入事件循環(huán):請求、定時器、事件....
3. 事件循環(huán)中包含:【微任務(wù)、宏任務(wù)】
微任務(wù):promise.then
宏任務(wù):setTimeout..
要執(zhí)行宏任務(wù)的前提是清空了所有的微任務(wù)
流程:同步 > 事件循環(huán)【微任務(wù)和宏任務(wù)】> 微任務(wù) > 宏任務(wù) > 微任務(wù)...
JS作用域
1. 除了函數(shù)外,js是沒有塊級作用域。
2. 作用域鏈:內(nèi)部可以訪問外部的變量,但是外部不能訪問內(nèi)部的變量。
注意:如果內(nèi)部有,優(yōu)先查找到內(nèi)部,如果內(nèi)部沒有就查找外部的。
3. 注意聲明變量是用var還是沒有寫(window.)
4. 注意:js有變量提升的機(jī)制【變量懸掛聲明】
5. 優(yōu)先級:聲明變量 > 聲明普通函數(shù) > 參數(shù) > 變量提升
JS判斷變量是不是數(shù)組,你能寫出哪些方法
1. isArray
2. Array.prototype.isPrototypeOf([])
3. Object.prototype.toString.call([]).indexOf('Array') > -1
4. [].constructor.toString().indexOf('Array') > -1
slice是干嘛的、splice是否會改變原數(shù)組
1. slice是來截取的
參數(shù)可以寫slice(3)、slice(1,3)、slice(-3)
返回的是一個新的數(shù)組
2. splice 功能有:插入、刪除、替換
返回:刪除的元素
該方法會改變原數(shù)組
JS數(shù)組去重
方式一:new set
const arr= [1,2,3,2,4,1];
function unique(arr){
return [...new Set(arr)]
}
方式二:Object的key是唯一
function unique(arr) {
const param = {};
arr.forEach(key => {
param[key] = key;
});
return Object.keys(param);
};
方式三:indexOf
function unique( arr ){
var brr = [];
for( var i=0;i<arr.length;i++){
if( brr.indexOf(arr[i]) == -1 ){
brr.push( arr[i] );
}
}
return brr;
}
方式四:sort
function unique( arr ){
arr = arr.sort();
var brr = [];
for(var i=0;i<arr.length;i++){
if( arr[i] !== arr[i-1]){
brr.push( arr[i] );
}
}
return brr;
}
找出多維數(shù)組最大值
function fnArr(arr){
var newArr = [];
arr.forEach((item,index)=>{
newArr.push( Math.max(...item) )
})
return newArr;
}
console.log(fnArr([
[4,5,1,3],
[13,27,18,26],
[32,35,37,39],
[1000,1001,857,1]
]));
給字符串新增方法實現(xiàn)功能
給字符串對象定義一個addPrefix函數(shù),當(dāng)傳入一個字符串str時,它會返回新的帶有指定前綴的字符串,例如: console.log( 'world'.addPrefix('hello') ) 控制臺會輸出helloworld
String.prototype.addPrefix = function(str){
return str + this;
}
console.log( 'world'.addPrefix('hello') )
找出字符串出現(xiàn)最多次數(shù)的字符以及次數(shù)
var str = 'aaabbbbbccddddddddddx';
var obj = {};
for(var i=0;i<str.length;i++){
var char = str.charAt(i);
if( obj[char] ){
obj[char]++;
}else{
obj[char] = 1;
}
}
console.log( obj );
//統(tǒng)計出來最大值
var max = 0;
for( var key in obj ){
if( max < obj[key] ){
max = obj[key];
}
}
//拿最大值去對比
for( var key in obj ){
if( obj[key] == max ){
console.log('最多的字符是'+key);
console.log('出現(xiàn)的次數(shù)是'+max);
}
}
new操作符具體做了什么
1. 創(chuàng)建了一個空的對象
2. 將空對象的原型,指向于構(gòu)造函數(shù)的原型
3. 將空對象作為構(gòu)造函數(shù)的上下文(改變this指向)
4. 對構(gòu)造函數(shù)有返回值的處理判斷
實現(xiàn)代碼如下 :
function Fun( age,name ){
this.age = age;
this.name = name;
}
function create( fn , ...args ){
var obj = {};
Object.setPrototypeOf(obj,fn.prototype);
var result = fn.apply(obj,args);
return result instanceof Object ? result : obj;
}
console.log( create(Fun,18,'張三') )
說一下call、apply、bind區(qū)別
1. 共同點(diǎn):功能一致,都是可以改變this指向
2. 語法: 函數(shù).call()、函數(shù).apply()、函數(shù).bind()
3. 區(qū)別一:參數(shù)不同,apply第二個參數(shù)是數(shù)組,call和bind有多個參數(shù)需要挨個寫
區(qū)別二:call、apply都是立即執(zhí)行 bind不會立即執(zhí)行,因為bind返回的是一個函數(shù)需要加入()執(zhí)行
場景:
1. 用apply的情況
var arr1 = [1,2,4,5,7,3,321];
console.log( Math.max.apply(null,arr1) )
2. 用bind的情況
var btn = document.getElementById('btn');
var h1s = document.getElementById('h1s');
btn.onclick = function(){
console.log( this.id );
}.bind(h1s)
閉包
1. 閉包是什么
閉包是一個函數(shù)加上到創(chuàng)建函數(shù)的作用域的連接,閉包“關(guān)閉”了函數(shù)的自由變量。
2. 閉包可以解決什么問題【閉包的優(yōu)點(diǎn)】
2.1 內(nèi)部函數(shù)可以訪問到外部函數(shù)的局部變量
2.2 閉包可以解決的問題
var lis = document.getElementsByTagName('li');
for(var i=0;i<lis.length;i++){
(function(i){
lis[i].onclick = function(){
alert(i);
}
})(i)
}
3. 閉包的缺點(diǎn)
3.1 變量會駐留在內(nèi)存中,造成內(nèi)存損耗問題。
解決:把閉包的函數(shù)設(shè)置為null
3.2 內(nèi)存泄漏【ie】 ==> 可說可不說,如果說一定要提到ie
原型鏈
1. 原型可以解決什么問題:解決了對象的共享屬性、方法
2. 誰有原型:函數(shù)擁有prototype、對象擁有__proto__
3. 對象查找屬性或者方法的順序
先在對象本身查找 > 構(gòu)造函數(shù)中查找 > 對象的原型 > 構(gòu)造函數(shù)的原型中 > 當(dāng)前原型的原型中查找
4. 原型鏈的最頂端是null
JS繼承有哪些方式
1. ES6 class 的extends
2. 原型鏈繼承
3. 借用構(gòu)造函數(shù)繼承
4. 組合式繼承(原型鏈繼承和借用構(gòu)造函數(shù)繼承)
方式一:ES6
class Parent{
constructor(){
this.age = 18;
}
}
class Child extends Parent{
constructor(){
super();
this.name = '張三';
}
}
let o1 = new Child();
console.log( o1,o1.name,o1.age );
方式二:原型鏈繼承
function Parent(){
this.age = 20;
}
function Child(){
this.name = '張三'
}
Child.prototype = new Parent();
let o2 = new Child();
console.log( o2,o2.name,o2.age );
方式三:借用構(gòu)造函數(shù)繼承
function Parent(){
this.age = 22;
}
function Child(){
this.name = '張三'
Parent.call(this);
}
let o3 = new Child();
console.log( o3,o3.name,o3.age );
方式四:組合式繼承
function Parent(){
this.age = 100;
}
function Child(){
Parent.call(this);
this.name = '張三'
}
Child.prototype = new Parent();
let o4 = new Child();
console.log( o4,o4.name,o4.age );
延遲加載JS有哪些方式
1. defer 是等html全部解析完成,才會執(zhí)行js代碼,順次執(zhí)行js腳本。
2. async 是和html解析同步的(并行的),不是順次執(zhí)行js腳本(誰先加載完誰先執(zhí)行)
3. 使用js動態(tài)創(chuàng)建<script type="text/javascript" src="xxx">標(biāo)簽