嗯,小白的进击之路,继续来补充了... 又看了一些坑,本身第一次疏忽作错的,仍是用笔记下来,共同进步html
恩,面试系列和排坑会在github更新哦,一块儿准备秋招的小伙伴路过能够star下,一块儿进步O(∩_∩)O~: 传送门git
请问如下输出是什么github
var arr1 = "john".split('');
var arr2 = arr1.reverse();
var arr3 = "jones".split('');
arr2.push(arr3);
console.log("array 1: length=" + arr1.length + " last=" + arr1.slice(-1));
console.log("array 2: length=" + arr2.length + " last=" + arr2.slice(-1));
复制代码
答案:面试
"array 1: length=5 last=j,o,n,e,s"
"array 2: length=5 last=j,o,n,e,s"
复制代码
是的,发现两个输出同样,先说这道题的核心,再好好想一想吧编程
var arr1 = arr2
赋值时,只是浅拷贝,拿到了arr2
的引用,这样带来的问题就是,修改arr1
的时候arr2
也会收到影响。arr1.push(arr2)
,这就是为何有一个函数叫concat
,push
会直接把整个数组push进去,而不会分开搞 搞清楚以上两点,这个题基本上就解开了。如下程序输出是什么?数组
console.log(1 + "2" + "2");
console.log(1 + +"2" + "2");
console.log(1 + -"1" + "2");
console.log(+"1" + "1" + "2");
console.log( "A" - "B" + "2");
console.log( "A" - "B" + 2);
复制代码
答案:bash
"122"
"32"
"02"
"112"
"NaN2"
NaN
复制代码
嗯,核心是如下几点,本身再细细思考闭包
-
+
会隐式转换为Number
类型+
做为运算符出如今String
类型前时,会认为须要字符串拼接,所以会隐式转换为String
Number
包含一个特殊的类型NaN,当对非数字进行Number转换时,会变为这个。第一题: 第二条,认为须要字符串拼接 1被转换为1
,答案122
第二题: 注意到第二个2
前面的+
号,是符合第一条的,所以第二个2
被转换为Number类型,答案为32
第三题: 同理,答案02
第五题: 运用(1)(3),显然是NaN2
,第六题同理异步
下面的代码将会形成栈溢出,请问如何优化,不改变原有逻辑函数
var list = readHugeList();
var nextListItem = function() {
var item = list.pop();
if (item) {
// process the list item...
nextListItem();
}
};
复制代码
答案:
var nextListItem = function() {
var item = list.pop();
if (item) {
// process the list item...
setTimeout(nextListItem,0}
};
复制代码
首先必须搞清楚,堆栈溢出的缘由。
在JS中,不当心的操做或者编程习惯,很容易形成堆栈溢出,特别是进行回调或者循环的时候。 引用如下来讲明溢出的缘由:
缘由是每次执行代码时,都会分配必定尺寸的栈空间(Windows系统中为1M),每次方法调用时都会在栈里储存必定信息(如参数、局部变量、返回值等等),这些信息再少也会占用必定空间,成千上万个此类空间累积起来,天然就超过线程的栈空间了。那么如何解决此类问题?
这里介绍两个思路解决此问题:
显然,这里就是使用的第一种方法,闭包。为何使用setTimeout就能够解决问题?咱们看下与没用以前的差异。若是没有使用setTimeout,那么函数将在大数据前不断的回调,直到最后走到重点,最初的函数才运行结束,释放内存。 可是若是使用了setTimeout
,咱们知道它是异步的,即便设置了时间为0,它也容许先执行下面的内容,能够释放堆栈,从而避免堆栈溢出的问题。 换言之,加了setTimeout
,nextListItem函数被压入事件队列,函数能够退出,所以每次会清空调用堆栈。
闭包 也是同样的道理,由于这道题要求不修改原有逻辑,第一种是最合适的答案,固然用闭包避免的方法就是返回出来一个函数
var nextListItem = function() {
var item = list.pop();
if (item) {
// process the list item...
return nextListItem()
}
};
复制代码
固然,这样作会改变函数的调用方式,咱们就须要不断的调用 nextListItem()()()
为了处理这个办法,能够对其进行进一步的封装
var nextListItem = function() {
var item = list.pop();
if (item) {
// process the list item...
return function() {
return nextListItem()
}
}
};
function autoRun(fun) {
var value = nextListItem();
while(typeof value === 'function') {
value = nextListItem()
}
return
}
复制代码
这样,就解决堆栈溢出的问题。 这里闭包的思路来源与堆栈溢出解决方案
下面函数的输出是什么?
var a={},
b={key:'b'},
c={key:'c'};
a[b]=123;
a[c]=456;
console.log(a[b]);
复制代码
答案: 输出是这样的456
,不是123
,至少我有有点之外...
缘由是什么呢? 这里了解ES6新的数据类型map的应该就会意识到了,没错,对象的key值是只容许String
类型的,这也是为何引入了map数据类型了。 好了,那若是把一个对象做为key值,就会调用toString
方法了。
Object.prototype.toString(obj)
会获得什么呢?没错`[object Object]。 那因此
a[b] ==> a["[object Object"] = 123;
a[b] ==> a["[object Object"] = 456;
复制代码
答案,显而易见
请作一个回文判断的函数,判断是不是回文
答案: 这是一个很简单、很常规的方法。链表是最好的判断回文的方法,固然得益于JS数组的灵活方法,能够更容易实现。
这里主要考虑了一个健壮性的问题,多了一个正则来检测:
function check(str) {
str = str.replace(/\W/g,'').toLowerCase();
return str === str.split('').reverse().join()
}
复制代码