js编程半年,起初没有用OOP的方式(一是因为js的class理解起来有点困难,二是觉得当前业务没有那么复杂,无需用OOP,三是进度优先,能实现功能就OK)。但半年后的现在,越来越发现面向过程的代码维护起来很费劲——因为没有封装、继承。故不得不缓一缓步子,硬着头皮再次捡起js的OOP来。
让我茅塞顿开的是 Vjeux的文章,也要感谢引路人阮一峰老师。Vjeux的文章已经够好,不再自己写了——也怕写不好。针对ECMA-262中对prototype解释图自己写了相应的代码,发出来,帮助学习者理解:
本文中的英文copy自ECMA-262
CF is a constructor (and also an object). Five objects have been created by using new expressions: cf1, cf2, cf3, cf4, and cf5. Each of these objects contains properties named q1 and q2. The dashed lines represent the implicit prototype relationship; so, for example, cf3’s prototype is CFp. The constructor, CF, has two properties itself, named P1 and P2, which are not visible to CFp, cf1, cf2, cf3, cf4, or cf5. The property named CFP1 in CFp is shared by cf1, cf2, cf3, cf4, and cf5 (but not by CF), as are any properties found in CFp’s implicit prototype chain that are not named q1, q2, or CFP1. Notice that there is no implicit prototype link between CF and CFp.
my code(在chrome(version: 50.0.2661.102)运行通过):
function CF() {
this.q1 = 'q1';
this.q2 = 'q2';
}
var CFp = {
CFP1: 'cfp1'
};
CF.prototype = CFp;
// 一般是直接将CFp的定义赋给prototype,无需先定义变量(图中为了说明问题,所以费劲取名)。如下:
// CF.prototype = {
// CFP1: 'cfp1'
// }
CF.P1 = 'p1'; // 实际工作中,这类属性基本没什么用吧?
CF.P2 = 'p2';
var cf1 = new CF();
var cf2 = new CF();
// cf3 ~ cf5相同
console.log(cf1.q1); // 'q1'
console.log(cf1.q2); // 'q2'
console.log(cf1.CFP1); // 'cfp1'
console.log('---');
console.log(cf1.P1); // undefined, because 'P1 and P2 are not visible to CFp, cf1, ...'
console.log(cf1.P2); // undefined
console.log('---');
console.log(CF.P1); // 'p1'
console.log(CF.CFP1); // undefined, because 'there is no implicit prototype link between CF and CFp'
console.log(CF.q1); // undefined
几个关键定义:
constructor
function object that creates and initializes objects
NOTE The value of a constructor’s prototype property is a prototype object that is used to implement inheritance and shared properties.
prototype
object that provides shared properties for other objects
NOTE When a constructor creates an object, that object implicitly references the constructor’s prototype property for the purpose of resolving property references. The constructor’s prototype property can be referenced by the program expression constructor.prototype, and properties added to an object’s prototype are shared, through inheritance, by all objects sharing the prototype. Alternatively, a new object may be created with an explicitly specified prototype by using the Object.create built-in function.