`

读<悟透JavaScript> 记

阅读更多

对象本无根,类型于无形,本来无一物,何处惹尘埃.....!!

 

 

原型真谛

    正当我们感概万分时,天空中一道红光闪过,祥云中出现了观音菩萨。只见她手持玉净瓶,轻拂翠柳枝,洒下几滴甘露,顿时让JavaScript又添新的灵气。

    观音洒下的甘露在JavaScript的世界里凝结成块,成为了一种称为“语法甘露”的东西。这种语法甘露可以让我们编写的代码看起来更象对象语言。

    要想知道这“语法甘露”为何物,就请君侧耳细听。

    在理解这些语法甘露之前,我们需要重新再回顾一下JavaScript构造对象的过程。

    我们已经知道,用 var anObject = new aFunction() 形式创建对象的过程实际上可以分为三步:第一步是建立一个新对象;第二步将该对象内置的原型对象设置为构造函数prototype引用的那个原型对象;第 三步就是将该对象作为this参数调用构造函数,完成成员设置等初始化工作。对象建立之后,对象上的任何访问和操作都只与对象自身及其原型链上的那串对象 有关,与构造函数再扯不上关系了。换句话说,构造函数只是在创建对象时起到介绍原型对象和初始化对象两个作用。

    那么,我们能否自己定义一个对象来当作原型,并在这个原型上描述类,然后将这个原型设置给新创建的对象,将其当作对象的类呢?我们又能否将这个原型中的一个方法当作构造函数,去初始化新建的对象呢?例如,我们定义这样一个原型对象:

     var  Person  =    // 定义一个对象来作为原型类
    {
        Create: 
function (name, age)   // 这个当构造函数
        {
            
this .name  =  name;
            
this .age  =  age;
        },
        SayHello: 
function ()   // 定义方法
        {
            alert(
" Hello, I'm  "   +   this .name);
        },
        HowOld: 
function ()   // 定义方法
        {
            alert(
this .name  +   "  is  "   +   this .age  +   "  years old. " );
        }
    };

    这个JSON形式的写法多么象一个C#的类啊!既有构造函数,又有各种方法。如果可以用某种形式来创建对象,并将对象的内置的原型设置为上面这个“类”对象,不就相当于创建该类的对象了吗?

    但遗憾的是,我们几乎不能访问到对象内置的原型属性!尽管有些浏览器可以访问到对象的内置原型,但这样做的话就只能限定了用户必须使用那种浏览器。这也几乎不可行。

    那么,我们可不可以通过一个函数对象来做媒介,利用该函数对象的prototype属性来中转这个原型,并用new操作符传递给新建的对象呢?

    其实,象这样的代码就可以实现这一目标:

     function  anyfunc(){};            // 定义一个函数躯壳
    anyfunc.prototype  =  Person;      // 将原型对象放到中转站prototype
     var  BillGates  =   new  anyfunc();   // 新建对象的内置原型将是我们期望的原型对象

    不过,这个anyfunc函数只是一个躯壳,在使用过这个躯壳之后它就成了多余的东西了,而且这和直接使用构造函数来创建对象也没啥不同,有点不爽。

    可是,如果我们将这些代码写成一个通用函数,而那个函数躯壳也就成了函数内的函数,这个内部函数不就可以在外层函数退出作用域后自动消亡吗?而且,我们可以将原型对象作为通用函数的参数,让通用函数返回创建的对象。我们需要的就是下面这个形式:

     function  New(aClass, aParams)     // 通用创建函数
    {
        
function  new_()      // 定义临时的中转函数壳
        {
            aClass.Create.apply(
this , aParams);    // 调用原型中定义的的构造函数,中转构造逻辑及构造参数
        };
        new_.prototype 
=  aClass;     // 准备中转原型对象
         return   new  new_();           // 返回建立最终建立的对象
    };
    
    
var  Person  =          // 定义的类
    {
        Create: 
function (name, age)
        {
            
this .name  =  name;
            
this .age  =  age;
        },
        SayHello: 
function ()
        {
            alert(
" Hello, I'm  "   +   this .name);
        },
        HowOld: 
function ()
        {
            alert(
this .name  +   "  is  "   +   this .age  +   "  years old. " );
        }
    };
    
    
var  BillGates  =  New(Person, [ " Bill Gates " 53 ]);   // 调用通用函数创建对象,并以数组形式传递构造参数
    BillGates.SayHello();
    BillGates.HowOld();

    alert(BillGates.constructor 
==  Object);      // 输出:true

    这里的通用函数New()就是一个“语法甘露”!这个语法甘露不但中转了原型对象,还中转了构造函数逻辑及构造参数。

    有趣的是,每次创建完对象退出New函数作用域时,临时的new_函数对象会被自动释放。由于new_的prototype属性被设置为新的原型 对象,其原来的原型对象和new_之间就已解开了引用链,临时函数及其原来的原型对象都会被正确回收了。上面代码的最后一句证明,新创建的对象的 constructor属性返回的是Object函数。其实新建的对象自己及其原型里没有constructor属性,那返回的只是最顶层原型对象的构造 函数,即Object。

    有了New这个语法甘露,类的定义就很像C#那些静态对象语言的形式了,这样的代码显得多么文静而优雅啊!

    当然,这个代码仅仅展示了“语法甘露”的概念。我们还需要多一些的语法甘露,才能实现用简洁而优雅的代码书写类层次及其继承关系。好了,我们再来看一个更丰富的示例吧:

     // 语法甘露:
     var  object  =      // 定义小写的object基本类,用于实现最基础的方法等
    {
        isA: 
function (aType)    // 一个判断类与类之间以及对象与类之间关系的基础方法
        {
            
var  self  =   this ;
            
while (self)
            {
                
if  (self  ==  aType)
                  
return   true ;
                self 
=  self.Type;
            };
            
return   false ;
        }
    };
    
    
function  Class(aBaseClass, aClassDefine)     // 创建类的函数,用于声明类及继承关系
    {
        
function  class_()    // 创建类的临时函数壳
        {
            
this .Type  =  aBaseClass;     // 我们给每一个类约定一个Type属性,引用其继承的类
             for ( var  member  in  aClassDefine)
                
this [member]  =  aClassDefine[member];     // 复制类的全部定义到当前创建的类
        };
        class_.prototype 
=  aBaseClass;
        
return   new  class_();
    };
    
    
function  New(aClass, aParams)    // 创建对象的函数,用于任意类的对象创建
    {
        
function  new_()      // 创建对象的临时函数壳
        {
            
this .Type  =  aClass;     // 我们也给每一个对象约定一个Type属性,据此可以访问到对象所属的类
             if  (aClass.Create)
              aClass.Create.apply(
this , aParams);    // 我们约定所有类的构造函数都叫Create,这和DELPHI比较相似
        };
        new_.prototype 
=  aClass;
        
return   new  new_();
    };

    
// 语法甘露的应用效果:    
     var  Person  =  Class(object,       // 派生至object基本类
    {
        Create: 
function (name, age)
        {
            
this .name  =  name;
            
this .age  =  age;
        },
        SayHello: 
function ()
        {
            alert(
" Hello, I'm  "   +   this .name  +   " "   +   this .age  +   "  years old. " );
        }
    });
    
    
var  Employee  =  Class(Person,     // 派生至Person类,是不是和一般对象语言很相似?
    {
        Create: 
function (name, age, salary)
        {
            Person.Create.call(
this , name, age);   // 调用基类的构造函数
             this .salary  =  salary;
        },
        ShowMeTheMoney: 
function ()
        {
            alert(
this .name  +   "  $ "   +   this .salary);
        }
    });

    
var  BillGates  =  New(Person, [ " Bill Gates " 53 ]);
    
var  SteveJobs  =  New(Employee, [ " Steve Jobs " 53 1234 ]);
    BillGates.SayHello();
    SteveJobs.SayHello();
    SteveJobs.ShowMeTheMoney();
    
    
var  LittleBill  =  New(BillGates.Type, [ " Little Bill " 6 ]);    // 根据BillGate的类型创建LittleBill
    LittleBill.SayHello();
    
    alert(BillGates.isA(Person));       
// true
    alert(BillGates.isA(Employee));      // false
    alert(SteveJobs.isA(Person));        // true
    alert(Person.isA(Employee));         // false
    alert(Employee.isA(Person));         // true

    “语法甘露”不用太多,只要那么一点点,就能改观整个代码的易读性和流畅性,从而让代码显得更优雅。有了这些语法甘露,JavaScript就很像一般对象语言了,写起代码了感觉也就爽多了!

    令人高兴的是,受这些甘露滋养的JavaScript程序效率会更高。因为其原型对象里既没有了毫无用处的那些对象级的成员,而且还不存在 constructor属性体,少了与构造函数间的牵连,但依旧保持了方法的共享性。这让JavaScript在追溯原型链和搜索属性及方法时,少费许多 工夫啊。

    我们就把这种形式称为“甘露模型”吧!其实,这种“甘露模型”的原型用法才是符合prototype概念的本意,才是的JavaScript原型的真谛!

    想必微软那些设计AJAX架构的工程师看到这个甘露模型时,肯定后悔没有早点把AJAX部门从美国搬到咱中国的观音庙来,错过了观音菩萨的点化。 当然,我们也只能是在代码的示例中,把Bill Gates当作对象玩玩,真要让他放弃上帝转而皈依我佛肯定是不容易的,机缘未到啊!如果哪天你在微软新出的AJAX类库中看到这种甘露模型,那才是真正 的缘分!

 

分享到:
评论

相关推荐

    HTML&JavaScript经典PPT 讲的都是重点

    &lt;SCRIPT language="JavaScript" &gt; function compute(op) { var num1,num2; num1=parseFloat(document.myform.num1.value); num2=parseFloat(document.myform.num2.value); if (op=="+") document.myform....

    网页教程代码参考

    &lt;br&gt;HTML&lt;br&gt;HTML教程&lt;br&gt;&lt;br&gt;HTML代码示例&lt;br&gt;&lt;br&gt;HTML参考(Reference)&lt;br&gt;&lt;br&gt;HTML知识库&lt;br&gt;&lt;br&gt;CSS&lt;br&gt;CSS教程&lt;br&gt;&lt;br&gt;CSS代码示例&lt;br&gt;&lt;br&gt;CSS参考(Reference)&lt;br&gt;&lt;br&gt;Javascript&lt;br&gt;Javascript教程&lt;br&gt;&lt;br&gt;...

    javascrip上百技术总集

    初看原型&lt;br&gt;悟透JavaScript(李站老师)-对象素描&lt;br&gt;悟透JavaScript(李站老师)-放下对象&lt;br&gt;悟透JavaScript(李站老师)-构造对象&lt;br&gt;悟透JavaScript(李站老师)-原型扩展&lt;br&gt;用javascript操作 asp .net ...

    悟透JavaScript.rar

    "悟透JavaScript"这份教程资料,对于初学者和有志于成为专业前端开发者的人员来说,无疑是一份宝贵的资源。通过系统学习这份教程,可以深入理解JavaScript,并在网页制作中实现各种丰富的交互功能。 JavaScript的...

    javascript程序设计

    &lt;title&gt;一段简单的JavaScript代码&lt;/title&gt; &lt;script language="javascript"&gt; window.alert("欢迎光临本网站"); &lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;h3&gt;这是一段简单的JavaScript代码。&lt;/h3&gt; &lt;/body&gt; &lt;/html&gt; ``` - **知识点**...

    [JavaScript]Javascript 设置与读取Co 三级select列表

    在网页中,这种三级联动通常涉及到多个`&lt;select&gt;`元素,它们之间的选项关联和更新需要通过JavaScript来实现。 首先,我们需要理解HTML的`&lt;select&gt;`元素和`&lt;option&gt;`元素。`&lt;select&gt;`元素用于创建一个下拉列表,而`...

    悟透JAVASCRIPT 美绘本

    悟透 JAVASCRIPT 美绘本 插图版

    悟透JavaScript(js)

    ### 悟透JavaScript(js):回归数据与代码的本质 #### 一、引言 《悟透JavaScript》这本书由李战(leadzen)撰写,旨在深入浅出地讲解JavaScript的核心概念和技术要点。本书通过生动有趣的比喻,将抽象的编程概念...

    悟透javascript(精简版)

    ### 悟透JavaScript核心知识点解析 #### 一、编程世界的本质:数据与代码 在《悟透JavaScript(精简版)》这本书中,作者李战(leadzen)以独特的视角探讨了编程世界的本质——数据与代码之间的关系。他通过生动的...

    轻轻松松学用javascript编程 、悟透JavaScript

    "轻轻松松学用javascript编程" 和 "悟透JavaScript" 这两个主题,旨在帮助初学者和进阶者深入理解和掌握这门语言。 JavaScript的核心概念包括变量、数据类型、操作符、流程控制、函数和对象。变量是存储数据的容器...

    悟透JavaScript.pdf

    ### 悟透JavaScript核心知识点解析 #### 一、编程世界的本质:数据与代码 **悟透JavaScript**这本书深入探讨了编程世界的核心——数据与代码之间的关系。在编程的世界里,一切皆可归结为这两种基本元素:数据与...

    javascript 写的计算器

    这些按钮可以通过`&lt;button&gt;`元素创建,并使用`id`或`class`属性来区分不同类型的按钮。HTML代码可能如下所示: ```html &lt;div id="calculator"&gt; &lt;input type="text" id="display" disabled&gt; &lt;div class="buttons"&gt;...

    JavaScript for breakfast Crunching scripts for your coffee table (含源代码)

    &lt;br&gt;JavaScript for breakfast Crunching scripts for your coffee table&lt;br&gt;&lt;br&gt;包含源代码&lt;br&gt;&lt;br&gt;&lt;br&gt;Tom Dell\'Aringa &lt;br&gt;&lt;br&gt;Published by DMXzone.com &lt;br&gt;&lt;br&gt;Dynamic Zones International &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;...

    js星级评论打分效果

    &lt;span&gt;js星级评论打分&lt;/span&gt; &lt;ul&gt; &lt;li&gt; &lt;a href="javascript:;"&gt;1&lt;/a&gt; &lt;/li&gt; &lt;li&gt; &lt;a href="javascript:;"&gt;2&lt;/a&gt; &lt;/li&gt; &lt;li&gt; &lt;a href="javascript:;"&gt;3&lt;/a&gt; &lt;/li&gt; ...

    一个月悟透JavaScript

    "一个月悟透JavaScript"这本书显然旨在帮助读者在短时间内深入理解和掌握这门语言的精髓。JavaScript以其灵活、动态的特性,使得网页交互变得更加丰富和生动。下面,我们将根据书名和描述,探讨JavaScript的一些关键...

    悟透javascript.pdf

    - 关系运算符:`&gt;`、`&lt;`、`&gt;=`、`&lt;=`、`==`、`!=`、`===`、`!==`等。 - 逻辑运算符:`&&`(与)、`||`(或)、`!`(非)等。 - 赋值运算符:`=`、`+=`、`-=`等。 3. **控制结构**: - 条件语句:`if`、`else if...

    元旦倒计时JavaScript代码

    &lt;div class="djs"&gt; &lt;p&gt;元旦倒计时:&lt;/p&gt; &lt;div class="time"&gt; &lt;span class="day"&gt;0&lt;/span&gt; &lt;span&gt;天&lt;/span&gt; &lt;span class="hour"&gt;1&lt;/span&gt; &lt;span&gt;小时&lt;/span&gt; &lt;span class="minute"&gt;2&lt;/span&gt; &lt;span&gt;分&lt;/span&gt; ...

    JavaScript权威指南(5th)

    This book is both an example-driven programmer's guide and a keep-on-your-desk reference, with new chapters that explain everything you need to know to get the most out of JavaScript, including:&lt;br&gt;...

    JSP图书管理系统

    &lt;script language="JavaScript"&gt;var when=new Date(); document.write("&lt;h4&gt;"); document.write(when.getYear()+"年"); document.write((when.getMonth()+1)+"月"); document.write(when.getDate()+...

    js效果页面实例及说明文档包html版

    绝对的经典javascript收藏 包含了各个种类的js校验实例&lt;br&gt;web开发绝妙帮手&lt;br&gt;&lt;br&gt;javascript收藏 &lt;br&gt;1.页面校验 &lt;br&gt;1.文本框约束输入 &lt;br&gt;2.表单校验工具库 &lt;br&gt;3.文本框部分内容不让改变 &lt;br&gt;2.下拉框类 &lt;br&gt;...

Global site tag (gtag.js) - Google Analytics