• 《王者归来》读书笔记 ── JavaScript 面向对象编程(1)


    《王者归来》读书笔记 ── 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 中可以有不逊色于其他各种面向对象语言的公有和私有特性:

    Javascript代码 <embed height="15" width="14" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" allowscriptaccess="always" quality="high" flashvars="clipboard=function%20List()%7B%0A%20%20%20%20var%20m_elements%20%3D%20%5B%5D%3B%20%20%20%2F%2F%E7%A7%81%E6%9C%89%E6%88%90%E5%91%98%EF%BC%8C%E5%AF%B9%E8%B1%A1%E5%A4%96%E6%97%A0%E6%B3%95%E8%AE%BF%E9%97%AE%0A%20%20%20%20m_elements%20%3D%20Array.apply(m_elements%2C%20arguments)%3B%0A%0A%20%20%20%20%2F%2F%E5%85%AC%E6%9C%89%E5%B1%9E%E6%80%A7%EF%BC%8C%E5%8F%AF%E4%BB%A5%E9%80%9A%E8%BF%87%E2%80%9C.%E2%80%9D%E8%BF%90%E7%AE%97%E7%AC%A6%E6%88%96%E4%B8%8B%E6%A0%87%E8%AE%BF%E9%97%AE%0A%20%20%20%20this.length%20%3D%20%7B%0A%20%20%20%20%20%20%20%20valueOf%20%3A%20function()%7Breturn%20m_elements.length%3B%7D%2C%0A%20%20%20%20%20%20%20toString%20%3A%20function()%7Breturn%20m_elements.length%3B%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20this.toString%20%3D%20function()%7B%0A%20%20%20%20%20%20%20%20return%20m_elements.toString()%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20this.add%20%3D%20function()%7B%0A%20%20%20%20%20%20%20%20m_elements.push.apply(m_elements%2C%20arguments)%3B%0A%20%20%20%20%7D%0A%7D" src="http://mockee.javaeye.com/javascripts/syntaxhighlighter/clipboard_new.swf" lk_mediaid="lk_juiceapp_mediaPopup_1236739438821" lk_media="yes">
    1. function List(){  
    2.     var m_elements = [];   //私有成员,对象外无法访问  
    3.      m_elements = Array.apply(m_elements, arguments);  
    4.   
    5.     //公有属性,可以通过“.”运算符或下标访问  
    6.     this.length = {  
    7.          valueOf : function(){return m_elements.length;},  
    8.         toString : function(){return m_elements.length;}  
    9.      }  
    10.   
    11.     this.toString = function(){  
    12.         return m_elements.toString();  
    13.      }  
    14.   
    15.     this.add = function(){  
    16.          m_elements.push.apply(m_elements, arguments);  
    17.      }  
    18. }  
    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); } }

    这个例子中 this.length, this.toString, this.add 是公有成员,其中 this.length 是私有成员 m_elements 的 length 属性的 getter,外部我们可以通过“.”运算符对这些属性进行访问。

    对象的 getter 是一种特殊的属性,它形式上像是变量或者对象属性,但它的值随着传入参数的改变而改变。在不支持 getter 的语言中,我们通常用 get<Name> 方法来替代,其中 <Name> 是 getter 的实际名字,其效果与 getter 等价。ECMAScript v3 不支持 getter,但可以用上面这种构造带有 valueOf 和 toString 方法的对象来模拟 getter。

    对象的 setter 是另一个相对应的属性,它的作用是通过类似赋值的方式改变对象的某些参数或者状态,遗憾的是,ECMAScript v3 不支持 setter,并且目前为止也没什么好的方法可以在 JS 中模拟 setter。要实现,只有通过定义 set<Name> 方法来实现:(


    II. 属性和方法的类型

    在 JS 里,对象的属性和方法支持 4 种不同的类型,下面通过一个例子来说明:

    Javascript代码
    1. function myClass(){  
    2.     var p = 100;  //private property; 1. 私有属性  
    3.     this.x = 10;  //dynamic public property 2. 动态公有属性  
    4. }  
    5.   
    6. myClass.prototype.y = 20;  //static public property or prototype property 3. 静态公有属性或称原型属性  
    7.   
    8. myClass.z = 30;  //static property 4. 静态属性或称类属性  
    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. 静态属性或称类属性

    下面说下他们的特点和区别:

    1. 私有属性上面已经提到,它的特点是对外界不开放,只能通过特定的 getter 和 setter 访问。实例化 myClass() 后,如果通过“.”运算符直接访问 p 会得到 undefined;

    2. 动态公有属性的特点是外界可以访问,而且每一个对象实例持有一个副本,他们之间不会相互影响;

    3. 原型属性的特点是每个对象实例共享唯一副本,对它的改写会相互影响;

    4. 类属性的特点是作为类型的属性而不是对象实例的属性,也就是说不能通过对象实例的“.”运算符访问,那样会得到 undefined。上例中通过 myClass.z 直接访问即可。

    有关 prototype 的知识点要放到下几篇,毕竟是 JS 面向对象编程的重点所在,内容比较多。简单预告一下第 2 篇笔记,包括 prototype 的使用技巧、实质及其范例。之后几篇会涉及继承和多态、构造和析构、包装对象、元类,类模板等。

    本篇结尾以一个例子简述一下 prototype,“prototype 是在 IE 4 及其以后版本引入的一个针对于某一类的对象的方法,而且特殊点在于:它是一个给类的对象添加方法的方法”:

    为本地对象 Number 添加数字阶乘方法:Number.fact()

    实现:

    Javascript代码
    1. Number.prototype.fact = function(){  
    2.     var num = Math.floor(this);  
    3.     if(num<0) return NaN;  
    4.     else if(num==0 || num==1) return 1;  
    5.     else return (num*(num-1).fact());  
    6. }  
    7.   
    8. alert((10).fact());  //3628800
  • 相关阅读:
    LIBSVM
    tf-idf
    DIV+CSS例子
    网页背景设置
    获取JDBC中的ResultSet的记录的条数
    SQL 基本语句
    经典SQL语句大全
    JS(截取字符串,显示当前系统时间yyyy-MM-dd,从文本框得到的数值计算)
    JavaScript实现全排列
    Java发送邮件
  • 原文地址:https://www.cnblogs.com/danghuijian/p/4400690.html
Copyright © 2020-2023  润新知