blog
blog copied to clipboard
面试之 js基础
学习
- 这里强烈推荐 冴羽大大的blog,写得很好,回过头去细细看,收获颇多
问题1:
if([2] > 1){console.log('猜猜 我能不能打印出来!')}
new function(){console.log(this)}
问题2:
const foo = {
bar: function () {
console.log(this)
}
}
(foo.bar)(); // {bar: ƒ}
(false || foo.bar)(); // Window
(foo.bar = foo.bar)(); // Window
问题3:
async function async1() {
console.log('async1 start')
await async2();
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
console.log('script start')
setTimeout(function(){
console.log('setTimeout')
}, 0)
async1();
console.log('script end')
问题4: 主要是查看这里
null == undefined
false == undefined
false == null
false == ['']
-
ECMAScript的最新说明:https://tc39.github.io/ecma262/#sec-intro
-
你不知道的js https://github.com/getify/You-Dont-Know-JS
-
关于js中Eventloop 具体看node官方中介绍: https://nodejs.org/es/docs/guides/event-loop-timers-and-nexttick/ 以及浏览器中事件队列与之区别
Number.isNaN ('a') ; // false; | 单纯的判断是不是NaN
isNaN('a'); // true | 判断是不是数字
遇到的一些面试题汇集:
1. 关于js模块的:来自 https://github.com/mqyqingfeng/Blog/issues/108
requirejs 为全局添加了 define 函数,你只要按照这种约定的方式书写这个模块即可。
// 模块引入
// main.js
require(['./add', './square'], function(addModule, squareModule) {
console.log(addModule.add(1, 1))
console.log(squareModule.square(3))
});
// add 模块声明
define(function() {
console.log('加载了 add 模块');
var add = function(x, y) {
return x + y;
};
return {
add: add
};
});
-
AMD:
-
CMD: sea.js AMD 和 CMD 都是用于浏览器端的模块规范 前两者区别:
- CMD 推崇依赖就近(想什么时候 require就什么时候加载,实现了懒加载(延迟执行 )),AMD 推崇依赖前置(依赖必须一开始就写好)
- 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。AMD 是将需要使用的模块先加载完再执行代码,而 CMD 是在 require 的时候才去加载模块文件,加载完再接着执行。
-
CommonJS 在服务器端比如 node,采用的则是 CommonJS 规范。
-
ES6模块
CommonJS amd:前者用于服务器,后者用于浏览器,“运行时加载”,只能在运行时确定这些东西 es6中import export ,静态化,引入宏(macro)和类型检验(type system)这些只能靠静态分析实现的功能。
2. 关于setTimeout,async,promise的执行顺序
3. 函数参数 arguments 是数组吗,有什么区别
arguments对象不是一个 Array 。它类似于Array,但除了length属性和索引元素之外没有任何Array属性。可以转化为一个数组
var args = Array.prototype.slice.call(arguments);
var args = [].slice.call(arguments);
// ES2015
const args = Array.from(arguments);
const args = [...arguments];
4. js继承(最优解:寄生组合继承)源码这里
主题思路:方法和属性分别分开继承(且只调用一次父的构造函数) 重学 JS 系列:聊聊继承
// 寄生组合继承
function Parent(name){
this.name = name;
this.colors = ['red', 'green']
}
Parent.prototype.getName = function(){
console.log(this.name)
}
function Child(name, age){
Parent.call(this, name)
this.age = age;
}
// 关键步:模拟new 的实现,只继承方法
const F = function () {}
F.prototype = Parent.prototype;
Child.prototype = new F();
const child1 = new Child('sundj', '12')
console.log(child1)
而寄生组合继承
寄生组合继承还可以如下:使用Object.create()
function Parent(value) {
this.val = value
}
Parent.prototype.getValue = function() {
console.log(this.val)
}
function Child(value) {
Parent.call(this, value)
}
Child.prototype = Object.create(Parent.prototype, {
constructor: {
value: Child,
enumerable: false,
writable: true,
configurable: true
}
})
const child = new Child(1)
child.getValue() // 1
child instanceof Parent // true
5. 浏览器多个标签页之间的通信
6. 经典的this 彻底弄清 this call apply bind 以及原生实现
7.前端鉴权
8. 浏览器跨域拦截流程
9. 关于原型链
深入了解 Object.prototype、Function.prototype、function Object 、function Function 之间的关系
10. 静态资源放置于独立域名之下
- 启用新的一级域名,每次请求浏览器不会携带cookie。这对于cookie内容比较大,并且流量大的网站会省去不少宽带费用。同时这也解惑了为什么不用二三级域名。
- 动静分离。静态资源与动态内容分离,有利于部署于CDN,减轻web服务器压力
- HTTP协议对同一个域名的同时下载线程数有限制。主要是为了优化下载速度,防止同一域名下下载线程数过多,导致下载速度变慢。各个浏览器都会遵守这个规定,但是限制的数目可能不一致。基于这个原因,可将资源部署于不同的域名,以达到最大化并发下载。
- 静态资源独立部署,为全局产品服务。这属于业务划分的范畴了。比如taobao.com和tmll.com都会用到tbcdn.cn上的静态资源,这些资源不必从属于某个产品。
- 接第4点原因,有利于最大化利用客户端缓存。比如访问taobao.com,缓存了tbcdn.cn上的某个js文件,之后再访问tmll.com时,也用到此js文件,不必再从tbcdn.cn上下载,直接用客户端缓存即可。
同时,就已经减轻了每台服务器的压力,服务器越多,每个服务器压力就越小