以下题目来自掘金等其它博客,但是问题的答案都是根据笔者自己的理解做出的。如果你最近想要换工作或者巩固一下自己的前端知识基础,不妨和我一起参与到每日刷题的过程中来,如何?
第一天要刷的手写题如下:
- 手写一个函数,实现new操作符。
- 手写一个函数,实现Object.create方法。
- 手写一个函数,实现instanceof操作符。
下面是我自己写的答案:
1. 手写一个函数,实现new操作符
根据new操作符的作用原理,可以比较方便的写出其实现:
markdown
new执行以下几个步骤:
1. 创建一个空对象:new操作符会创建一个新的空对象,该对象继承自构造函数的原型对象。
2. 设置对象的原型链:新创建的空对象的__proto__属性会被设置为构造函数的prototype属性,这样就建立了对象与构造函数原型之间的连接。
3. 执行构造函数代码:将新创建的空对象作为this关键字绑定到构造函数,并执行构造函数内部的代码。这样,构造函数可以通过this来操作和设置新对象的属性和方法。
4. 返回新对象实例:如果构造函数没有显式返回值,则new操作符会隐式返回新创建的对象实例。如果构造函数有返回值,有以下两种情况:
- 如果返回值是一个对象,则new操作符会返回该对象。
- 如果返回值不是一个对象(比如基本数据类型),则忽略返回值,返回新创建的对象。
自己实现的myNew函数,接受一个function类型的参数作为其"类",接受剩余参数作为返回对象的初始化值。
javascript
function myNew (constructor, ...rest) {
// 判断传入的参数是否有效
if(typeof constructor !== "function") throw new Error("参数一必须是构造函数");
// 绑定原型
const obj = Object.create(constructor.prototype);
// 执行构造函数
const rst = constructor.apply(obj, rest);
return (rst && (typeof rst === "object")) ? rst : obj;
}
2. 手写一个函数,实现Object.create方法
Object.create方法的作用为:
plaintext
Object.create()方法是JavaScript中用于创建一个新对象的方法。它的作用是以指定的原型对象作为新对象的原型,并可选择性地为新对象定义属性和方法。
Object.create(proto, [propertiesObject])接受两个参数:
1. proto:必需,表示新对象的原型。它可以是一个对象字面量、null或者其他已存在的对象。新对象将继承proto对象的属性和方法。
2. propertiesObject(可选):一个可选的对象,用于定义新对象的属性和方法。该对象的每个属性都是通过属性描述符来定义的,类似于Object.defineProperty()的第二个参数。
借用原型设计模式实现Object.create:
javascript
function myCreate(proto, propertiesObject) {
if (Object(proto) !== proto) {
throw new TypeError('Object prototype may only be an Object or null');
}
// 创建一个空函数
function F() {}
// 指定此函数的原型
F.prototype = proto;
// 创建待返回实例
const obj = new F();
// 往实例对象上添加属性
if (propertiesObject !== undefined) {
Object.defineProperties(obj, propertiesObject);
}
// 返回实例对象
return obj;
}
3. 手写一个函数实现instanceof操作符的功能
- x instanceof y 的作用原理就是,在x的原型链上寻找y,如果找到了就返回true,如果找不到就返回false;
- 根据其作用原理,其实现过程也就呼之欲出了:首先判断x是不是object类型的,如果不是直接返回false就可以了。如果是的话,则逐级比较x的原型和y是否相等,知道x原型链的尽头,也就是null。如果此时y与任何一层原型都不相等,则返回false,否则返回true。
- 实现代码如下:
javascript
function myInstanceof(obj, cons){
if(Object(obj)!==obj) return false;
let _p = obj.__proto__;
while(_p!==null){
if(_p==cons.prototype) return true;
_p = _p.__proto__;
}
return false;
}