前端基础
浏览器
- 浏览器的缓存机制:强缓存与协商缓存,以及其区别是什么?
- 存储相关:localstorage、sessionStorage、cookie等分别是做什么用的,区别是什么?
- 浏览器的network面板里面的东西,主要是timing下面的时间段代表的都是什么意思?TTFB是什么?
- 浏览器的performance用过吗,是用来干什么的?
- 跨域的原理,跨域的实现方式有哪几种?
浏览器环境下的event loop是怎样的?其实也就是宏任务和微任务,可以看下这篇文章
JavaScript
基础数据类型和引用数据类型
- 基础数据类型:Undefined、Null、Boolean、String、Number、Symbol
- 引用数据类型:Object、Array、Date、RegExp、Function
- 此处可能会考察,typeof、instanceof;包括手动实现以下typeof和instanceof
// 实现typeof
function type(obj) {
return Object.prototype.toString.call(a).slice(8,-1).toLowerCase();
}
复制代码
// 实现instanceof
function instance(left,right){
left=left.__proto__
right=right.prototype
while(true){
if(left==null)
return false;
if(left===right)
return true;
left=left.__proto__
}
}
原型链
理解原型链是做什么的,也就是:实例.proto === 构造函数.prototype
Object.prototype.__proto__ === null // true
Function.prototype.__proto__ === Object.prototype // true
Object.__proto__ === Function.prototype // true
有个比较好的问题,可以思考下:
function F() {
}
Object.prototype.b = 2;
Function.prototype.a = 1;
var f = new F();
console.log(f.a) // 1
console.log(f.b) // 2
console.log(F.a) // undefined
console.log(F.b) // 2
上面代码,为什么F.a是undefined?
function F() {
}
Object.prototype.b = 2;
Function.prototype.a = 1;
var f = new F();
console.log(f.a) // undefined
console.log(f.b) // 2
console.log(F.a) // 1
console.log(F.b) // 2
上面代码,为什么f.a是undefined?
function F() {
}
F.prototype.a = 1;
var f1 = new F()
F.prototype = {
a: 2
}
var f2 = new F()
console.log(f1.a) // 1
console.log(f2.a) // 2
继承
继承的几种方式:
- 原型链继承:
function SuperType() {
this.name = 'Yvette';
this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.getName = function () {
return this.name;
}
function SubType() {
this.age = 18;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
let instance1 = new SubType();
instance1.colors.push('yellow');
console.log(instance1.getName());
console.log(instance1.colors); // ['red', 'blue', 'green', 'yellow']
let instance2 = new SubType();
console.log(instance2.colors); // ['red', 'blue', 'green', 'yellow']
缺点:
- 通过原型来实现继承时,原型会变成另一个类型的实例,原先的实例属性变成了现在的原型属性,该原型的引用类型属性会被所有的实例共享。(引用类型值被所有实例共享)
- 在创建子类型的实例时,没有办法在不影响所有对象实例的情况下给超类型的构造函数中传递参数
构造函数继承:
function SuperType(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
function SubType(name) {
SuperType.call(this, name);
}
let instance1 = new SubType('draven');
instance1.colors.push('yellow');
console.log(instance1.colors); // ['red', 'blue', 'green', 'yellow']
let instance2 = new SubType('ben');
console.log(instance2.colors); // ['red', 'blue', 'green']
优点:
- 可以向超类传递参数
- 解决了原型中包含引用类型值被所有实例共享的问题 缺点:
- 方法都在构造函数中定义,函数复用无从谈起。
- 超类型原型中定义的方法对于子类型而言都是不可见的。
组合继承:
function SuperType(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function () {
console.log(this.name);
}
function SuberType(name, age) {
SuperType.call(this, name);
this.age = age;
}
SuberType.prototype = new SuperType()
SuberType.prototype.constructor = SuberType
let instance1 = new SuberType('draven', 25);
instance1.colors.push('yellow');
console.log(instance1.colors)