唉,我仍是前端小渣渣一个。javascript
是一家云服务产品公司,面试流程也比较简单,前端负责人拿了一块白板和记号笔,心想一会要手写代码了。。。。前端
不过这种面试方式仍是不错的。java
去以前觉得本身准备的差很少,其实准备的远远不够充足啊。react
一开始通常会让你进行一个简单的自我介绍,我就主要说了一下上家公司的工做经历,描述了一下我负责过的项目,每一个项目的业务功能,主要详细介绍每一个项目用到的技术。面试
虽然我说了不少,可是过后以为我在表达的时候,语言的条理性、逻辑性、准确性都不是很好,表达能力的强弱也是面试官比较看中的一部分,毕竟有可能之后和他共事交流工做内容,探讨技术等,因此,自我介绍这一块,以为也挺重要的,自我介绍表明了面试官对你的第一印象,即使你面试不少次了,也说过不少次了,这方面仍是应该好好梳理下本身的语言。redux
接下来考察js了,面试官慢慢的拿起了他的小白板,个人内心默默的有点小紧张。。。。数组
考察方式也比较中规中矩,按照js里的大类挨个考察。bash
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}复制代码
“咦?。。。,上一次的面试不是也碰到了这个?”闭包
而后我淡定的说出了答案:框架
“setTimeout
函数会延迟执行,那么等到执行console.log()
的时候,i
已经变成5了,因此最后会一次性打印出5个5;”
问:“那我要输出0~4呢?”
“怎么也有这个问题?是否是要问我有几种改法。。。”
我直接说var
改为let
就能够了
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i);
}, 1000);
}复制代码
或者加个闭包:
for (var i = 0; i < 5; i++) {
(function(i) {
setTimeout(function() {
console.log(i);
}, 1000);
})(i)
}
复制代码
或者这样:
for(var i = 1;i < 5;i++){
var a = function(){
var j = i;
setTimeout(function(){
console.log(j);
},1000)
}
a();
}复制代码
这也是用了闭包的方法,其实就至关于把var化成了let效果同样,这样i的值一开始不会被默认绑定,每执行一次循环的时候都会给i赋予新值。
问:“若是去掉function
里的 i
呢?”
“这样其实对内存没有保持引用, i 最后仍是5。”
因为相似的面试题频繁遇到,整理了一些相关的面试题:
好比这个:
for (var i = 0; i < 5; i++) {
setTimeout((function(i) {
console.log(i);
})(i), i * 1000);
}复制代码
延时函数的第一个参数变成了一个当即执行函数,在这里应该是一个undefined
,等价于:
setTimeout( undefined, … )
;
当即函数会立马执行,因此是立马就输出0~4;
Promise考察:
setTimeout(function() {
console.log(1)}, 0);
new Promise(function executor(resolve) {
console.log(2);
for( var i=0 ; i<10000 ; i++ ) {
i == 9999 && resolve();
}
console.log(3);
}).then(function() {
console.log(4);
});
console.log(5);复制代码
考察运行机制,首先Promise
是异步的,Promise
只有三中状态,pending、fulfilled(成功)、rejected(失败)
,后二者统称为resolve
(已定型),一旦状态定下句就没法再改变。
第一个延时函数首先会设置一个定时,在定时结束后传递这个函数将它放到任务队列中去,所以一开始不会输出1;
Promise
里的函数会按顺序执行,输出2 3 ,Promise
里的then
就是会异步执行,放到当前Promise
任务队列的最后执行,而console.log(5)
是按顺序执行的,因此先输出5,再输出4。Promise.then()
里面的回调属于 microtask, 会在当前 Event Loop 的最后执行, 而 SetTimeout
内的回调属于 macrotask, 会在下一个 Event Loop 中执行
最后,才会输出1。
最后输出: 2 3 5 4 1
先来个最简单的
var obj = {
a: "1"
};
var obj2 = obj;
obj2.a = "2";
console.log(obj.a);复制代码
“确定是输出 2 啊”
ojb2只是对obj实例的一个引用,到最后仍是修改的obj的值。
this指针
name = "name of window";
function show() {
var name = "name in function show()";
alert(this.name);
}
show();复制代码
这里定义了一个全局变量 name
,这个变量是属于 window
的,在 show
函数里也声明了一个name
变量。
this
的定义是指向调用当前函数的那个对象, show()
函数是在全局被调用的,因此this
应该指向的是当前 window
对象。
再看下一个:
var myObj = {
name: " my Object",
show: function() {
var name = "my Object in function";
alert(this.name);
},
};
myObj.show();复制代码
此次,调用 myObj.show()
的对象是 myObj
, 因此就会输出 my Object
先来个排序吧:
var arr = [ 2, 4, 50, 20, 3 ];复制代码
冒泡排序:
var arr = [ 2, 4, 50, 20, 3 ];
for(var i = 0 ; i < arr.length-1; i ++){
for(var j = 0; j < arr.length-i; j++ ){
var ls;
if(arr[j] > arr[j+1]){
ls = arr[j];
arr[j] = arr[j+1]
arr[j+1] = ls
}
}
}
console.log(arr);复制代码
其实我要开始想到的是用sort()
,可是sort
排出来的不是很稳定,他默认排序是根据字符串Unicode码点。
还问我sort有几个参数,第二个参数是什么?
我当时没想起来,后续整理出来吧!
可选参数是一个比较函数, compareFunction
,用来指定按某种顺序进行排列的函数。若是省略,元素按照转换为的字符串的各个字符的Unicode位点进行排序。
compareFunction(a, b)
小于 0 ,那么 a 会被排列到 b 以前;compareFunction(a, b)
等于 0 , a 和 b 的相对位置不变;compareFunction(a, b)
大于 0 , b 会被排列到 a 以前。compareFunction(a, b)
必须老是对相同的输入返回相同的比较结果,不然排序的结果将是不肯定的。要比较数字而非字符串,比较函数能够简单的以 a 减 b,以下的函数将会将数组升序排列
function compareNumbers(a, b) {
return a - b;
}复制代码
因此上边那个排序就能够简单的写成:
var arr = [ 2, 4, 50, 20, 3 ];arr.sort(function (a, b) {
return a - b;
});
console.log(arr);复制代码
或者更简洁一点:
var arr = [ 2, 4, 50, 20, 3 ];
arr.sort((a, b) => a -b );
console.log(arr);复制代码
又给我改了一下,说怎么用sort 来排序一个对象?
var obj = [
{ name: 'a', value: 21 },
{ name: 'b', value: 37 },
{ name: 'c', value: 45 },
{ name: 'd', value: -12 },
{ name: 'e' }
];复制代码
应该是这样:
obj.sort(function (a, b) {
return (a.value - b.value);
});复制代码
零零碎碎的问了很多,其余的记不太清了,都是一些知识性的东西,不罗列了。
而后问了一些react、 redux相关的技术原理,生命周期、单向数据流、虚拟DOM等等。。。
这些我回答的还好,由于工做每天用这个,也比较熟悉,js基础类的一些题回答的不太好,我也知道我js基础不扎实,再者,面试题看少了,虽然这些基础的知识点在工做中用的很少,有的记不清楚的就google了,也不会影响开发进度,可是,即使react 用的再熟练,重中之重的js基础!才是最重要的,框架都是js写的。
反思一下,以前工做中碰到了一些不会的或者生疏不经常使用的技术,google出来答案后直接就用上了,也没有仔细的去研究其中的原理,知其然不知其因此然!
过后也没有总结出来,下次再碰到这个技术点,可能又要google了。。。
不说废话了!
alert(a);
a();
var a=3;
function a(){
alert(10)
}
alert(a);
a=6;
a();
复制代码
果不其然,我本身看一遍的时候就分析错了。
关键的一点就是:var 声明的变量 和function生命的函数都会提早,只是提早到做用域开始的位置,但不会进行赋值操做;
function a(){alert(10)}
,就会看到这个函数。
a()
,执行函数,就是出现
alert(10)
var a=3;
因此
alert(a)
就是显示
3
a
不是一个函数了,因此往下在执行到
a()
的时候, 报错。
再来看:
alert(a);
a();
var a=3;
var a=function(){
alert(10)
}
alert(a);
a=6;
a();
复制代码
区别是,函数此次用var声明了,根据原理,他只是声明被提早,但a 没有被赋值为一个函数,
因此,一开始alert(a) 是undefined
;
a() 报错;
相似的题目:
var a=0;
function aa(){
alert(a);
var a=3;
}
aa();复制代码
在aa函数里面,有var a=3,那么在aa做用域里面,就是把a这个变量声明提早,可是不会赋值,因此是undefined
;
var a=0;
function aa(a){
alert(a);
var a=3;
};
aa(5);
alert(a);
//5,0 复制代码
在函数体内,参数a的优先级高于变量a ;
var a=0;
function aa(a){
alert(a);
a=3;
alert(a);
}
aa();
alert(a);
复制代码
首先没有传参数进去,aa()
是 undefined
;
a=3,实际上修改的是形参a的值,并非全局变量a,往下alert(a)
也是形参a;
最后的alert(a)
; 是全局的a;
不说了!。。。
我要去刷面试题,继续啃个人JavaScript 语言精粹了。