持续做你不会做的事。。
问答
1.基础类型有哪些?复杂类型有哪些?有什么特征?
- 基础类型
基础类型包括:string、boolean、number、null、undefined。简单数据类型是保存在栈内存(连续的)当中的简单数据段,它在内存中具有固定大小,存储的是数据的具体值。
它进行复制时,不会改变原来的值,而是在变量对象上形成一个新值,然后把该值复制到为新值分配的内存上。 - 复杂类型
复杂类型是除了上面提到的几种数据类型,包括对象、数组、函数、正则等。它指的是那些保存在堆内存中的对象,变量中保存的实际上只是一个指针,这个指针执行内存中的另一个位置,由该位置保存对象。
所以当一个变量向另一个变量复制引用类型的值时,两个变量实际上将引用同一个对象。因此,改变其中一个变量,会影响到另一个变量。
举例说明一下:
var a = 1;
var b = a;
a = 2;
console.log(b) //1,复制基本类型值
var obj1 = {name: 'kevin', sex: 'male'},
obj2 = obj1;
obj1.name = 'xiaoming';
console.log(obj2.name); //"xiaoming"
上面的代码其实可以这么解释,a和b是基本类型,它们的值存在连续的栈内存中,相互没有影响。而复杂类型复制时,它们是指向同一个堆内存地址,所以相互会有影响。
我们再来稍微改变一下:
var obj1 = {name: 'kevin', sex: 'male'},
obj2 = obj1;
obj1.name = 'xiaoming';
console.log(obj2.name);
obj1 = {} //把一个空对象给obj1
obj1.name = 'hunger'
console.log(obj2.name) //"xiaoming"
它的结果其实还是不会变的因为obj1只是指向了另外一个地址,如下图所示。
2.如下代码的输出? 为什么?
var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2};
console.log(obj1 == obj2);
console.log(obj1 = obj2);
console.log(obj1 == obj2);
var obj1 = {a:1, b:2};
var obj2 = {a:1, b:2}; //obj1和obj2内容一样,但它们是不同的对象,所以地址不同
console.log(obj1 == obj2); //obj1和obj2指向的地址不同,所以这里输出:false。
console.log(obj1 = obj2); //把obj2复制给obj1,因为它们是引用类型,所以指向同一个地址。输出:Object {a: 1, b: 2}
console.log(obj1 == obj2); //因为它们指向的地址相同,所以,输出:true。
代码
1.写一个函数getIntv
,获取从当前时间到指定日期的间隔时间。
var str = getIntv("2016-01-08");
console.log(str); // 距除夕还有 20 天 15 小时 20 分 10 秒
实现方式:
function getIntv(val) {
var space = Date.parse(val) - Date.now()
var day = Math.floor(space/(24*60*60*1000))
var hour = Math.floor((space - day*24*60*60*1000)/(60*60*1000))
var minute = Math.floor((space - day*24*60*60*1000 - hour*60*60*1000)/(60*1000))
var second = Math.floor((space - day*24*60*60*1000 - hour*60*60*1000-minute*60*1000)/1000)
return '距离中秋还有 ' + day + ' 天 ' + hour + ' 小时 ' + minute + ' 分 ' + second + ' 秒 '
}
var str = getIntv("2016-09-15");
console.log(str); //距离中秋还有 25 天 22 小时 33 分 47 秒
然后尝试了一下下面的方法,但是没有得到正确的结果,不知道是什么原因,具体还不知道怎么解决。
function getIntv(val) {
var space = new Date(Date.parse(val) - Date.now())
var year = space.getFullYear() - 1970
var month = space.getMonth() + 1 //getMonth返回的月份是从0开始的
var day = space.getDay()
var hour = space.getHours()
var minute = space.getMinutes()
var second = space.getSeconds()
return '距离中秋还有 ' + year + ' 年 ' + month + ' 月 ' + day + ' 天 ' + hour + ' 小时 ' + minute + ' 分 ' + second + ' 秒 '
}
var str = getIntv("2016-09-15");
console.log(str);
2.把数字日期改成中文日期
var str = getChsDate('2015-01-08');
console.log(str); // 二零一五年一月八日
实现方式:
function getChsDate(val) {
var arr = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
var valArr = val.split('-') //数组
var year = []
for (var i = 0; i < valArr[0].length; i++) {
year += arr[valArr[0][i]]
}
function getChs(num) {
if (num < 10) {
return arr[num[1]]
}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]) + '日'
}
var str1 = getChsDate('2015-01-08')
var str2 = getChsDate('2016-11-24')
console.log(str1) // 二零一五年一月八日
console.log(str2) //二零一六年十一月二十四日
3.写一个函数获取n天前的日期
var lastWeek = getLastNDays(7); // ‘2016-01-08’
var lastMonth = getLastNDays(30); //'2015-12-15'
实现方式:
function getLastNDays(val) {
var nDay = []
var date = new Date(Date.now() - val*24*60*60*1000)
nDay[0] = date.getFullYear()
nDay[1] = date.getMonth() + 1 //获取的月份是从0开始的
nDay[2] = date.getDate()
return nDay.join('-')
}
var today = getLastNDays(0) //2016-8-21
var lastWeek = getLastNDays(7); // 2016-8-14
var lastMonth = getLastNDays(30); //2016-7-22
4.完善如下代码,用于获取执行时间如:
var Runtime = (function(){
//code here ...
var obj = {
start: function(){
//code here ..., 当前时间
},
end: function(){
//code here ... 结束时间
},
get: function(){
//code here ... 获取执行时间
}
};
return obj;
}());
Runtime.start();
//todo something
Runtime.end();
console.log( Runtime.get() );
实现方式:
var Runtime = (function(){
var startTime
var endTime
var obj = {
start: function(){
startTime = Date.now() //当前时间
return startTime
},
end: function(){
endTime = Date.now() //结束时间
return endTime
},
get: function(){
return endTime - startTime//获取执行时间
}
};
return obj;
}());
Runtime.start();
for (var i = 0; i< 10000; i++) {
console.log(1)
}
Runtime.end();
console.log( Runtime.get() ); //1440
5.楼梯有200级,每次走1级或是2级,从底走到顶一共有多少种走法?用代码(递归)实现。
递归:优点,代码简单、作用却很强大;缺点,执行效率差,复杂度比普通方式高很多。
- 利用递归思想:
- 只有一个台阶: (1) //1
- 两个台阶: (2)、(1,1) //2
- 三个台阶: (1,2)、(2,1)、(1,1,1) //3
- 四个台阶:(2,2)、(1,1,2)、(1,2,1)、(2,1,1)、(1,1,1,1) //5
...
以此类推,n级台阶就是f(n-1)+f(n-2)种走法。
- 或者还可以这么想:
比如有n个台阶,第一次走的时候有两种可能:第一,走一步,那么接下来还有f(n-1)种可能;第二,走两步,那么还有f(n-2)种可能。所以总的方法应该为:
function f(n) {
return f(n-1) + f(n-2)
}
然后再加上停止递归的条件,就是n为1和n为2的时候,就可以了。
实现方式:
function goSteps(n) {
if (n === 1) {
return 1
}else if (n === 2) {
return 2
}else {
return goSteps(n-1) + goSteps(n-2)
}
}
var stepNum = goSteps(200) //复杂度O(2^n),也就是2^200,复杂度太高,所以无法计算出来。测试了简单数据是正确的。
6.写一个json对象深拷贝的方法,json对象可以多层嵌套,值可以是字符串、数字、布尔、json对象中的任意项。
function jsonCopy(val) {
var newJson = {}
for (var key in val) {
if (typeof val[key] === 'object') {
newJson[key] = jsonCopy(val[key]) //如果json里面有多层嵌套对象,则用递归再次调用。
}else {
newJson[key] = val[key]
}
}
return newJson
}
var json = {
"age": 24,
"name": "cttin",
"address": {
"school": "Nanjing University of Posts and Telecommunications",
"city": "Nan Jing"
}
} //json数据要严格按照它的语法来,否则会报错,我一开始就是没写好,一直报错。
console.log(jsonCopy(json))