一回季、問(wèn)答
1.基礎(chǔ)類型有哪些家制?復(fù)雜類型有哪些?有什么特征泡一?
①基礎(chǔ)類型包括:number,boolean,string,null,undefinded慰丛。
②復(fù)雜類型包括:指的是由多個(gè)值構(gòu)成的對(duì)象,有對(duì)象瘾杭、函數(shù)诅病、數(shù)組、正則等粥烁。
基礎(chǔ)類型
①基礎(chǔ)類型指的是保存在棧內(nèi)存(連續(xù)的)中的簡(jiǎn)單數(shù)據(jù)段贤笆,它在內(nèi)存中具有固定大小,存儲(chǔ)的是數(shù)據(jù)的具體值讨阻;基本類型的訪問(wèn)是按值訪問(wèn)的芥永,可以操作保存在變量中的實(shí)際的值。
②它進(jìn)行復(fù)制時(shí)钝吮,會(huì)在該變量上創(chuàng)建一個(gè)新值埋涧,然后再把該值復(fù)制到為新變量分配的位置上。
基本類型的特征:
1.基本類型的值是不可變的奇瘦;
2.基本類型的比較是值的比較棘催;
3.基本類型的變量是存放在棧內(nèi)存復(fù)雜類型
復(fù)雜類型指的是保存在堆內(nèi)存中的對(duì)象,意思是耳标,變量中保存的實(shí)際上只是一個(gè)指針醇坝,這個(gè)指針指向內(nèi)存中的另一個(gè)位置,由該位置保存對(duì)象次坡。
復(fù)雜類型的特征
1.引用類型的值是可變的呼猪;
2.基本類型的比較是內(nèi)存地址的比較;
3.引用類型的值是同時(shí)保存在棧內(nèi)存和堆內(nèi)存中的對(duì)象砸琅,棧區(qū)內(nèi)存保存變量標(biāo)識(shí)符和指向堆內(nèi)存中該對(duì)象的指針宋距,也可以說(shuō)是該對(duì)象在堆內(nèi)存的地址。總結(jié):JS里基本類型(值)和復(fù)雜類型(引用)有什么區(qū)別症脂?
①基本類型變量存的是值谚赎,復(fù)雜類型的變量存的是內(nèi)存地址。
②基本類型在賦值的時(shí)候拷貝值摊腋,復(fù)雜類型在賦值的時(shí)候只拷貝地址沸版,不拷貝值。
Reference
基本類型 引用類型 簡(jiǎn)單賦值 對(duì)象引用
舉例說(shuō)明:
1.基礎(chǔ)類型
var a = 1;
var b = a; //將a里面的內(nèi)容賦給b兴蒸,所以b=1,
a = 2; //將a改為2了细办,但b里面沒(méi)有改變橙凳。a蕾殴,b是簡(jiǎn)單類型,它們之間是相互獨(dú)立的
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)存中對(duì)象的屬性值
console.log(obj2.name); //xiaoming
上面的復(fù)雜類型改變一下岛啸;
var obj1 = {name:'hunger',sex:'male'};
obj2 = obj1;
obj1.name = 'xiaoming'
console.log(obj2.name); //xiaoming
obj1 = {}; //obj1開(kāi)辟了一個(gè)新的空間钓觉,并且指向這個(gè)空間
console.log(obj1,obj2) //obj2還是指向原來(lái)的空間
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,然后指向同一個(gè)地址瞬铸,返回obj1所指向的對(duì)象批幌,如圖2
console.log(obj1 == obj2);
//obj1和obj2的內(nèi)存地址相同,所以true
打印結(jié)果
圖1
圖2
二嗓节、代碼
1.寫一個(gè)函數(shù)getIntv荧缘,獲取從當(dāng)前時(shí)間到指定日期的間隔時(shí)間
var str = getIntv("2016-01-08");
console.log(str); // 距除夕還有 20 天 15 小時(shí) 20 分 10 秒
function getIntv(val){
var timeline = Date.parse(val)-Date.now()
//這樣寫是它們之間的間隔時(shí)間,用毫秒數(shù)來(lái)表現(xiàn)的
var day = Math.floor(timeline/(24*60*60*1000))
//這樣寫是間隔時(shí)間除以一天的毫秒數(shù)拦宣,得到的是多少天的時(shí)間截粗,例如10.333,然后通過(guò)Math.floor取10鸵隧。
var hour = Math.floor((timeline-day*24*60*60*1000)/(60*60*1000))
//這樣寫時(shí)間隔時(shí)間減去整數(shù)天的毫秒數(shù)就是剩下的毫秒數(shù)绸罗,也就是上面取10天之后剩下的小數(shù)點(diǎn)的時(shí)間,
//然后再除以小時(shí)的毫秒數(shù)豆瘫,然后取整數(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 "距離國(guó)慶還有"+day+"天"+hour+"小時(shí)"+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ù)時(shí)間時(shí),返回本地時(shí)間的字符串形式靡羡,
//例如:var Jan02_1970 = new Date(3600*24*1000);
//Fri Jan 02 1970 08:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)
var yeardate = d.getFullYear().toString().split("");
//d 時(shí)間對(duì)象傳遞了參數(shù)系洛,然后獲取的年份是所傳遞參數(shù)時(shí)間的年份,
//例如Jan02_1970.getFullYear()
//1970
var year = '';
for(var i = 0;i <yeardate.length; i++){
year += arr[yeardate[i]];
//這里是遍歷數(shù)組yeardate,然后將遍歷出來(lái)的數(shù)字成了arr數(shù)組的索引略步,再得到arr數(shù)組里面的實(shí)際值描扯,
//最后賦值給year。
//注意:arr['1']會(huì)轉(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,然后得到實(shí)際的值杭煎,
//然后作為arr數(shù)組的下標(biāo)恩够,最后得到arr數(shù)組下標(biāo)對(duì)應(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.寫一個(gè)函數(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)鍵是這羡铲,這里的時(shí)間間隔得到的是本地時(shí)間的字符串
lastDay[0]=d.getFullYear();
lastDay[1]=d.getMonth();
lastDay[2]=d.getDay();
return lastDay.join('-');
//最后將得到的時(shí)間數(shù)字?jǐn)?shù)組轉(zhuǎn)化為字符串形式
}
var lastWeek = getLastNDays(7);
console.log(lastWeek);
var lastMonth = getLastNDays(30);
console.log(lastMonth);
4.完善如下代碼蜂桶,用于獲取執(zhí)行時(shí)間如:
var Runtime = (function(){
//code here ...
var obj = {
start: function(){
//code here ..., 當(dāng)前時(shí)間
},
end: function(){
//code here ... 結(jié)束時(shí)間
},
get: function(){
//code here ... 獲取執(zhí)行時(shí)間
}
};
return obj;
}());
Runtime.start();
//todo something
Runtime.end();
console.log( Runtime.get() );
var Runtime = (function(){ //這是一個(gè)立即執(zhí)行函數(shù)
var obj = {
start: function(){
startTime = Date.now(); //當(dāng)前時(shí)間
return startTime;
},
end: function(){
endTime = Date.now(); //結(jié)束時(shí)間
return endTime;
},
get: function(){
return endTime-startTime //獲取執(zhí)行時(shí)間
}
};
return obj;
}());
Runtime.start();
//因?yàn)榱⒓磮?zhí)行函數(shù)返回的是obj對(duì)象也切,相當(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() ); //用時(shí)348毫秒
5.樓梯有200級(jí)腰湾,每次走1級(jí)或是2級(jí),從底走到頂一共有多少種走法疆股?用代碼(遞歸)實(shí)現(xiàn)费坊。
找規(guī)律:
1.走1級(jí)樓梯 :(1); 有1種方法
2.走2級(jí)樓梯:(1,1)/(2); 有2種方法
3.走3級(jí)樓梯:(1,1,1)/(1,2)/(2,1); 有3種方法
4.走4級(jí)樓梯:(1,1,1,1)/(1,1,1,2)/(1,1,2,1)/(1,2,1,1)/(2,1,1,1)旬痹; 有5種方法
.....
依次類推 走n級(jí)樓梯就是(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.寫一個(gè)json對(duì)象深拷貝的方法附井,json對(duì)象可以多層嵌套,值可以是字符串两残、數(shù)字永毅、布爾、json對(duì)象中的任意項(xiàng)磕昼。
<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的作用是遍歷對(duì)象
if(typeof( val[key] ) === "object"){//如果json里面有多層嵌套的對(duì)象卷雕,就用遞歸再次調(diào)用
newJson[key] = jsonCopy( json[key] );//將嵌套的對(duì)象里面的內(nèi)容復(fù)制到新的對(duì)象里面
}else{
newJson[key] = val[key]; //將原來(lái)的對(duì)象遍歷后復(fù)制到新的對(duì)象里面去
}
}
return newJson;
}
var newJson1=jsonCopy(json)
console.log(newJson1);
</script>