废话先说
最近投了数多简历,大都了无音讯,昨天有幸收到了新蛋集团的面试电话,在今天上午进行了电话面试,面试的小哥十分和蔼,声音听起来很舒服,也特别有耐心,可惜自己回答的并不好,结果就顺其自然吧。
但是通过这次面试,我对自己的了解加深了不少,一是自己除了前端基础的知识之外,对于网络协议及算法方面的知识了解太少,二是对于自己知道的知识无法准确描述。
在这先整理下自己这次面试的问题,并打算对自己的不足之处进行巩固加强,不要再错过本可以抓住的机会了。
正文开始
问题一:简单介绍一下闭包
1.概念:闭包就是有权访另一个函数作用域中变量的函数。 如:
function a(){
var m=3 ;
function b(){
console.log(m);
console.log('string');
};
return b;
}
var result=a();
result(); //3 'string'
上面的函数a和b就构成了一个闭包。在全局中执行函数b中可以引用a中的变量m。
2.特性:
- 函数嵌套函数;
- 函数内部可以引用函数外部的参数和变量;
- 函数变量和参数不会被垃圾回收机制回收;
3.优缺点:
优点
- 希望一个变量长期驻扎在内存中
- 避免全局变量的污染
- 私有成员的存在
缺点
- 常驻内存,增大内存使用量,使用不当回造成内存泄漏;
4.自执行函数的好处
- 隔离作用域,避免全局作用域污染
- 模拟块级作用域
问题二:判断下面函数是不是闭包,有什么问题吗?
function a(){
var m=3;
function b(){
console.log(m);
};
function c(){
console.log('string');
};
return b;
}
var result=a();
result();
它是一个闭包,但是闭包是b而不是c,因为只是返回了b.
问题三:描述一下原型链
1.原型:
每个函数都会默认有一个prototype属性,它是一个指针,指向此函数的原型对象。而构造函数作为一个函数,同样拥有自己的原型对象,而通过构造函数生成的对象实例中,拥有一个_proto_ 属性,它指向构造函数的原型对象,我们把构造函数的原型对象称为对象实例的原型。
如图:person就是构造函数,而Person prototype原型对象,也是对象实例person1的原型,此实例会继承所有存在它原型中的所有属性及方法。
原型链
既然每个实例对象都有一个原型,而每个构造函数也都能创建实例,那假如我们将构造函数 f1 的原型属性指向构造函数f2的实例对象,那么构造函数f1的实例对象就能访问f2的原型属性,依次类推,我们还可以把构造函数f3的原型属性指向f2的队实例对象,那么f3的实例对象同样可以访问到f1的原型,这样,就构成了一条原型链。
如图:从上到下依次讲解,首先,原型链的顶端是Object prototype
,它的_proto_ 属性为 ,接下来看构造函数SuperType
,它的prototype属性指向的是原型对象SuperType prototype
,这个原型对象其实是Object的一个实例对象,因为它的_proto_ 属性指向Object prototype
,因此,SuperType
的实例属性可以访问Object prototype
中的属性与方法。
同理,我们通过SubType.prototype=new SuperType()
,可以将subType的原型对象指向为SuperType的一个实例对象,这样SubType 的实例对象instance通过原型链可以访问到上面三个原型中的合法属性与方法。
问题四:关于setTimeout()
首先关于setTimeout()我的理解为:
JavaScript引擎是单线程运行的,浏览器无论在什么时候都只且只有一个线程在运行JavaScript程序。
意思就是只要是setTimeout中的代码,执行时间总是要等到其他线程结束后才执行。
题目:
setTimeout(console.log('a'),0)
console.log('c');
的输出顺序;
我答的是先输出c后输出a,时候在浏览器里运行发现并不是按照我想的那样,结果是按顺序输出的。后来又试了其他情况才发现自己以前的理解有偏差。
setTimeout(a,0);
console.log('b');
function a(){
console.log('a')
}
//此时输出顺序为 b, a;
setTimeout(a(),0);
console.log('b');
function a(){
console.log('a')
};
//此时输出顺序为 a,b;
这样下来就发现题目中的写法其实并没有用到setTiemout()的知识,当程序运行到它时他会立刻给出结果而不需要等待。另外,这样一来setTimeout也就没有作用了,在实际开发中这种写法是不正确的。