JavaScript
1、介紹js的基本數據類型。
Undefined、Null、Boolean、Number、String、
ECMAScript 2015新增:Symbol(創建后獨一無二且不可變的數據類型)
2、介紹js有哪些內置對象?
Object是JavaScript中所有對象的父對象
數據封裝類對象:Object、Array、Boolean、Number和String
其他對象:Function、Arguments、Math、Date、RegExp、Error
3、說幾條寫JavaScript的基本規范?
(1)不要在同一行聲明多個變量。
(2)請使用===/!==來比較true/false或者數值
(3)使用對象字面量替代new Array這種形式
(4)不要使用全局函數。
(5)Switch語句必須帶有default分支
(6)函數不應該有時候有返回值,有時候沒有返回值。
(7)For循環必須使用大括號
(8)If語句必須使用大括號
(9)for-in循環中的變量應該使用var關鍵字明確限定作用域,從而避免作用域污染。
4、JavaScript原型,原型鏈?有什么特點?
每個對象都會在其內部初始化一個屬性,就是prototype(原型),當我們訪問一個對象的屬性時,
如果這個對象內部不存在這個屬性,那么他就會去prototype里找這個屬性,這個prototype又會有自己的prototype,
于是就這樣一直找下去,也就是我們平時所說的原型鏈的概念。
關系:instance.constructor.prototype = instance.__proto__
特點:
JavaScript對象是通過引用來傳遞的,我們創建的每個新對象實體中并沒有一份屬于自己的原型副本。當我們修改原型時,與之相關的對象也會繼承這一改變。
當我們需要一個屬性的時,Javascript引擎會先看當前對象中是否有這個屬性,如果沒有的話,
就會查找他的Prototype對象是否有這個屬性,如此遞推下去,一直檢索到Object內建對象。
function Func(){}
Func.prototype.name = "Sean";
Func.prototype.getInfo = function() {
return this.name;
}
var person = new Func();//現在可以參考var person = Object.create(oldObject);
console.log(person.getInfo());//它擁有了Func的屬性和方法
//"Sean"
console.log(Func.prototype);
// Func {name="Sean", getInfo=function()}
5、JavaScript有幾種類型的值?,你能畫一下他們的內存圖嗎?
棧:原始數據類型(Undefined,Null,Boolean,Number、String)
堆:引用數據類型(對象、數組和函數)
兩種類型的區別是:存儲位置不同;
原始數據類型直接存儲在棧(stack)中的簡單數據段,占據空間小、大小固定,屬于被頻繁使用數據,所以放入棧中存儲;
引用數據類型存儲在堆(heap)中的對象,占據空間大、大小不固定。如果存儲在棧中,將會影響程序運行的性能;引用數據類型在棧中存儲了指針,該指針指向堆中該實體的起始地址。當解釋器尋找引用值時,會首先檢索其在棧中的地址,取得地址后從堆中獲得實體
6、如何將字符串轉化為數字,例如'12.3b'?
* parseFloat('12.3b');
*正則表達式,'12.3b'.match(/(\d)+(\.)?(\d)+/g)[0]* 1,但是這個不太靠譜,提供一種思路而已。
7、如何將浮點數點左邊的數每三位添加一個逗號,如12000000.11轉化為『12,000,000.11』?
function commafy(num){
return num && num
.toString()
.replace(/(\d)(?=(\d{3})+\.)/g, function($1, $2){
return $2 + ',';
});
}
8、如何實現數組的隨機排序?
方法一:```javascriptvar arr = [1,2,3,4,5,6,7,8,9,10]; function randSort1(arr){ for(var i = 0,len =arr.length;i < len; i++ ){ var rand = parseInt(Math.random()*len); var temp= arr[rand]; arr[rand] = arr[i]; arr[i] = temp; } return arr; } console.log(randSort1(arr));
```
方法二:
```javascript
var arr = [1,2,3,4,5,6,7,8,9,10];
function randSort2(arr){
var mixedArray = [];
while(arr.length > 0){
var randomIndex =parseInt(Math.random()*arr.length);
mixedArray.push(arr[randomIndex]);
arr.splice(randomIndex, 1);
}
return mixedArray;
}
console.log(randSort2(arr));
```
方法三:
```javascript
var arr = [1,2,3,4,5,6,7,8,9,10];
arr.sort(function(){
return Math.random() - 0.5;
})
console.log(arr);
```
9、Javascript如何實現繼承?
(1)構造繼承
(2)原型繼承
(3)實例繼承
(4)拷貝繼承
原型prototype機制或apply和call方法去實現較簡單,建議使用構造函數與原型混合方式。
```javascript
function Parent(){
this.name = 'wang';
}
function Child(){
this.age = 28;
}
Child.prototype = new Parent();//繼承了Parent,通過原型
var demo = new Child();
alert(demo.age);
alert(demo.name);//得到被繼承的屬性
```
10、javascript創建對象的幾種方式?
javascript創建對象簡單的說,無非就是使用內置對象或各種自定義對象,當然還可以用JSON;但寫法有很多種,也能混合使用。
(1)對象字面量的方式
person={firstname:"Mark",lastname:"Yun",age:25,eyecolor:"black"};
(2)用function來模擬無參的構造函數
function Person(){}
var person=new Person();//定義一個function,如果使用new"實例化",該function可以看作是一個Class
person.name="Mark";
person.age="25";
person.work=function(){
alert(person.name+" hello...");
}
person.work();
(3)用function來模擬參構造函數來實現(用this關鍵字定義構造的上下文屬性)
function Pet(name,age,hobby){
this.name=name;//this作用域:當前對象
this.age=age;
this.hobby=hobby;
this.eat=function(){
alert("我叫"+this.name+",我喜歡"+this.hobby+",是個程序員");
}
}
var maidou =new Pet("麥兜",25,"coding");//實例化、創建對象
maidou.eat();//調用eat方法
(4)用工廠方式來創建(內置對象)
var wcDog =new Object();
wcDog.name="旺財";
wcDog.age=3;
wcDog.work=function(){
alert("我是"+wcDog.name+",汪汪汪......");
}
wcDog.work();
(5)用原型方式來創建
function Dog(){
}
Dog.prototype.name="旺財";
Dog.prototype.eat=function(){
alert(this.name+"是個吃貨");
}
var wangcai =new Dog();
wangcai.eat();
(6)用混合方式來創建
function Car(name,price){
this.name=name;
this.price=price;
}
Car.prototype.sell=function(){
alert("我是"+this.name+",我現在賣"+this.price+"萬元");
}
var camry =new Car("凱美瑞",27);
camry.sell();
11、Javascript作用鏈域?
全局函數無法查看局部函數的內部細節,但局部函數可以查看其上層的函數細節,直至全局細節。
當需要從局部函數查找某一屬性或方法時,如果當前作用域沒有找到,就會上溯到上層作用域查找,
直至全局函數,這種組織形式就是作用域鏈。
12、談談This對象的理解。
this總是指向函數的直接調用者(而非間接調用者);
如果有new關鍵字,this指向new出來的那個對象;
在事件中,this指向觸發這個事件的對象,特殊的是,IE中的attachEvent中的this總是指向全局對象Window;
13、eval是做什么的?
它的功能是把對應的字符串解析成JS代碼并運行;
應該避免使用eval,不安全,非常耗性能(2次,一次解析成js語句,一次執行)。
由JSON字符串轉換為JSON對象的時候可以用eval,var obj =eval('('+ str +')');
14、什么是window對象?什么是document對象?
window對象是指瀏覽器打開的窗口。
document對象是Documentd對象(HTML文檔對象)的一個只讀引用,window對象的一個屬性。
15、null,undefined的區別?
null表示一個對象是“沒有值”的值,也就是值為“空”;
undefined表示一個變量聲明了沒有初始化(賦值);
undefined不是一個有效的JSON,而null是;
undefined的類型(typeof)是undefined;
null的類型(typeof)是object;
Javascript將未賦值的變量默認值設為undefined;
Javascript從來不會將變量設為null。它是用來讓程序員表明某個用var聲明的變量時沒有值的。
typeof undefined
//"undefined"
undefined :是一個表示"無"的原始值或者說表示"缺少值",就是此處應該有一個值,但是還沒有定義。當嘗試讀取時會返回undefined;
例如變量被聲明了,但沒有賦值時,就等于undefined
typeof null
//"object"
null :是一個對象(空對象,沒有任何屬性和方法);
例如作為函數的參數,表示該函數的參數不是對象;
注意:
在驗證null時,一定要使用===,因為==無法分別null和undefined
null == undefined // true
null=== undefined // false
再來一個例子:
null
Q:有張三這個人么?
A:有!
Q:張三有房子么?
A:沒有!
undefined
Q:有張三這個人么?
A:有!
Q:張三有多少歲?
A:不知道(沒有被告訴)
16、寫一個通用的事件偵聽器函數。
// event(事件)工具集,來源:github.com/markyun
markyun.Event = {
//頁面加載完成后
readyEvent : function(fn) {
if (fn==null) {
fn=document;
}
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = fn;
} else {
window.onload = function() {
oldonload();
fn();
};
}
},
//視能力分別使用dom0||dom2||IE方式來綁定事件
//參數:操作的元素,事件名稱,事件處理程序
addEvent : function(element, type, handler) {
if (element.addEventListener) {
//事件類型、需要執行的函數、是否捕捉
element.addEventListener(type,handler, false);
} else if (element.attachEvent) {
element.attachEvent('on' +type, function() {
handler.call(element);
});
} else {
element['on' + type] = handler;
}
},
//移除事件
removeEvent : function(element, type, handler) {
if (element.removeEventListener) {
element.removeEventListener(type, handler, false);
} else if (element.datachEvent) {
element.detachEvent('on' +type, handler);
} else {
element['on' + type] = null;
}
},
//阻止事件(主要是事件冒泡,因為IE不支持事件捕獲)
stopPropagation : function(ev) {
if (ev.stopPropagation) {
ev.stopPropagation();
} else {
ev.cancelBubble = true;
}
},
//取消事件的默認行為
preventDefault : function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
//獲取事件目標
getTarget : function(event) {
return event.target || event.srcElement;
},
//獲取event對象的引用,取到事件的所有信息,確保隨時能使用event;
getEvent : function(e) {
var ev = e || window.event;
if (!ev) {
var c = this.getEvent.caller;
while (c) {
ev = c.arguments[0];
if (ev && Event ==ev.constructor) {
break;
}
c = c.caller;
}
}
return ev;
}
};
17、["1","2", "3"].map(parseInt)答案是多少?
parseInt()函數能解析一個字符串,并返回一個整數,需要兩個參數(val, radix),
其中radix表示要解析的數字的基數。【該值介于2 ~ 36之間,并且字符串中的數字不能大于radix才能正確返回數字結果值】;
但此處map傳了3個(element, index, array),我們重寫parseInt函數測試一下是否符合上面的規則。
function parseInt(str, radix) {
return str+'-'+radix;
};
var a=["1", "2","3"];
a.map(parseInt);? // ["1-0", "2-1","3-2"]不能大于radix
因為二進制里面,沒有數字3,導致出現超范圍的radix賦值和不合法的進制解析,才會返回NaN
所以["1", "2", "3"].map(parseInt)答案也就是:[1,NaN, NaN]
18、事件是?IE與火狐的事件機制有什么區別?如何阻止冒泡?
(1)我們在網頁中的某個操作(有的操作對應多個事件)。例如:當我們點擊一個按鈕就會產生一個事件。是可以被JavaScript偵測到的行為。
(2)事件處理機制:IE是事件冒泡、Firefox同時支持兩種事件模型,也就是:捕獲型事件和冒泡型事件;
(3)ev.stopPropagation();(舊ie的方法ev.cancelBubble = true;)
19、什么是閉包(closure),為什么要用它?
閉包是指有權訪問另一個函數作用域中變量的函數,創建閉包的最常見的方式就是在一個函數內創建另一個函數,通過另一個函數訪問這個函數的局部變量,利用閉包可以突破作用鏈域,將函數內部的變量和方法傳遞到外部。
閉包的特性:
(1)函數內再嵌套函數
(2)內部函數可以引用外層的參數和變量
(3)參數和變量不會被垃圾回收機制回收
//li節點的onclick事件都能正確的彈出當前被點擊的li索引
index = 0
index = 1
index = 2
index = 3
var nodes = document.getElementsByTagName("li");
for(i = 0;i
nodes[i].onclick = (function(i){
return function() {
console.log(i);
} //不用閉包的話,值每次都是4
})(i);
}
執行say667()后,say667()閉包內部變量會存在,而閉包內部函數的內部變量不會存在
使得Javascript的垃圾回收機制GC不會收回say667()所占用的資源
因為say667()的內部函數的執行需要依賴say667()中的變量
這是對閉包作用的非常直白的描述
function say667() {
// Local variable that ends up within closure
var num = 666;
var sayAlert = function() {
alert(num);
}
num++;
return sayAlert;
}
varsayAlert = say667();
sayAlert()//執行結果應該彈出的667
20、javascript代碼中的"usestrict";是什么意思?使用它區別是什么?
use strict是一種ECMAscript 5添加的(嚴格)運行模式,這種模式使得Javascript在更嚴格的條件下運行,
使JS編碼更加規范化的模式,消除Javascript語法的一些不合理、不嚴謹之處,減少一些怪異行為。
默認支持的糟糕特性都會被禁用,比如不能用with,也不能在意外的情況下給全局變量賦值;
全局變量的顯示聲明,函數必須聲明在頂層,不允許在非函數代碼塊內聲明函數,arguments.callee也不允許使用;
消除代碼運行的一些不安全之處,保證代碼運行的安全,限制函數中的arguments修改,嚴格模式下的eval函數的行為和非嚴格模式的也不相同;
提高編譯器效率,增加運行速度;
為未來新版本的Javascript標準化做鋪墊。
京程一燈,夢起的地方,我們始終相信通過努力,可以改變自己的命運。
我們始終相信,通過堅持不懈,可以為大家解決更多的前端技術問題。
我們始終相信,時間可以證明,我們可以為廣大IT從業者解決前端學習路線。
HTML5,CSS3,Web前端,jquery,javascript,前端學習路線,各類問題,我們都可以為你解決。
更多技術好文,前端問題,面試技巧,請關注京程一燈(原一燈學堂)