前段时间刷掘金发现一篇很不错的文章(清单),以为挺有道理的。有些知识点之前看事后,过段时间后发现又忘了,而后又去查找资料,反反复复 感受知识点永远不是本身的且学的又比较零散。因此按照 一名【合格】前端工程师的自检清单去完善本身知识体系(根据自身状况稍做调整)。javascript
这里说明下大部分知识点详解都是引用下面连接的,都是很不错的文章,值得去研究,在此感谢各位做者大大了。 若是引用涉及做者版权之类,请私信我,会尽快删掉的。html
JavaScript
规定了几种语言类型?前端
Number
,Undefined
,Boolean
,String
,Null
,Symbol
,BigInt
Object
JavaScript
对象的底层数据结构是什么?: HashMap
java
Symbol
类型在实际开发中的应用、可手动实现一个简单的Symbol
react
JavaScript
中的变量在内存中的具体存储形式git
基本类型对应的内置对象,以及他们之间的装箱拆箱操做es6
理解值类型和引用类型github
null
和undefined
的区别面试
至少能够说出三种判断JavaScript
数据类型的方式,以及他们的优缺点,如何准确的判断数组类型 ES6 有个Array.isArray
能够很好的判断是否为数组类型。 判断 JS 数据类型的四种方法:编程
typeof
:
null
之外,都可以返回正确的结果。function
之外,一概返回 object
类型。null
,返回 object
类型。function
返回 function
类型。instanceof
:
instanceof
只能用来判断两个对象是否属于实例关系, 而不能判断一个对象实例具体属于哪一种类型constructor
:
constructor
存在的,这两种类型的数据须要经过其余方式来判断。constructor
是不稳定的,这个主要体如今自定义对象上,当开发者重写 prototype 后,原有的 constructor
引用会丢失,constructor
会默认为 Object
toString
:
toString()
是 Object
的原型方法,调用该方法,默认返回当前对象的 [[Class]]
。这是一个内部属性,其格式为 [object Xxx]
,其中 Xxx 就是对象的类型。 此方法也有缺点,不能精确的判断自定义类型,对于自定义类型只会返回 [object Object]
,不过能够用instanceof
代替判断。
function Person () {}
const p = new Person();
Object.prototype.toString.call(p); // [object Object]
p instanceof Person; // true
复制代码
可能发生隐式类型转换的场景以及转换原则,应如何避免或巧妙应用。
出现小数精度丢失的缘由,JavaScript能够存储的最大数字、最大安全数字,JavaScript处理大数字的方法、避免精度丢失的方法。
Number.MAX_VALUE
它的值能够经过Number.MAX_VALUE获得,在控制台打印获得值:1.7976931348623157e+308。Number.MAX_SAFE_INTEGER
: 9007199254740991理解原型设计模式以及JavaScript
中的原型规则
原型规则
var arr = [];arr.a = 1;
prototype
(显式原型),属性值也是一个普通对象;(obj._proto_ === Object.prototype)
;_proto_
(即它的构造函数的prototype
)中去寻找;instanceof
的底层实现原理,手动实现一个instanceof
实现继承的几种方式以及他们的优缺点
至少说出一种开源项目(如Node
)中应用原型继承的案例[暂时没看过源码,看了以后再来回答]
能够描述new
一个对象的详细过程,手动实现一个new
操做符
理解es6 class
构造以及继承的底层实现原理
es6 引入的 class
类实质上是 JavaScript
基于原型继承的语法糖。
class Animal {
constructor(name) {
this.name = name;
}
sayHi() {
return `Hello ${this.name}`;
}
}
// es5
function Animal(name) {
this.name = name;
}
Animal.prototype.sayHi = () => {
return `Hello ${this.name}`;
};
复制代码
让咱们来看看经过babel
转换的Animal
类,是否跟上面es5相似呢?
"use strict";
/** * 判断left 是不是 right 的实例, 底层利用 instanceof, */
function _instanceof(left, right) {
if (
right != null &&
typeof Symbol !== "undefined" &&
right[Symbol.hasInstance]
) {
return !!right[Symbol.hasInstance](left);
} else {
return left instanceof right;
}
}
function _classCallCheck(instance, Constructor) {
if (!_instanceof(instance, Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
/** * 利用Object.defineProperty添加对象属性 */
function _defineProperties(target, props) {
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
/** * 给构造函数or构造函数原型添加属性or方法 */
function _createClass(Constructor, protoProps, staticProps) {
if (protoProps) _defineProperties(Constructor.prototype, protoProps);
if (staticProps) _defineProperties(Constructor, staticProps);
return Constructor;
}
var Animal =
/*#__PURE__*/
(function() {
// 构造函数
function Animal(name) {
// 检测 this(this 指向生成的实例)是不是构造函数Animal的实例
_classCallCheck(this, Animal);
this.name = name;
}
// 向构造函数添加方法
_createClass(Animal, [
{
key: "sayHi",
value: function sayHi() {
return "Hello ".concat(this.name);
}
}
]);
return Animal;
})();
复制代码
从以上转义后的代码来看,底层仍是采用了原型的继承方式。
理解词法做用域和动态做用域
理解JavaScript
的做用域和做用域链
理解JavaScript
的执行上下文栈,能够应用堆栈信息快速定位问题
this
的原理以及几种不一样使用场景的取值。
this
是什么?this
就是函数运行时所在的环境对象。
闭包的实现原理和做用,能够列举几个开发中闭包的实际应用
// 1. 经典闭包面试题
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
})
}
for (var i = 0; i < 5; i++) {
(function (j) {
setTimeout(() => {
console.log(j)
})
}(i))
}
// 2. 模块化方案
const module = (function() {
var name = 'rudy';
var getName = function () {
return name;
}
var changeName = function (newName) {
name = newName;
return name;
}
return {
getName: getName,
changeName: changeName
}
}())
// 私有变量
var privateNum = (function () {
var num = 0;
return function () {
return num++;
}
}())
privateNum(); // 0
privateNum(); // 1
privateNum(); // 2
复制代码
必要应用场景实在是太多了,以上只列举了部分场景。
理解堆栈溢出和内存泄漏的原理,如何防止
如何处理循环的异步操做;
若是须要简单的处理下for循环的异步操做,就是让每一个循环体拥有本身的做用域,能够利用
es6
中的let
或者闭包来解决。
// let
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log(i);
// do something
})
}
// 闭包
for (var i = 0; i <5; i++) {
(function (j) {
setTimeout(() => {
console.log(j);
// do something
})
}(i))
}
复制代码
理解模块化解决的实际问题,可列举几个模块化方案并理解其中原理