一、問答
1.基礎(chǔ)類型有哪些?復(fù)雜類型有哪些?有什么特征?
①基礎(chǔ)類型包括:number,boolean,string,null,undefinded。
②復(fù)雜類型包括:指的是由多個值構(gòu)成的對象,有對象、函數(shù)、數(shù)組、正則等。
基礎(chǔ)類型
①基礎(chǔ)類型指的是保存在棧內(nèi)存(連續(xù)的)中的簡單數(shù)據(jù)段,它在內(nèi)存中具有固定大小,存儲的是數(shù)據(jù)的具體值;基本類型的訪問是按值訪問的,可以操作保存在變量中的實際的值。
②它進行復(fù)制時,會在該變量上創(chuàng)建一個新值,然后再把該值復(fù)制到為新變量分配的位置上。
基本類型的特征:
1.基本類型的值是不可變的;
2.基本類型的比較是值的比較;
3.基本類型的變量是存放在棧內(nèi)存復(fù)雜類型
復(fù)雜類型指的是保存在堆內(nèi)存中的對象,意思是,變量中保存的實際上只是一個指針,這個指針指向內(nèi)存中的另一個位置,由該位置保存對象。
復(fù)雜類型的特征
1.引用類型的值是可變的;
2.基本類型的比較是內(nèi)存地址的比較;
3.引用類型的值是同時保存在棧內(nèi)存和堆內(nèi)存中的對象,棧區(qū)內(nèi)存保存變量標(biāo)識符和指向堆內(nèi)存中該對象的指針,也可以說是該對象在堆內(nèi)存的地址。總結(jié):JS里基本類型(值)和復(fù)雜類型(引用)有什么區(qū)別?
①基本類型變量存的是值,復(fù)雜類型的變量存的是內(nèi)存地址。
②基本類型在賦值的時候拷貝值,復(fù)雜類型在賦值的時候只拷貝地址,不拷貝值。
Reference
基本類型 引用類型 簡單賦值 對象引用
舉例說明:
1.基礎(chǔ)類型
var a = 1;
var b = a; //將a里面的內(nèi)容賦給b,所以b=1,
a = 2; //將a改為2了,但b里面沒有改變。a,b是簡單類型,它們之間是相互獨立的
console.log(a,b) //所以結(jié)果是 2 1
2.復(fù)雜類型
var obj1 = {name:'hunger',sex:'male'};
obj2 = obj1; //這是將obj1的堆內(nèi)存地址賦給obj2
obj1.name = 'xiaoming' //這里相當(dāng)于改變了堆內(nèi)存中對象的屬性值
console.log(obj2.name); //xiaoming

上面的復(fù)雜類型改變一下;
var obj1 = {name:'hunger',sex:'male'};
obj2 = obj1;
obj1.name = 'xiaoming'
console.log(obj2.name); //xiaoming
obj1 = {}; //obj1開辟了一個新的空間,并且指向這個空間
console.log(obj1,obj2) //obj2還是指向原來的空間


2.如下代碼的輸出? 為什么?
var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);
//obj1和obj2雖然內(nèi)容相同,但是它們內(nèi)存地址不相同,指針指向的空間不同,如圖1
console.log(obj1 = obj2);
//將obj2的內(nèi)存地址賦給obj1,然后指向同一個地址,返回obj1所指向的對象,如圖2
console.log(obj1 == obj2);
//obj1和obj2的內(nèi)存地址相同,所以true
打印結(jié)果

圖1

圖2

二、代碼
1.寫一個函數(shù)getIntv,獲取從當(dāng)前時間到指定日期的間隔時間
var str = getIntv("2016-01-08");
console.log(str); // 距除夕還有 20 天 15 小時 20 分 10 秒
function getIntv(val){
var timeline = Date.parse(val)-Date.now()
//這樣寫是它們之間的間隔時間,用毫秒數(shù)來表現(xiàn)的
var day = Math.floor(timeline/(24*60*60*1000))
//這樣寫是間隔時間除以一天的毫秒數(shù),得到的是多少天的時間,例如10.333,然后通過Math.floor取10。
var hour = Math.floor((timeline-day*24*60*60*1000)/(60*60*1000))
//這樣寫時間隔時間減去整數(shù)天的毫秒數(shù)就是剩下的毫秒數(shù),也就是上面取10天之后剩下的小數(shù)點的時間,
//然后再除以小時的毫秒數(shù),然后取整數(shù)小時的時間。下面依次類推
var minute = Math.floor((timeline-day*24*60*60*1000-hour*60*60*1000)/(60*1000))
var second = Math.floor((timeline-day*24*60*60*1000-hour*60*60*1000-minute*60*1000)/(1000))
return "距離國慶還有"+day+"天"+hour+"小時"+minute+"分鐘"+second+"秒"
}
var str = getIntv("2016-10-1")
console.log(str);
打印結(jié)果:

2.把數(shù)字日期改成中文日期
var str = getChsDate('2015-01-08');
console.log(str); // 二零一五年一月八日
方法1:
function getChsDate(val){
var arr = ["零","一","二","三","四","五","六","七","八","九"];
var d = new Date(val);
//new Date接受參數(shù)時間時,返回本地時間的字符串形式,
//例如:var Jan02_1970 = new Date(3600*24*1000);
//Fri Jan 02 1970 08:00:00 GMT+0800 (中國標(biāo)準(zhǔn)時間)
var yeardate = d.getFullYear().toString().split("");
//d 時間對象傳遞了參數(shù),然后獲取的年份是所傳遞參數(shù)時間的年份,
//例如Jan02_1970.getFullYear()
//1970
var year = '';
for(var i = 0;i <yeardate.length; i++){
year += arr[yeardate[i]];
//這里是遍歷數(shù)組yeardate,然后將遍歷出來的數(shù)字成了arr數(shù)組的索引,再得到arr數(shù)組里面的實際值,
//最后賦值給year。
//注意:arr['1']會轉(zhuǎn)換為arr[1],數(shù)組下標(biāo)數(shù)字字符串轉(zhuǎn)化數(shù)字
}
var month = arr[d.getMonth() + 1];
var day = arr[d.getDate()];
var result = year + "年" + month + "月" + day +"日";
return result;
}
var str = getChsDate('2015-01-08');
console.log(str); //二零一五年一月八日
方法2:
function getChsDate(val) {
var arr = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
var valArr = val.split('-') //將字符串轉(zhuǎn)化為字符串?dāng)?shù)組的形式
var year = []
for (var i = 0; i < valArr[0].length; i++) {
year += arr[valArr[0][i]]
//valArr[0][i]是遍歷年份,得到年份里面的數(shù)字
}
function getChs(num) {
if (num < 10) {
return arr[num[1]]
//arr[num[1]] 傳遞參數(shù)如月份,然后是數(shù)字字符串月份下標(biāo)1,然后得到實際的值,
//然后作為arr數(shù)組的下標(biāo),最后得到arr數(shù)組下標(biāo)對應(yīng)的值
}else if (num === 10 ) {
return '十'
}else if (num > 10 && num < 20) {
return '十' + arr[num[1]]
}else if (num === 20) {
return '二十'
}else if (num > 20 && num < 30) {
return '二十' + arr[num[1]]
}else if (num === 30) {
return '三十'
}else if (num > 30) {
return '三十' + arr[num[1]]
}
}
return year + '年' + getChs(valArr[1]) + '月' + getChs(valArr[2]) + '日'
// valArr[1]遍歷月份,然后作為參數(shù)傳入函數(shù)里面
}
var str1 = getChsDate('2015-01-08')
var str2 = getChsDate('2016-11-24')
console.log(str1) // 二零一五年一月八日
console.log(str2) //二零一六年十一月二十四日
方法3:
function changeZh(str){
str+=''; //將數(shù)字變?yōu)樽址? var days = ['零','一','二','三','四','五','六','七','八','九','十'];
var outstr='';
for(var i=0;i<str.length;i++){
outstr+= days[(str[i])];
}
return outstr;
}
function getChsdate(datestr){
var d= new Date(datestr);
return changeZh(d.getFullYear())+'年'+changeZh(d.getMonth()+1)+'月'+changeZh(d.getDate())+'日';
}
console.log(getChsdate('2016-09-12'))
3.寫一個函數(shù)獲取n天前的日期
var lastWeek = getLastNDays(7); // ‘2016-01-08’
var lastMonth = getLastNDays(30); //'2015-12-15
function getLastNDays(val){
var lastDay = [];
var d = new Date(Date.now()-val*24*60*60*1000);
//關(guān)鍵是這,這里的時間間隔得到的是本地時間的字符串
lastDay[0]=d.getFullYear();
lastDay[1]=d.getMonth();
lastDay[2]=d.getDay();
return lastDay.join('-');
//最后將得到的時間數(shù)字數(shù)組轉(zhuǎn)化為字符串形式
}
var lastWeek = getLastNDays(7);
console.log(lastWeek);
var lastMonth = getLastNDays(30);
console.log(lastMonth);

4.完善如下代碼,用于獲取執(zhí)行時間如:
var Runtime = (function(){
//code here ...
var obj = {
start: function(){
//code here ..., 當(dāng)前時間
},
end: function(){
//code here ... 結(jié)束時間
},
get: function(){
//code here ... 獲取執(zhí)行時間
}
};
return obj;
}());
Runtime.start();
//todo something
Runtime.end();
console.log( Runtime.get() );
var Runtime = (function(){ //這是一個立即執(zhí)行函數(shù)
var obj = {
start: function(){
startTime = Date.now(); //當(dāng)前時間
return startTime;
},
end: function(){
endTime = Date.now(); //結(jié)束時間
return endTime;
},
get: function(){
return endTime-startTime //獲取執(zhí)行時間
}
};
return obj;
}());
Runtime.start();
//因為立即執(zhí)行函數(shù)返回的是obj對象,相當(dāng)于var Runtime=obj,
//所以obj.start();等同于Rumtime.start()
for(var i=0;i<1000;i++){
console.log(1);
}
Runtime.end();
console.log( Runtime.get() ); //用時348毫秒
5.樓梯有200級,每次走1級或是2級,從底走到頂一共有多少種走法?用代碼(遞歸)實現(xiàn)。
找規(guī)律:
1.走1級樓梯 :(1); 有1種方法
2.走2級樓梯:(1,1)/(2); 有2種方法
3.走3級樓梯:(1,1,1)/(1,2)/(2,1); 有3種方法
4.走4級樓梯:(1,1,1,1)/(1,1,1,2)/(1,1,2,1)/(1,2,1,1)/(2,1,1,1); 有5種方法
.....
依次類推 走n級樓梯就是(n-2)+(n-1)
function getStep(n){
var result = 0;
if(n === 1){
result = 1;
}else if (n === 2) {
result = 2;
}else{
result = getStep(n - 1) + getStep(n - 2);//這里就是遞歸方法
}
return result;
}
console.log(getStep(3));
console.log(getStep(4));
console.log(getStep(5));

6.寫一個json對象深拷貝的方法,json對象可以多層嵌套,值可以是字符串、數(shù)字、布爾、json對象中的任意項。
<script>
var json ={
"name":"xiaoming",
"age":13,
"sex":"male",
"speciality":{
"sport":"basketball",
"literature":"sing",
"suject":"math"
}
}
function jsonCopy(val){ //var val=json
var newJson={};
for(var key in val){//使用for in的作用是遍歷對象
if(typeof( val[key] ) === "object"){//如果json里面有多層嵌套的對象,就用遞歸再次調(diào)用
newJson[key] = jsonCopy( json[key] );//將嵌套的對象里面的內(nèi)容復(fù)制到新的對象里面
}else{
newJson[key] = val[key]; //將原來的對象遍歷后復(fù)制到新的對象里面去
}
}
return newJson;
}
var newJson1=jsonCopy(json)
console.log(newJson1);
</script>
