- 這是來自某出行類大司的一面。
- 偏Javascript基礎。
js基礎
1.基本類型有哪些
Number String Boolean Null Undefined Symbol (落下沒說)
2.Null 和 Undefined什麼區別?
參考文章:undefined與null的區別
null表示"沒有對象",即該處不應該有值。典型用法是:
(1) 作爲函數的參數,表示該函數的參數不是對象。
(2) 作爲對象原型鏈的終點。
undefined表示"缺少值",就是此處應該有一個值,但是還沒有定義。典型用法是:
(1)變量被聲明瞭,但沒有賦值時,就等於undefined。
(2) 調用函數時,應該提供的參數沒有提供,該參數等於undefined。
(3)對象沒有賦值的屬性,該屬性的值爲undefined。
(4)函數沒有返回值時,默認返回undefined。
區別:
(1)定義:undefined表示一個變量沒有被聲明,或者被聲明瞭但沒有被賦值。(比如,一個沒有傳入實參的形參變量的值爲undefined。再比如,如果一個函數什麼都不返回,則該函數默認返回undefined;)
null是一個表示“沒有值”的值,是空對象引用,引用指向爲空 。
(2)類型:undefined的類型(typeof)是undefined;null的類型(typeof)是object。
(3)用Number()轉化成數值:undefined爲NaN ,null爲0。
3.如何判斷數組類型,幾種方法?
參考文章:Js中如何判斷一個對象爲數組類型
var testArr = [1, 2]
console.log (testArr instanceof Array )
console.log( testArr.constructor == Array ) // 不一定準確,因爲數組是引用類型
console.log( Object.prototype.toString.call(testArr) === '[object Array]' )
console.log( Array.isArray( testArr) ) //ES5提供
4.循環有哪些寫法?for括號中有什麼,能不寫嗎?while的條件可以是什麼?結束循環有哪些方式?
結束循環的方法:
- return ==》結束循環並中斷函數執行;
- break ==》結束循環函數繼續執行;
- continue ==》跳過本次循環;
- for 循環中的變量 i,由於 ES5並沒有塊級作用域的存在,它在循環結束以後仍然存在於內存中,所以建議使用函數自執行的方式來避免;
10.遍歷一個數組的方法?
(1)常用的方法性能對比(由強到弱):for(length緩存,每次計算length、不爲null)、forEach、map、for of 、for in 。參考文章:JS幾種數組遍歷方式以及性能分析對比(已經不知道誰是原作者了,2006年的應該是吧)
(2)我不常用的方法還有:filter、some、every、reduce、reduceRight、find、findIndex
(3)ES6提供的:entries()、keys()、values()
參考文章:js數組遍歷方法總結(頁面好看點就完美了)
它們都返回一個遍歷器對象,可以用for...of循環進行遍歷,唯一的區別是keys()是對鍵名的遍歷、values()是對鍵值的遍歷,entries()是對鍵值對的遍歷。
5.ES6:let 和 var 有哪些區別?
(1)塊作用域:let
聲明的變量僅在塊級作用域內有效,var聲明的變量在全局範圍內都有效。
(2)變量提升:let
聲明的變量一定要在聲明後使用,否則報錯ReferenceError。var聲明的
變量可以在聲明之前使用,值爲undefined,即
“變量提升”。
(3)let的“暫時性死區”(TDZ):如果區塊中存在let
和const
命令,這個區塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡是在聲明之前就使用這些變量,就會報錯。使用let
命令聲明變量之前,該變量都是不可用的。這在語法上,稱爲“暫時性死區”(temporal dead zone,簡稱 TDZ)。
if (true) {
// TDZ開始
tmp = 'abc'; // ReferenceError
console.log(tmp); // ReferenceError
let tmp; // TDZ結束
console.log(tmp); // undefined
tmp = 123;
console.log(tmp); // 123
}
6.ES6:箭頭函數與普通函數寫法有什麼區別?
參考文章:箭頭函數和普通函數的區別
(1)構造函數:箭頭函數沒有構造函數,不能通過new獲得對象。
(2)參數:箭頭函數不綁定arguments,取而代之用rest參數...解決
let C = (...c) => {
console.log(arguments) // Uncaught ReferenceError: arguments is not defined
console.log(c);
}
C(3,82,32,11323); // [3, 82, 32, 11323]
(3)this指向:箭頭函數不綁定this,會捕獲其所在的上下文的this值,作爲自己的this值。
(先自己分析,再看鏈接裏的具體分析)
示例一:
var obj = {
a: 10,
b: function(){
console.log(this.a); //10
},
c: function() {
return ()=>{
console.log(this.a); //10
}
}
}
obj.b();
obj.c()();
示例二:
var obj = {
a: 10,
b: () => {
console.log(this.a); //undefined
console.log(this); //window
},
c: function() {
console.log(this.a); //10
console.log(this); //obj{...}
}
}
obj.b();
obj.c();
(4)使用call()和apply()調用:直傳入參數,不改變this指向。
(5)原型屬性:箭頭函數沒有原型屬性。
(6)箭頭函數不能當做Generator函數,不能使用yield關鍵字。
(7)箭頭函數不能換行。
7.一個頁面引入了1.js和2.js,1.js中有個變量a,2.js能訪問到a變量嗎?怎麼訪問?
我想到的最直接的:html中引用1.js、2.js,2.js中可以訪問1.js中的方法從而訪問到變量。具體怎麼寫?兩種。
方法一:構造函數。
從閉包角度,對於getName,它的作用域鏈中包括包含函數的作用域,所以能訪問到name變量
<!--在html中-->
<script src="coding.js"></script>
<script src="test.js"></script> <!--引用coding.js中的變量-->
// coding.js中
function Person(name){
var name = name || "noName"
// 從閉包角度,對於getName,它的作用域鏈中包括包含函數的作用域,所以能訪問到name變量
this.getName=function(){
return name;
};
// setName同理
this.setName=function(value){
name=value;
};
}
// test.js
var person = new Person()
console.log(person.name) // undefined
console.log(person.getName()) // noName
var person=new Person('哈哈');
console.log(person.getName());//'哈哈'
person.setName('呀呀');
console.log(person.getName());//'呀呀'
方法二:利用閉包的私有作用域。
構造函數使用函數表達式 並且不用var聲明;公共方法寫在原型鏈上;私有變量是實例共享的;
// coding.js
(function(){
var name='noName';
// 構造函數使用函數表達式,然而不用var聲明,所以是全局的
Person=function(value){
name = value;
};
// 公共方法寫在原型鏈上,都訪問同樣的內部變量,所以私有變量是實例共享的
Person.prototype.getName=function(){
return name;
};
Person.prototype.setName=function(value){
name=value;
}
})();
// test.js
var person = new Person()
console.log('直接訪問:' + person.name)
console.log('無參數訪問:' + person.getName())
var person1=new Person('舊實例');
var person2=new Person('新實例');
console.log(person1.getName());
console.log(person2.getName());
方法三:使用本地存儲策略。cookie或者localStorage。(回憶一下做過的微信小程序項目)
方法四:使用參數傳遞。
這兩種方法感覺不是本題的意思,應該屬於跨頁面的數據傳遞。
參考文章:JS實現把一個頁面層數據傳遞到另一個頁面的兩種方式
8.形參和實參分別是什麼。
形參是函數定義的時候的參數。實參是調用該函數實際傳入的參數。
function add(a,b) { // a b 是形參
return a + b
};
add(1,2); // 1 2 是實參
需要注意的是:
- 調用函數傳遞的實參與定義函數規定的形參是依次對應的
- 超出形參數目的實參不傳遞其值。
- 如果沒有對應的實參(實參數目少於形參數目)傳入,其值爲undefined。
- 而函數使用了形參未定義的‘字面量’,出錯:xx is not defined 。
// 關於實參、形參
function add(a, b, c){
// console.log(arguments)
console.log(a,b,c)
console.log(a + b + c)
// console.log(x) //報錯:x is not defined
}
add(1,2,3,4)
add(1,2)
add(1,'2',3)
9.說一下作用域鏈。
看前面的總結即可。閉包爲什麼會造成內存泄漏?
數據結構
1.什麼是平衡二叉樹?滿二叉樹?完全二叉樹?
下一篇:
設計模式
整理單獨一篇吧
用vue實現數據雙向綁定舉例子說的觀察者模式。