JavaScript常問(wèn)面試題及答案總結(jié)大全
面試題:延遲加載JS有哪些方式?
https://www.growingwiththeweb.com/2014/02/async-vs-defer-attributes.html
?
延遲加載:async、defer
例如: <script defer type="text/javascript" src='script.js'></script>defer:等html全部解析完成,才會(huì)執(zhí)行js代碼,順次執(zhí)行js腳本。
async:async是和html解析同步的(一起的),不是順次執(zhí)行js腳本(誰(shuí)先加載完誰(shuí)先執(zhí)行)。
面試題:JS數(shù)據(jù)類(lèi)型有哪些?
基本類(lèi)型: string、number、boolean、undefined、null、symbol,bigint
引用類(lèi)型:object
?
NaN是一個(gè)數(shù)值類(lèi)型,但是不是一個(gè)具體的數(shù)字。
面試題:null和undefined的區(qū)別
1. 作者在設(shè)計(jì)js的都是先設(shè)計(jì)的nul1(為什么設(shè)計(jì)了null:最初設(shè)計(jì)js的時(shí)候借鑒了java的語(yǔ)言)
2. null會(huì)被隱式轉(zhuǎn)換成0,很不容易發(fā)現(xiàn)錯(cuò)誤。
3. 先有null后有undefined,出來(lái)undefined是為了填補(bǔ)之前的坑。
?
具體區(qū)別:JavaScript的最初版本是這樣區(qū)分的:null是一個(gè)表示"無(wú)"的對(duì)象(空對(duì)象指針),轉(zhuǎn)為數(shù)值時(shí)為0;undefined是一個(gè)表示”無(wú)”的原始值,轉(zhuǎn)為數(shù)值時(shí)為NaN。
面試題:JS數(shù)據(jù)類(lèi)型考題
<script type="text/javascript">
console.log( true + 1 ); // 2
console.log( 'name'+true ); //nametrue
console.log( undefined + 1 ); //NaN
console.log( typeof(undefined + 1 )); //number
console.log( typeof null ); //Object
//字符串和其他類(lèi)型相加,變成連接的形式
alert(typeof(NaN)); // number
alert(typeof(undefined)) // undefined
alert(typeot(null)) // Object
</script>面試題:==和===有什么不同
== :比較的是值
string == number || booleanll number ....都會(huì)隱式轉(zhuǎn)換
通過(guò)valueOf轉(zhuǎn)換(valueOf()方法通常由JavaScript在后臺(tái)自動(dòng)調(diào)用,并不顯示地出現(xiàn)在代碼中。)
=== :除了比較值,還比較類(lèi)型
console.log( 1 =='1' ); // true console.log( true == 1 ); // true console.log( null == undefined ); // true console.log( [1,2] == '1,2' ) // true
面試題:JS微任務(wù)和宏任務(wù)
1.js是單線程的語(yǔ)言。
2.js代碼執(zhí)行流程: 同步執(zhí)行完 ==》 事件循環(huán)
同步的任務(wù)都執(zhí)行完了,才會(huì)執(zhí)行事件循環(huán)的內(nèi)容
進(jìn)入事件循環(huán):請(qǐng)求、定時(shí)器、事件 ···
3. 事件循環(huán)中包含: 【微任務(wù)、宏任務(wù)】
微任務(wù):promise.then
宏任務(wù):setTimeout...要執(zhí)行宏任務(wù)的前提是清空了所有的微任務(wù)
流程:同步 ==》 事件循環(huán)【微任務(wù)和宏任務(wù)】 ==》 微任務(wù) ==》 宏任務(wù) ==》 微任務(wù)...
面試題:JS作用域考題
1. 除了函數(shù)外,js是沒(méi)有塊級(jí)作用域。
2. 作用域鏈:內(nèi)部可以訪問(wèn)外部的變量,但是外部不能訪問(wèn)內(nèi)部的變量。
注意:如果內(nèi)部有,優(yōu)先查找到內(nèi)部,如果內(nèi)部沒(méi)有就查找外部的。
3. 注意聲明變量是用var還是沒(méi)有寫(xiě)(window.)
4. 注意:js有變量提升的機(jī)制【變量懸掛聲明】
5. 優(yōu)先級(jí):聲明變量>聲明普通函數(shù)>參數(shù)>變量提升
?
面試的時(shí)候怎么看:
1.本層作用域有沒(méi)有此變量【注意變量提升】
2.注意:js除了函數(shù)外沒(méi)有塊級(jí)作用域
3.普通聲明函數(shù)是不看寫(xiě)函數(shù)的時(shí)候順序
// 考題一:
function c(){
var b = 1;
function a(){
console.log( b ); // undefined
var b = 2;
console.log( b ); //2
}
a();
console.log( b ); // 1
}
c();// 考題二:
var name = 'World!';
(function(){
if (typeof name ==='undefined'){
var name ='Jack':
console.log('Goodbye'+ name): // Goodbye Jack
}else{
console.log('Hello'+name):
}
})()// 考題三
var bar = 1;
function test(){
console.log( bar ); // undefine
var bar = 2;
console.log( bar ); // 2
}
test();
function fun( a ){
var a = 10;
functibn a(){}
console.log( a ); // 10
}
fun( 100 );// 考題四:
function fun(){
var a = 2;
function a(){}
console.log( a ); // 2
}
fun();
function fun(){
console.log( a ); // f a(){}
var a = 10;
function a(){}
}
fun();
function fun(){ // var a
a=10;
console.log( a ); // 10
var a = 20;
console.log( a ); // 20
}
fun();面試題:JS對(duì)象考題
JS對(duì)象注意點(diǎn):
1. 對(duì)象是通過(guò)new操作符構(gòu)建出來(lái)的,所以對(duì)象之間不相等
2. 對(duì)象注意:引用類(lèi)型
3. 對(duì)象的key都是字符串類(lèi)型
4. 對(duì)象如何找屬性|方法
先在對(duì)象本身找===>構(gòu)造函數(shù)中找===>對(duì)象原型中找===>構(gòu)造函數(shù)原型中找 ===>對(duì)象上一層原型查找
// 面試題一: console.log( [1,2,3] === [1,2,3] ); // true
// 面試題二:
var obj1= {
a:'hellow‘
}
var obj2 = obj1
obj2.a = 'world'
console.log(obj1) //{a:'world'}
(function(){
console.log(a) // undefinud
var a=1
})();// 面試題三:
var a = {};
var b = {
key:'a'
}
var с = {
key:'c"
}
a[b] ='123';
a[c] ='456';
console.log( a[b] ) // '456'面試題:JS作用域+this指向+原型考題
// 考題一:
function Foo({
getName= function(){console.log(1)}//注意是全局的window.
return this;
}
Foo.getName = function()(console.log(2))
Foo.prototype.getName = function()(console.log(3)}
var getName = function()(console.log(4))
function getName(){
console.log(5)
}
Foo.getName(); // 2
getName(); // 4
Foo().getName(); // 1
getName(); // 1
new Foo().getName(); // 3// 考題二:
var o ={
a:10,
b:{
fn:function(){
console.log(this.a ); // undefined
console.log(this) // {fn:f}, 代表對(duì)象
}
}
}
o.b.fn();面試題:JS判斷變量是不是數(shù)組,你能寫(xiě)出哪些方法
方法一:isArray
var arr = [1,2,3];
console.log(Array isArray( arr ) );
方法二:instancerof
var arr = [1,2,3];
console.log( arr instanceof Array);
方法三:原型prototype
console.log( Object.prototype.toString.call(arr).indexOf('Array') > -1):
方法四:isPrototypeOf()
console.log( Array.prototype.isPrototypeof(arr))
方法無(wú):constructor
console.log( arr.constructor.toString().indexof('Array') > -1)面試題:slice是干嘛的、splice是否會(huì)改變?cè)瓟?shù)組
1.slice是來(lái)截取的
參數(shù)可以寫(xiě)slice(3)、slice(1,3)、slice(-3)
返回的是一個(gè)新的數(shù)組
2.splice功能有:插入、刪除、替換
返回:刪除的元素
該方法會(huì)改變?cè)瓟?shù)組
面試題:JS數(shù)組去重
方式一:new Set
var arr1 = [1,2,3,2,4,1];
console.log( Array.from( new Set(arr1))); // [1,2,3,4]
console.log( [...new Set(arr1)] ); // [1,2,3,4]
function unique(arr){
return [...new Set(arr)]
}
console.log(unique(arr1) ); // [1,2,3,4]方式二:indexOf
var arr2 = [1,2,3,2,4,1];
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;
}
console.log( unique(arr2) ); // [1,2,3,4]方式三:sort
var arr3 = [1,2,3,2,4,1];
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;
}
console.log( unique(arr3) ); // [1,2,3,4]面試題:找出多維數(shù)組最大值
function fnArr(arr){
var newArr = [];
arr.forEach((item,index)=>{
newArr.push(Math.max(...item))
})
return newArr; // [5, 27, 39, 1001]
}
console.log(fnArr([
[4,5,1,3],
[13,27,18,26],
[32,35,37,39],
[1000,1001,857,1]
]))面試題:給字符串新增方法實(shí)現(xiàn)功能
/*考題:
1.給字符串對(duì)象定義一個(gè)addPrefix函數(shù),當(dāng)傳入一個(gè)字符串str時(shí),它會(huì)返回新的帶有指定前
綴的字符串,例如:
console.log("world".addPrefix("hello")
控制臺(tái)會(huì)輸出::“helloworld"
*/
String.prototype.addPrefix = function(str){
return str + this;
}
console.log('world'.addPrefix('hello')) // helloworld面試題:找出字符串出現(xiàn)最多次數(shù)的字符以及次數(shù)
var str = 'helloworld'
var obj={};
for(var i=0;i<str.length;i++){
//charAt() 方法可返回指定位置的字符。
var char = str.charAt(i);
if( obj[char]){
obj[char]++;
}else{
obj[char] = 1;
}
}
console.log( obj ); // {h: 1, e: 1, l: 3, o: 2, w: 1, …}
//統(tǒng)計(jì)出來(lái)最大值
var max = 0;
for( var key in obj ){
if( max < obj[key] ){
max = obj [key];
}
}
//拿最大值去對(duì)比
for( var key in obj ){
if(obj[key] == max ){
console.log('最多的字符是' + key); //最多的字符是l
console.log('出現(xiàn)的次數(shù)是' + max); // 出現(xiàn)的次數(shù)是3
}
}面試題:new操作符具體做了什么
1. 創(chuàng)建了一個(gè)空的對(duì)象
2. 將空對(duì)象的原型,指向于構(gòu)造函數(shù)的原型
3. 將空對(duì)象作為構(gòu)造函數(shù)的上下文(改變this指向)
4. 對(duì)構(gòu)造函數(shù)有返回值的處理判斷
5. 如果構(gòu)造器中沒(méi)有返回對(duì)象,則返回上面的創(chuàng)建出來(lái)的對(duì)象
面試題:閉包
1.閉包是什么
閉包是一個(gè)函數(shù)加上到創(chuàng)建函數(shù)的作用域的連接,閉包“關(guān)閉”了函數(shù)的自由變量。
2. 閉包可以解決什么問(wèn)題【閉包的優(yōu)點(diǎn)】
2.1內(nèi)部函數(shù)可以訪問(wèn)到外部函數(shù)的局部變量
2.2閉包可以解決的問(wèn)題
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 變量會(huì)駐留在內(nèi)存中,造成內(nèi)存損耗問(wèn)題。
解決:把閉包的函數(shù)設(shè)置為null
3.2 內(nèi)存泄漏【ie】 ==> 可說(shuō)可不說(shuō),如果說(shuō)一定要提到ie
面試題:原型鏈
1. 原型可以解決什么問(wèn)題 對(duì)象共享屬性和共享方法 2. 誰(shuí)有原型 函數(shù)擁有:prototype 對(duì)象擁有:__proto__ 3.對(duì)象查找屬性或者方法的順序 先在對(duì)象本身查找 --> 構(gòu)造函數(shù)中查找 --> 對(duì)象的原型 --> 構(gòu)造函數(shù)的原型中 --> 當(dāng)前原型的原型這找 4.原型鏈 4.1 是什么?:就是把原型串聯(lián)起來(lái) 4.2 原型鏈的最頂端是null 每個(gè)對(duì)象(Object)都有一個(gè)私有屬性指向另一個(gè)名為原型(prototype)的對(duì)象。原型對(duì)象也有一個(gè)自己的原型,層層向上直到一個(gè)對(duì)象的原型為 null。根據(jù)定義,null 沒(méi)有原型,并作為這個(gè)原型鏈(prototype chain)中的最后一個(gè)環(huán)節(jié)。
隱式原型

原型鏈

面試題: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 );//方法二:原型鏈繼承(實(shí)現(xiàn)了共享)
function Parent(){
this.age = 20;
}
function Child(){
this.name= '張三'
}
Child.prototype = new Parent();
let o2 = new Child();
console.log( o2,o2.name,o2.age ); // {name:'張三',age:20},'張三',20// 方法三:借用構(gòu)造函數(shù)(實(shí)現(xiàn)不了共享)
function Parent(){
this.age = 20;
}
function Child(){
Parent.call(this);
this.name= '張三';
}
let o3 = new Child();
console.log( o3,o3.name,o3.age ); // {name:'張三',age:20} '張三' 20// 方法四:組合式繼承(既可以實(shí)現(xiàn)共享,也可以解決原型鏈問(wèn)題)
function Parent(){
this.age = 20;
}
function Child(){
Parent.call(this);
this.name= '張三';
}
Child.prototype = new Parent();
let o4 = new Child();
console.log( o4,o4.name,o4.age ); // {name:'張三',age:20} '張三' 20說(shuō)一下call、apply、bind區(qū)別
共同點(diǎn):功能一致
可以改變this指向語(yǔ)法:函數(shù).call()、函數(shù).apply()、函數(shù).bind()
區(qū)別:
1. call、apply可以立即執(zhí)行。bind不會(huì)立即執(zhí)行,因?yàn)閎ind返回的是一個(gè)函數(shù)需要加入()執(zhí)行
2.參數(shù)不同:apply第二個(gè)參數(shù)是數(shù)組。call和bind有多個(gè)參數(shù)需要挨個(gè)寫(xiě)。
var str='你好';
varobj={str:'這是obj對(duì)象內(nèi)的str'}
function fun(){
console.log( this, this.str );
}
//fun.call(obj); // call立即執(zhí)行
//fun.apply(obj); // apply立即執(zhí)行
fun.bind(obj)(); // 執(zhí)行結(jié)果為函數(shù)
fun. bind(obj) ; // bind不會(huì)立即執(zhí)行,因?yàn)閎ind返回的是函數(shù)
fun();
var str ='你好';
varobj={str:'這是obj對(duì)象內(nèi)的str'}
function fun( name, age ){
this.name = name;
this.age = age;
console.log( this,this.str );
}
fun.call(obj,‘張三',18); // {str:'這是obj對(duì)象內(nèi)的str',name:'張三',age:18} '這是obj對(duì)象內(nèi)的str'
fun.apply(obj,['張三',88]);// {str:'這是obj對(duì)象內(nèi)的str',name:'張三',age:88} '這是obj對(duì)象內(nèi)的str'
fun.bind(obj,['張三',88])();// {str:'這是obj對(duì)象內(nèi)的str',name:['張三',88],age:undefined} '這是obj對(duì)象內(nèi)的str'
fun.bind(obj,'張三',88)();// {str:'這是obj對(duì)象內(nèi)的str',name:'張三',age:88} '這是obj對(duì)象內(nèi)的str'場(chǎng)景
// apply
var arr1= [1,2,4,5,7,3,321];
console.log(Math.max.apply(null,arr1))
// bind
var btn = document.getElementById('btn');
var h1s = document.getElementById('h1s');
btn.onclick = function(){
console.log( this.id );
}.bind(h1s)sort背后原理是什么?
V8引擎sort函數(shù)只給出了兩種排序InsertionSort和QuickSort,數(shù)量小于10的數(shù)組使用InsertionSort,比10大的數(shù)組則使用QuickSort。
之前的版本是:插入排序和快排,現(xiàn)在是冒泡
鏈接:
https://github.com/v8/v8/blob/ad82a40509c5b5b4680d4299c8f08d6c6d31af3c/src/js/array.js
var arr1= [12,11,1,23,'45','34',21,'b','a','ab','bc'];
console.log( arrl.sort()); // [1,11,12,21,23,'34','45','a','ab','b','bc']
var arr2= [12,111,11,1,23,'45','34',21];
var arr3 = arr2.sort(function( a, b ){
return b-a;
})
console.log( arr3 ); // [111,'45','34',23,21,12,11,1]
var arr4 = [
{name:'zhangsan',age:18},
{name:'lisi',age:2},
{name:'wangwu',age:50},
];
function compare(age){
return function(a,b){
var val1 = alage];
var val2 = b[age];
return val1 - val2;
}
}
var arr5 = arr4.sort(compare('age'));
console.log( arr5 );// {name:'wangwu',age: 50}
// {name:'zhangsan',age: 18}
// {Rname:'lisi',age:2} 深拷貝和淺拷貝
共同點(diǎn):復(fù)制
1. 淺拷貝:只復(fù)制引用,而未復(fù)制真正的值。
2. 深拷貝:是復(fù)制真正的值(不同引用)
// 1、淺拷貝
var arr1= ['a','b','c','d'];
var arr2 = arr1;
arr1[0]='你好嗎';
arr2[1]='還行';
console.log( arr1, arr2 ); // ['你好嗎',‘還行','c','d']
var obj1 = {a:1,b:2}
var obj2 = Object.assign(obj1);
obj1.a = '100';
obj2.b = '你怎么養(yǎng)';
console.log( obj1,obj2); // {a:'100',b:'你怎么養(yǎng)'}// 2、深拷貝
var obj3 = {
a:1,
b:2
}
var obj4 = JSON.parse(JSON.stringify( obj3));
obj3.a = '100′;
obj4.b = '你怎么陽(yáng)'
console.log( obj3, obj4 ); // {a: '100',b:2}{a:1,b:'你怎么陽(yáng)'}// 遞歸形式
var obj5 ={
a:1,
b:2,
arr:['a','b','c','d']
}
function copyObj( obj ){
if(Array.isArray(obj){
var newObj = [];
}else{
var newObj = {};
}
for( var key in obj ){
if( typeof obj[keyl =object' ){
newObj[key] = copyObj(obj[keyl);
}else{
newObj[key] = obj[key];
}
}
return newObj;
}
console.log(copyObj(obj5));面試題:localStorage、sessionStorage、cookie的區(qū)別
公共點(diǎn):在客戶(hù)端存放數(shù)據(jù)
區(qū)別:
1.?dāng)?shù)據(jù)存放有效期
sessionStorage :僅在當(dāng)前瀏覽器窗口關(guān)閉之前有效?!娟P(guān)閉瀏覽器就沒(méi)了】
localStorage :始終有效,窗口或者瀏覽器關(guān)閉也一直保存,所以叫持久化存儲(chǔ)。
cookie :只在設(shè)置的cookie過(guò)期時(shí)間之前有效,即使窗口或者瀏覽器關(guān)閉也有效。2. localStorage、sessionStorage不可以設(shè)置過(guò)期時(shí)間
cookie有過(guò)期時(shí)間,可以設(shè)置過(guò)期(把時(shí)間調(diào)整到之前的時(shí)間,就過(guò)期了)3.存儲(chǔ)大小的限制
cookie存儲(chǔ)量不能超過(guò)4k
localStorage、sessionStorage不能超過(guò)5M****根據(jù)不同的瀏覽器存儲(chǔ)的大小是不同的。
總結(jié)
到此這篇關(guān)于JavaScript常問(wèn)面試題及答案總結(jié)的文章就介紹到這了,更多相關(guān)JS常問(wèn)面試題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序?qū)崿F(xiàn)左右列表聯(lián)動(dòng)
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)左右列表聯(lián)動(dòng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
JavaScript表單即時(shí)驗(yàn)證 驗(yàn)證不成功不能提交
這篇文章主要為大家詳細(xì)介紹了JavaScript表單即時(shí)驗(yàn)證,驗(yàn)證不成功不能提交,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08
React Native JSI實(shí)現(xiàn)RN與原生通信的示例代碼
本文主要介紹了React Native JSI實(shí)現(xiàn)RN與原生通信的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
JavaScript指定斷點(diǎn)操作實(shí)例教程
這篇文章主要給大家介紹了關(guān)于JavaScript指定斷點(diǎn)操作的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09
javascript獲取隱藏dom的寬高 具體實(shí)現(xiàn)
一個(gè)隱藏的DOM是獲取不到寬高的,如果想要獲取,采用下面的方法:2013-07-07
jQuery及JS實(shí)現(xiàn)循環(huán)中暫停的方法
這篇文章主要介紹了jQuery及JS實(shí)現(xiàn)循環(huán)中暫停的方法,以實(shí)例形式分析了循環(huán)中暫停的原理及實(shí)現(xiàn)技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-02-02
微信小程序?qū)崿F(xiàn)上傳照片代碼實(shí)例解析
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)上傳照片代碼實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08

