本系列文章针对目前常见的面试题,仅提供了相应的核心原理及思路,部分边界细节未处理。后续会持续更新,希望对你有所帮助。
思考
这是今天的题目,你可以先思考一下,然后重点关注不熟悉的~
逐个击破
1.JS中数据类型有哪几种?有什么区别?
最新的 ECMAScript 标准定义了 7 种数据类型:
简单(基本)数据类型 Undefined、Null、Boolean、Number、String、 Symbol类型(ES6新增)
复杂数据类型:Object
注意一下两种特殊类型:
undefined
。在使用var
声明变量但未对其加以初始化时,这个变量的值就是undefined
。无论在什么情况下都没有必要把一个变量的值显式地设置为undefined
。null
。从逻辑角度来看,null
表示一个空指针对象,而这也正式使用typeof
操作符检测null
值时会返回object
的原因。事实上,undefined值是派生自null值的。两种类型复制的区别
基本类型变量的复制:
从一个变量向一个变量复制时,会在栈中创建一个新值,然后把值复制到为新变量分配的位置上,改变源数据不会影响到新的变量(互不干涉);
引用类型变量的复制:
复制的是存储在栈中的指针,将指针复制到栈中为新变量分配的空间中,而这个指针副本和原指针执行存储在堆中的同一个对象,复制操作结束后,两个变量实际上将引用同一个对象;因此改变其中的一个,将影响另一个;
2.JavaScript中什么是闭包?写出一个例子?
闭包就是定义在函数内部,能够读取其他函数内部变量的函数。
举例:用闭包实现一个计数器
function createCounter() {
let counter = 0;
return function () {
counter = counter + 1;
return counter
};
}
const increment = createCounter();
const c1 = increment();
const c2 = increment();
const c3 = increment();
console.log('example increment', c1, c2, c3);//1,2,3
闭包的用途:
使用闭包注意点
还有疑问的话可以查看我这篇文章【JS基础系列】带你深入理解闭包
3.如何正确判断this的指向(注意区分严格模式和非严格模式)?
this
的指向总共可以分为五种:
还有疑问的话可以查看我这篇文章【JS基础系列】如何正确判断this的指向?
4.说一下对call、apply、bind三个区别?自己实现一下bind方法
在JS中,call、apply和bind是Function对象自带的三个方法,这三个方法的主要作用是改变函数中的this指向。
call、apply、bind方法的共同点和区别:
apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。
var func = function(arg1, arg2) {};
func.call(this, arg1, arg2);
func.apply(this, [arg1, arg2])
func.bind(this, arg1, arg2)()
其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
下面自己实现一个bind方法:
Function.prototype.bind2 = function (context) {
if (typeof this !== "function") {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
var fNOP = function () {};
var fBound = function () {
var bindArgs = Array.prototype.slice.call(arguments);
return self.apply(this instanceof fNOP ? this : context, args.concat(bindArgs));
}
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
}
还有疑问的话可以查看我这篇文章【JS基础系列】bind方法的模拟实现
5.js实现一个继承方法
// 借用构造函数继承实例属性
function Child () {
Parent.call(this)
}
// 寄生继承原型属性
(function () {
let Super = function () {}
Super.prototype = Parent.prototype
Child.prototype = new Super()
})()
恭喜你,又掌握了一个新技能~