这是一篇方法论的文章,鉴于笔者水平有限,难免会有纰漏。但是实在想分享一种“授人以渔”的方法。因为最近看了一些面试题,大多数都在零零碎碎的写各种总结和技巧。总得来说,会有收获,每个作者的分享也很不错。然而凡事总怕但是——但是,我这里要说的是,这些经验式的总结和技巧,如同一个个芝麻粒一样,无序和零散。这就是我写这篇文章的目的,现在的媒介资源,让我可以轻而易举获得各种大小的芝麻粒,然而芝麻背后的道理?如何知晓?
Javascript 是什么
说起前端 Javascript,我们通常指的是客户端 ECMAScript 以及 BOM 和 DOM 的结合体。Javascript 还有其他环境中的变体在此不再赘述。本文也不讨论 BOM 和 DOM 的细节,它们都是一堆 API 的实现。直接呼应本文标题【一条获取 Javascript 真相的途径】,就在 ECMAScript 之中。ECMAScript 全称是:European Computer Manufacturers Association。这么长的单词,并不重要,我们只要知道它是一个标准化的脚本程序设计语言即可。
从 Object.create
探讨 ECMAScript 里有什么
这一段开始,就是我想认真探讨的问题。我们先来看一个实例:如何实现/模拟 Object.create
?
这里有一个实现,可以参考。可是,为什么是这样?这么写的来源又是在哪里?其实反过来思考,如果我们知道原理,下面的例子或许就不能称作一个问题,
Object.create = function (obj) {
var B={};
B.__proto__=obj;
return B;
};
这原理,自然就在 ECMAScript 之中。在正片开始之前,重要的东西发三遍:
下图是以上链接的内容示例。

这个文档非常好用,提供了定位当前链接,图钉和查看引用以及搜索的功能。我们可以通过直接输入 Object.create
定位到相关实现。伪代码如下:
19.1.2.2 Object.create ( O, Properties )
The create function creates a new object with a specified prototype. When the create function is called, the following steps are taken:
- If Type(O) is neither Object nor Null, throw a TypeError exception.
- Let obj be ObjectCreate(O).
- If Properties is not undefined, then
- Return ? ObjectDefineProperties(obj, Properties).
- Return obj.
通过以上定义得知,实现一个 Object.create
需要大致四步,我们来按照说明实现如下。这个 create 方法创建了一个拥有特殊原型的对象。当方法调用时,执行以下四步:
- 判断对象类型是否是对象或null,如果不是,抛出一个错误。
- 创建一个空对象(这里面还有一个抽象操作名为:ObjectCreate 用来定义运行时的普通对象)
- 如果第二个参数不是 undefined。那么返回
ObjectDefineProperties(obj, properties)
的调用结果(这一步也是由一个名为: ObjectDefinePropertis 的抽象操作完成的。它的主要作用就是返回一个包含第二个参数属性的对象,这些属性跟 Object.defineProperties(obj, props) 的第二个参数相对应)。 - 返回该对象
好了,针对以上论述我们应该能容易实现如下代码:
function myObjectCreate(obj, properties) {
if (typeof obj !== "object") {
throw new Error("not a object");
}
let tempObj = {}; //
tempobj.__proto__ = obj;
if (properties !== undefined) {
Object.defineProperties(tempObj, properties);
}
return tempObj;
}
以上算是根据 ECMAScript 的标准实现了一遍 Object.create
。过程比较简单,其中有两个抽象操作,我们如果不去阅读这份实现,在实际开发中永远不会遇到。但是,如果你对这深层次的实现有一定的了解或者认识,那么会在写代码的过程中带着更顺畅的理解去实现功能。这其中区别,不用多说了吧。
回顾
现在我们回头看看,这篇文章其实没有多少知识点。如同我开始所讲,希望前端开发者不要总是过着吃别人丢过来的鱼片过日子。当我们学会捕鱼(钓鱼不太合适)的时候,有很多东西,不言自明。如果针对本文中的例子有所体会,也一定是你自己要通过阅读 ECMAScript 的实现来完成。这份标准的词汇量很少,也没有晦涩的语法。坚持探究下去,里面还讲了 bind call apply 的定义。这些经常会在各种面试题中出现,如果你能理解这内部的操作过程以及逻辑,想必再也不用死记硬背这些枯燥乏味的实现了吧。我们回头看 Object.create
的实现:
- 判断类型
- 创建空对象并绑定 proto
- 处理属性描述符,如果存在的话
- 返回该对象
可是如果我们看最开始的那份答案:
Object.create = function (obj) {
var B={};
B.__proto__=obj;
return B;
};
这里写的是很简单易懂,但也就止步到此了。希望本文能给你带来一些启发,我们共同进步,如果有什么建议,还望不吝赐教。
