我出的这套基础题,面试(当面答题,想百度是不存在的)好多人,状况都比较差,没有令我满意的,是我出题太难了么? javascript
当咱们想要从 object 中读取一个缺失的属性时,js 会自动从原型中获取它
举例:
const animal = {
eats: true,
sleep: true,
voice: '',
bark(){
console.log(this.voice);
},
}
const dog = {
run: true,
voice: 'wang~~ wang~~',
}
dog.__proto__ = animal;
console.log(dog.run) // true
console.log(dog.eats) // true
console.log(dog.bark()) // wang~~ wang~~
console.log(dog.sleep) // true
总结:
全部的对象都有一个隐藏的 [[Prototype]] 属性,它能够是另外一个对象或者 null。
可使用 obj.__proto__ 进行访问。
[[Prototype]] 引用的对象称为“原型”。
要读取 obj 属性或者调用一个方法,并且它不存在,那么就会尝试在原型中查找它。
写/删除直接在对象上进行操做,它们不使用原型(除非属性其实是一个 setter)。
咱们调用 obj.method(),并且 method 是从原型中获取的,this 仍然会引用 obj。
方法重视与当前对象一块儿工做,即便它们是继承的。
扩展:
构造函数继承、组合继承、寄生继承、寄生组合式继承。
复制代码
防抖:
连续触发的事件(高频),在单位时间T内只执行最后一次,
若在T内再次触发,则清空定时从新计算。场景:模糊搜索
节流:
连续触发的事件(高频),在单位时间T内只执行一次。窗口滚动,获取滚动条top
复制代码
若子域同源,则能够经过设置document.domain将窗口视为同源站点,进行通讯,
例如本地储存等等方式。
若不一样源,咱们能够在经过 postMessage(data,targetOrigin) 这个接口,进行跨窗口通讯。
复制代码
css
点击劫持: 容许恶意网页以用户的名义点击 “受害站点”。 一般恶意网页在受害网站连接之上放置一个透明 <iframe> 标签。 防范: 服务端 header 字段 X-Frame-Options 可以容许或禁止 frame 内页面的显示。 复制代码复制代码
链表(Linked list)是一种常见的基础数据结构,是一种线性表,
可是并不会按线性的顺序储存数据,而是在每个节点里存到下一个节点的指针(Pointer)。
因为没必要须按顺序储存,链表在插入的时候能够达到 o(1)的复杂度,比另外一种线性表顺序表快得多,
可是查找一个节点或者访问特定编号的节点则须要 o(n)的时间,而顺序表响应的时间复杂度分别是 o(logn)和 o(1)。
特色:
无需预先分配内存,能够充分利用计算机内存空间,实现灵活的内存动态管理
插入/删除节点不影响其余节点
随机访问速度较慢
增长告终点的指针域,空间开销比较大
单向链表:
是链表中最简单的一种,它包含两个域,一个信息域和一个指针域。
这个连接指向列表中的下一个节点,而最后一个节点则指向一个空值。
应用:
git commit、es6的Iterator、react的fiber算法。
复制代码
前端路由(spa)纯浏览器行为,是由浏览器控制的(hash、history),
当打开一个spa页面后,切换路由,浏览器改变地址栏url并经过js展现对应页面(组件)
后端路由,切换路由时,服务端会去匹配并查找对应资源,返回给浏览器并渲染。
复制代码
本题相对开放一些。
webpack我的理解:
webpack是划时代的,比较完美解决了前端模块依赖的问题,任何资源都是js,任何资源均可以在js中声明依赖,
真正实现了通用的模块化开发。
loader的设计原则:
单一职责、全部模块都是js模块,webpack 只支持js模块,全部其余类型的模块,
好比图片,css等,都须要经过对应的loader转成js模块。
因此在webpack中不管任何类型的资源,本质上都被当成js模块处理。
全部的loader都是一个管道,能够把一个loader看作是一个数据管道,
进口是一个字符串,而后通过加工,输出另外一个字符串。
复制代码
function transform(arr,num){
const newArr = [];
for(let i=0,len=arr.length;i < len;i=i+num){
newArr.push(arr.slice(i,i+num));
}
return newArr;
}
复制代码
function slow(x,y,z) {
// 这里可能会有重负载的CPU密集型工做
// ...
alert(`Called with ${XYZ}`);
return XYZ;
}
复制代码
function memo(func){
const cache = new Map();
return function(){
// const key = [...arguments].join(',');
const key = [].join.call(arguments);
if(cache.has(key)){
return cache.get(key);
}
const res = func.apply(this, arguments);
cache.set(key, res);
return res;
}
}
memo(slow)(1,2,3);
复制代码
前端
class Event{ constructor(){ this.pool = new Map() } broadcast(){ const [key,...rest] = [...arguments]; if(this.pool.has(key)){ const func = this.pool.get(key) func.apply(this, rest) } } addEventListenering(key, func){ this.pool.set(key,func) } removeEventListenering(key){ this.pool.delete(key) } } const ev = new Event(); ev.addEventListenering('event1',function(param){ console.log('发布新值了',param) }) ev.broadcast('event1',1000); //发布新值了 1000 ev.broadcast('event1',2000); //发布新值了 2000 ev.broadcast('event1',3000); //发布新值了 3000 ev.removeEventListenering('event1'); ev.broadcast('event1',3000); 复制代码复制代码
function A() {
this.a = 1;
}
A.prototype.b = 1;
const a = new A();
console.log(a.a);
console.log(a.b);
const b = new A();
b.__proto__.a = 2;
A.prototype.b = 2;
console.log(a.a);
console.log(a.b);
复制代码
1 1 1 2复制代码
var name = '小红';
var obj = {
name: '小明',
sayName() {
console.log(`${this.name}`);
},
};
var sayName = () => {
console.log(`${this.name}`);
};
var fn = obj.sayName;
sayName();
obj.sayName();
sayName.call(obj);
obj.sayName.call(this);
fn();
复制代码
小红 小明 小红 小红 小红复制代码
new Promise((resolve) => {
console.log(3);
resolve();
}).then(() => {
onsole.log(4);
});
setTimeout(() => {6
console.log(2);
}, 0);
Promise.resolve().then(() => {
console.log(5);
});
console.log(1);
复制代码
3 1 4 5 2复制代码