fecoding 2019-03-29
function Parent (name) { this.name = name; } var son = new Parent('chris'); // 实例的 contructor 指向实例的构造函数 console.log(son.constructor === Parent); // true // instanceof 用于验证实例与原型对象的关系 console.log(son instanceof Parent); // true // isPrototypeOf 用于验证实例与 prototype 对象的关系 console.log(Parent.prototype.isPrototypeOf(son)) // true // 实例的 __proto__ 指向其构造函数的 prototype 对象 console.log(son.__ptoto__ === Parent.prototype); // true // __proto__ 是每个对象都有的属性,prototype 属性只有函数才有
假设有如下两个类
function Person () { this.type = 'human'; } function Parent (name) { this.name = name; }
想要实现 Parent 继承 Person,常见的有以下四种方式:
/* 1. 构造函数绑定 */ function Parent (name){ Person.apply(this, arguments); this.name = name; } /* 2. prototype 模式 */ Parent.prototype = new Person(); // prototype 对象的 contructor 属性应该指向构造函数, // 上一步使得 Parent.prototype.contructor === Person // 此后将使 son.prototype === Parent.prototype === Person,造成继承链紊乱,因此需要修正 Parent.prototype.contructor = Parent; /* 3. 直接继承 prototype */ // 优点:效率高,不用创建实例,节省内存 // 缺点:任何对 Parent.prototype 的修改将直接影响 Person.prototype // 缺点:Person.prototype.contructor 也被修改(=== Parent) Parent.prototype = Person.prototype; Parent.prototype.contructor = Parent; /* 4. 利用空对象作为中介 */ var F = function () {}; F.prototype = Person.prototype; Parent.prototype = new F(); Parent.prototype.constructor = Parent;
假设有以下两个对象
var father = { lastname: 'paul' }; var son = { height: 180 };
需要实现 son 对 father 的继承,有以下几种方式:
/* 1. 空函数作中介 */ function object (o) { var F = function () {}; F.prototype = o; return new F(); } var son = object(father); son.height = 180; /* 2. 浅拷贝、深拷贝*/ // 逐个将父对象的属性拷贝至子对象
最后,送上知乎用户 @doris 的一图流作为结尾:
是一道经常出现在前端面试时的问题。如果只是简单的了解new关键字是实例化构造函数获取对象,是万万不能够的。更深入的层级发生了什么呢?同时面试官想从这道题里面考察什么呢?下面胡哥为各位小伙伴一一来解密。