《王者归来》读书笔记 ── JavaScript 面向对象编程(1)
跳过 JS 核心(语言结构、数据类型、函数、对象、集合、字符串等)以及 BOM、DOM 部分,这个系列的笔记主要总结一下《王者归来》面向对象编程部分的知识点,以便梳理和查阅。
JavaScript 究竟是不是一种面向对象的语言呢?
“ 面向对象不是只有类模型一种,prototype-based(基于原型)是 class-based(基于类)的简化版,是一种 class-less 的面向对象。对应的,prototype 继承是 class 继承的简化版(例如省略了多重继承、基类构造函数、忽略了引用属性的继承等),但不能因为它不支持这些特性就不承认它是一种完整的继承。是否为继承添加额外的特性,开发者可以自由选择,但在不需要这些额外特性的时候,还是有理由尽量用 prototype-based 继承。
总而言之,prototype-based 认为语言本身可能不需要过分多的 reuse 能力,它牺牲了一些特性来保持语言的简洁,这没有错,prototype-based 虽然比 class-based 简单,但它依然是真正意义上的 object-oriented。”
I. 公有和私有 ── 属性的封装
JS中,函数是绝对的“第一型”,JS 的对象和闭包都是通过函数实现的。利用闭包的概念,JS 中可以有不逊色于其他各种面向对象语言的公有和私有特性:
function List(){ var m_elements = []; //私有成员,对象外无法访问 m_elements = Array.apply(m_elements, arguments); //公有属性,可以通过“.”运算符或下标访问 this.length = { valueOf : function(){return m_elements.length;}, toString : function(){return m_elements.length;} } this.toString = function(){ return m_elements.toString(); } this.add = function(){ m_elements.push.apply(m_elements, arguments); }}function myClass(){ var p = 100; //private property; 1. 私有属性 this.x = 10; //dynamic public property 2. 动态公有属性}myClass.prototype.y = 20; //static public property or prototype property 3. 静态公有属性或称原型属性myClass.z = 30; //static property 4. 静态属性或称类属性Number.prototype.fact = function(){ var num = Math.floor(this); if(num<0) return NaN; else if(num==0 || num==1) return 1; else return (num*(num-1).fact());}alert((10).fact()); //3628800function List(){ var m_elements = []; //私有成员,对象外无法访问 m_elements = Array.apply(m_elements, arguments); //公有属性,可以通过“.”运算符或下标访问 this.length = { valueOf : function(){return m_elements.length;}, toString : function(){return m_elements.length;} } this.toString = function(){ return m_elements.toString(); } this.add = function(){ m_elements.push.apply(m_elements, arguments); }}function myClass(){ var p = 100; //private property; 1. 私有属性 this.x = 10; //dynamic public property 2. 动态公有属性}myClass.prototype.y = 20; //static public property or prototype property 3. 静态公有属性或称原型属性myClass.z = 30; //static property 4. 静态属性或称类属性Number.prototype.fact = function(){ var num = Math.floor(this); if(num<0) return NaN; else if(num==0 || num==1) return 1; else return (num*(num-1).fact());}alert((10).fact()); //3628800