全面理解面向对象的 JavaScript(来自ibm)(5)

如果您已对原型、函数构造器、闭包和基于上下文的 this 有了充分的理解,那么理解 Simple Inheritance 的实现原理也并非相当困难。从本质上讲,var Person = Class.extend(...)该语句中,左边的 Person 实际上是获得了由 Class 调用 extend 方法返回的一个构造器,也即一个 function 对象的引用。顺着这个思路,我们继续介绍 Simple Inheritance 是如何做到这一点,进而实现了由原型继承方式到类式继承方式的转换的。图 2 是 Simple Inheritance 的源码及其附带注释。为了方便理解,用中文对代码逐行补充说明。

图 2.Simple Inheritance 源码解析

图 2.Simple Inheritance 源码解析

 

抛开代码第二部分,整体连贯地考察第一和第三部分会发现,extend 函数的根本目的就是要构造一个具有新原型属性的新构造器。我们不禁感叹 John Resig的大师手笔及其对 JS 语言本质把握的细腻程度。至于 John Resig是如何想到这样精妙的实现方法,感兴趣的读者可以阅读本文 (),其中有详细介绍关于最初设计 Simple Inheritance 的思维过程。

JavaScript 私有成员实现

到此为止,如果您任然对 JavaScript 面向对象持怀疑态度,那么这个怀疑一定是,JavaScript 没有实现面向对象中的信息隐藏,即私有和公有。与其他类式面向对象那样显式地声明私有公有成员的方式不同,JavaScript 的信息隐藏就是靠闭包实现的。见 :

清单 7. 使用闭包实现信息隐藏

复制代码 代码如下:


// 声明 User 构造器
 function User( pwd ) {
    // 定义私有属性
    var password = pwd;
    // 定义私有方法
    function getPassword() {
        // 返回了闭包中的 password
        return password;
    }
    // 特权函数声明,用于该对象其他公有方法能通过该特权方法访问到私有成员
    this.passwordService = function() {
        return getPassword();
    }
 }
 // 公有成员声明
 User.prototype.checkPassword = function( pwd ) {
    return this.passwordService() === pwd;
 };
 // 验证隐藏性
 var u = new User( "123456" );
 // 打印 true
 console.log( u.checkPassword( "123456" ) );
 // 打印 undefined
 console.log( u.password );
 // 打印 true
 console.log( typeof u.gePassword === "undefined" );

JavaScript 必须依赖闭包实现信息隐藏,是由其函数式语言特性所决定的。本文不会对函数式语言和闭包这两个话题展开讨论,正如上文默认您理解 JavaScript 中基于上下文的 this 一样。关于 JavaScript 中实现信息隐藏,Douglas Crockford在《 Private members in JavaScript 》()一文中有更权威和详细的介绍。

结束语

JavaScript 被认为是世界上最受误解的编程语言,因为它身披 c 语言家族的外衣,表现的却是 LISP 风格的函数式语言特性;没有类,却实也彻底实现了面向对象。要对这门语言有透彻的理解,就必须扒开其 c 语言的外衣,从新回到函数式编程的角度,同时摒弃原有类的面向对象概念去学习领悟它。随着近些年来 Web 应用的普及和 JS 语言自身的长足发展,特别是后台 JS 引擎的出现 ( 如基于 V8 的 NodeJS 等 ),可以预见,原来只是作为玩具编写页面效果的 JS 将获得更广阔发展天地。这样的发展趋势,也对 JS 程序员提出了更高要求。只有彻底领悟了这门语言,才有可能在大型的 JS 项目中发挥她的威力。

您可能感兴趣的文章:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wdzydw.html