1.延時加載JS有哪些方式
延時加載 :async defer
例如:<script defer type="type/javascript" src='script.js'></ script>
defer:等html全部解析完成,才會執行js代碼,順次執行的
async: js和html解析是同步的,不是順次執行js腳本(誰先加載完先執行誰)
2.JS數據類型有哪些
基本類型:string,number,boolean,undefined,null,symbol,bigint
引用類型:object
NaN是一個數值類型,但不是一個具體的數字null和undefined的區別
null會被隱式轉換為0,很不容易發現錯誤
為了彌補null的坑所以出現了unfefined
null是bject類型,undefined是undefined類型
undefined表示變量未初始化或屬性不存在
null 表示明確的無或空值==和===的區別
==比較的是值
===除了比較值還比較類型
3.JS微任務和宏任務
JS是單線程的 ,同一時間只能執行一個任務
JS代碼執行流程:同步執行完 ==》事件循環
事件循環 【微任務,宏任務】微任務:promise.then宏任務:setTimeout..要執行宏任務的前提是清空了所有的微任務
同步的任務都執行完了,才會執行事件循環的內容
進入事件循環:請求,定時器,事件...總體流程:
同步 ==》 事件循環 【微任務和宏任務】 ==》 微任務 ==》 宏任務
4.JS作用域
除了函數外,JS是沒有塊級作用域的
作用域鏈:內部可以訪問外部的變量,但是外部不能訪問內部的變量注意:如果內部有,優先查找到內部,如果內部沒有就查找外部的,一層一層往外找。var a =b =10 ==> var a= window.b = 10前面沒有類型 默認是window
JS有變量提升機制(變量懸掛聲明)
聲明變量的優先級是大于聲明普通函數的------
console.log(str) ? undefined
var str ="你好"
--------------
var name = 'a'
(function(){
if(typeof name =='undefined'){var name = 'b'console.log('111'+name) --> √
}else{console.log('222'+name)}
})
? 111b 因為內部已經有了name
--------------
console.log(c) ==>undefined (變量提升)
if(false){var c= 10
}
console.log(c) ==>undefined (變量提升)
--------------
var bar=1
function test(){
console.log(bar) ? undefined
var bar = 2;
console.log(bar) ==>2
}
-------
5.JS對象考題
對象是通過new操作符構建出來的,所以對象之間不相等 (除了引用外)
[1,2,3] === [1,2,3] ==>false
對象的key都是字符串類型var a ={}
var b =
key :'aa'
}
var c = {
key:'c'
}
a[b]='123' =>給a添加了 [Object Object]:123
a[c]='456' =>重新賦值 a.[Object Object] =456
console.log(a[b]) =>456
對象如何查找屬性
查找規則: 先在對象本身 ==》構造函數 ==》對象原型 ==》構造函數原型找 ==》對象上一層原型每個函數都自帶一個prototype【原型】對象擁有 __proto__
new Fun 該Fun構造函數的原型指向于(new Fun)的原型new的函數 this執行new
否則指向window
6.判斷是不是數組有哪些方法
1.isArrayvar arr = [1,2,3];console.log(Array.isArray(arr)) true2.instanceofvar arr = [1,2,3]console.log(arr instanceof Array) true3.通過原型var arr = [1,2,3]console.log(Object.protorype.toString.call(arr).indexOf('Array')!==-1)4.isProtorypeOf()console.log(Array.prototype.isPrototypeOf(arr))5.construct console.log(arr.constructor.toString().indexOf('Array'))
9.關于slice 和 splice
1.slice是用來截取的參數可以寫slice(3),slice(1,3),slice(-3)返回的是一個新的數組
2.splice功能:插入,刪除,替換會改變原數組splice(從哪開始,刪幾個元素,'插入的元素')
let removed = arr.splice(2,2) //從索引2開始,刪除2個元素
arr.splice(2,0,"apple","orange") 從索引2開始添加兩個元素
arr.splice(2,2,"apple","orange")從索引2開始替換兩個元素
10.關于數組去重
方式一:new set
var arr1 = [1,2,3,1,2,3]
function unique(arr){return [...new Set(arr)]
}
console.log(unique(arr1))
方式二:indexOf
var arr2 = [1,2,3,1,2,3]
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
}
11.new操作符具體做了什么
1.創建一個空的對象
2.將空對象的原型,指向于構造函數的原型
3.將空對象作為構造的上下文(改變this指向)
4.對構造函數有返回值的處理判斷(如果返回的是基本類型 則忽略 如果是引用類型則返回)
function Fun(age,name){this.age=age;this.name=name;
}
function create(fn,...args){
//創建一個空對象
var obj = {};
//將對象的原型指向構造函數的原型
Object.setProtorypeOf(obj,fn.prototype)
//將空對象作為構造函數的上下文
var result = fn.apply(obj,args)
return result instanceof Object >result:obj
}
console.log(create(Fun,18,'張三'))
12.關于閉包
1.閉包是什么
閉包是一個函數加上到創建函數的作用域的鏈接,閉包 關閉了 函數的自由變量
2.閉包可以解決什么問題內部函數可以訪問到外部函數的局部變量閉包可以解決的問題var lis = document.getElementsByTagName('li')for(vat i = 0;i<lis.length;i++){(function(i){lis[i].onclick = function(){alert(i)}})(i)}
閉包的缺點變量會駐留在內存中,造成內存損耗的問題解決:把閉包的函數設置為空內存泄漏(ie)
13.原型鏈
原型可以解決什么問題: 對象共享屬性和方法
誰有原型:
函數擁有:prototype
對象擁有:__proto__
對象查找屬性或方法的順序
現在對象本身查找->構造函數中查找->對象的原型->構造函數的原型
14.JS的繼承有哪些方式
方式一: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)
方式三:借用構造函數繼承
function Parent(){
this.age = 12
}
function Child(){
this.name = '張三'
Parent.call(this)
}
let o1 = new Child()
console.log(o1,o1.name,o1,age)
15.clal apply bind的區別
可以改變指向
語法:函數.call , 函數.apply ,函數.bind
區別:call apply可以立即執行,bind不會立即執行,因為bind返回的是一個函數需要加()執行
后面的參數是傳遞的參數
apply第二個參數是數組,call和bind有多個參數需要挨個寫
16.深拷貝和淺拷貝
淺拷貝:只復制應用 不復制值 地址是一樣的
深拷貝:是復制真正的值 兩個地址 遞歸
function copyObj (obj){
if(Array.isArray(obj)){
var newObj = []
}
var newObj = {}
for(var key in obj){
if(typeof obj[key] ==='object'){
newObj[key]=copyObj(obj[key])
}else{
newObj[key]=obj[key]
}}
return newObj
}
17.localStorage sessionStorage cookie的區別
sessionStorage.setItem('key','123') :僅在當前瀏覽器窗口關閉
之前有效 【關閉了瀏覽器之后就沒了】localStorage.setItem('key','123'): 始終有效 窗口或者瀏覽器
關閉也有效,所以叫持久化存儲cookie:
var data = new Data()
vat time = 3600*60*60*24
time =data.getTIme() +time
data.setTime(time)
documment.cookie = 'key=789;expires = ' +data.toUTSCtring()+'' //設置過期時間存儲大小限制:cookie 不能超過4K
localStorage,sessionStorage不能超過5M