面试题
phy-lei 2021-03-27
面试
# 写在前面的话
每一次的面试,不仅能让我从中找到自己想要的工作,即使失败,也是一次对自己知识点的一个查漏补缺,以此记录一些自己遇到的一些面试题,此贴是长久更新...
# 1.创建对象有哪几种方式,各有什么区别
答:创建对象有 3 种方式,分别是字面量创建,构造函数创建,使用 Object.create 创建。前两种方式的创建是没啥区别的,原型指针proto指向的仍是内置 Object 对象,而 Object.create 接受 2 个参数,第一个参数是新创建对象的原型对象,第二个参数 propertiesObject(对象的描述),代码:
// Object.create
var obj = Object.create(
{ a: 1 },
{
foo: {
writable: true,
configurable: true,
value: "hello"
}
}
);
console.log(Object.getPrototypeOf(obj)); //ES5 获取目标对象的原型 => {a:1}
console.log("a" in obj); //hasOwnProperty判断不到原型的属性 故可以用in => true
// 字面量创建
var a = {
foo: "hello"
};
// 构造函数创建
var b = new Object({ foo: "hello" });
既然 object.create 的第一个参数是新创建对象的原型对象,那么也可以做到跟其他 2 种方式创建变量一样的原型,可以 Object.create(Object.prototype, {propertiesObject}),这样就跟前面 2 种方式没什么区别了,而如果想要创建一个全空对象的话(原型也为空),可以使用 Object.create(null)
# 2.介绍下原型及原型链
答:每个函数都有一个 prototype 属性;每一个 JavaScript 对象(除了 null)都具有的一个属性,叫proto,这个属性会指向该对象的原型;每个原型都有一个 constructor 属性指向关联的构造函数。图:

# 3.什么是执行上下文
答:当 JS 执行到一段可执行代码时(全局代码、函数代码、eval)就会创建执行上下文,1、进入执行上下文(类似于编译阶段),2、代码执行(引擎执行),执行上下文内有三个重要属性:
- 变量对象也称为活动对象 AO(函数的所有形参,函数声明,变量声明)
- this
- 作用域链([[scope]])
// 示例:
function foo(a) {
var b = 2;
function c() {}
var d = function() {};
b = 3;
}
foo(1)
// 进入执行上下文时AO
fooScopeContext = {
AO = {
arguments: {
0: 1,
length: 1
},
a: 1,
b: undefined,
c: reference to function c(){},
d: undefined
},
Scope: fooscope.[[scope]],
}
// 代码执行后AO
fooScopeContext = {
AO = {
arguments: {
0: 1,
length: 1
},
a: 1,
b: 3,
c: reference to function c(){},
d: reference to FunctionExpression "d"
},
Scope: fooscope.[[scope]],
}
# 4.手写 call
Function.prototype.myCall = function(context, ...args) {
console.log(this, context, args);
// 这里默认使用默认绑定window
if (typeof context === "undefined" || context === null) {
context = window;
}
// 利用隐式绑定调用this 其实就是相当于调用的是替身
let fnSymbol = Symbol();
context[fnSymbol] = this;
let fn = context[fnSymbol](...args); //此时this就指向context了
delete context[fnSymbol]; // 将替身删除
return fn;
};