假如这是一个能继承武功的异世界
灵魂链__proto__
// 异世界的每个人都是以 Person 为原型诞生的
function Person() {
this.type = "异界人";
}
// 宇宙中诞生了一个灵魂:王一
function 王一() {}
// 王一的灵魂来到了异世界,以 Person 为原型 重塑了灵魂
王一.prototype = new Person();
// 王一的灵魂附着在一个叫王1的孩子上,在异世界出生了
const 王1 = new 王一();
// 王1长大后查看自己的灵魂指向(__proto__),上天告诉他 ,你是由王一灵魂创造的
王1.__proto__ === 王一.prototype;
// 王1又问,那王一灵魂是怎么来的,上天告诉他,是以 Person为原型构造的
王一.prototype.__proto__ === Person.prototype;
// 王1又问,那 Person 是怎么来的,上天告诉他,是以万物之根 Object 为原型构造的
Person.prototype.__proto__ === Object.prototype;
// 王1又问,那 Object 是怎么来的,上天告诉他,是从无(null)即宇宙诞生之初就有了.
Object.prototype.__proto__ === null;
// 王1 恍然大悟,不再多问
灵魂构造肉身 new
// 若干年后...
// 王2 出生了,这时候他问上天
// 那么灵魂是如何通过 new 构造人的
function Person(family, name) {
this.family = family;
this.name = name;
}
// 模拟 new 创造过程
const myNew = function () {
// 先由万物之根创造一个肉体
const obj = new Object();
// 获取灵魂构造器, 这里是用的Person的灵魂构造器
// 此处的 arguments 为[Person ,"王氏", "王2"]
// 利用 shift 方法,把数组的第一个元素从其中删除,并返回第一个元素的值。即返回了Person
const constructor = [].shift.call(arguments);
// 将肉体的灵魂指向Person的灵魂原型
obj.__proto__ = constructor.prototype;
// 借用外部传入的属性给肉体赋予一定的属性
// 此处的 arguments 为["王氏", "王2"]即(family, name)两个参数
const result = constructor.apply(obj, arguments);
// 确保创造出来的一定是个正常的人(Object)
return typeof result === "object" ? result : obj;
};
// 下面的产生的结果是一样的
const 王2 = new Person("王氏", "王2");
const 王2 = myNew(Person, "王氏", "王2");
检测灵魂与肉体关系 instanceof
// 又过了很多年,王3出生了
// 这时候他问,那么我怎么直接知道哪个灵魂构造器和我有没有关系呢 ?
// 上天告诉他
// instanceof 可以判断灵魂构造器和自己有没有关系
function Person() {
this.type = "异界人";
}
function 王一() {}
// 王一灵魂以 Person 为构造器重塑
王一.prototype = new Person();
const 王1 = new 王一();
function 王二() {}
// 王二灵魂以 王一灵魂 为构造器重塑
王二.prototype = new 王一();
const 王2 = new 王二();
function 王三() {}
// 王三灵魂以 王一灵魂 为构造器重塑
王三.prototype = new 王二();
const 王3 = new 王三();
// 以下输出都为 true
console.log(王3 instanceof 王三);
console.log(王3 instanceof 王二);
console.log(王3 instanceof 王一);
console.log(王3 instanceof Person);
console.log(王3 instanceof Object);
// instanceof 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
// 而__proto__ 将对象连接起来组成了原型链。
// instanceof 实现
function myInstanceof(人, 灵魂) {
// 获得要检测灵魂的构造器
let prototype = 灵魂.prototype;
// 获得人灵魂的构造器
人 = 人.__proto__;
// 判断人灵魂的构造器是否等于灵魂的构造器
while (true) {
// 直至匹配到灵魂指向原点 null
if (人 === null) return false;
if (prototype === 人) return true;
// 倘若不同, 则用父级灵魂构造器匹配
人 = 人.__proto__;
}
}
// 以下输出都为 true
console.log(myInstanceof(王3, 王三));
console.log(myInstanceof(王3, 王二));
console.log(myInstanceof(王3, 王一));
console.log(myInstanceof(王3, Person));
console.log(myInstanceof(王3, Object));
总结
-
Object 是所有人(对象)的根本
-
所有人(对象)都可以通过__proto__找到自己的灵魂原型
-
__proto__就是人跟“灵魂构造器的原型”联系起来的纽带,由此形成了原型链
-
prototype 属性表示灵魂的原型对象。