`
openxtiger
  • 浏览: 151235 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

采有闭包、原型链实现Js的真正继承和封装

阅读更多

 

Javascript对象创建过程:

1.初始化对象

2.将对象的__proto__=类的prototype属性

3.用类构造对象

 

__proto__:为原型链

 

每个对象都会在其内部初始化一个属性,就是__proto__,当我们访问一个对象的属性时,如果这个对象内部不存在这个属性,那么他就会去__proto__里找这个属性,这个__proto__又会有自己的__proto__,于是就这样一直找下去,也就是我们平时所说的原型链的概念。

 

2.将对象的__proto__ = 类的prototype属性,且prototype是一个对象。

 

因此为了实现继承,我们只要将对象的的原型链进行修改即可。

由于__proto__在对象创建后才可出现,其实这个属性也不能直接访问(原则上),但我们在类定义时就得确认类的继承关系。此时,我们突然发现以上加粗的公式。

类的prototype = 对象的 __proto__。好吧,现在只要在类的prototype上做文章即可。

 

可以想象,如果要加入父类的原型链,只有两种方法:

1.将子类的prototype=父类的prototype。这个非常不好,因为既然相等了,此时改变任何一个类的prototype,都会影响另一个类的prototype

2.将子类的prototype=父类的对象。这个是一个不错的想法,修改了类属性时,只是修改父类对象的一个实例,并不会修改父类的类

然到就这样结束,不会的。为什么不会呢?因为我们在定义类时,并不想让类分配内存,我这类也许只是定义,未必会用,那么以上定义方式就悲剧了,子类的prototype=父类的对象(定义时就创建了父类的对象)。当然创建对象是必须的,可是我们是否可以创建一个不用分配内存(或很少内存)的对象呢,是的,你猜到了,定义一个什么都没有类,比如 var F = function(){};  new F(); 

好了,现在有空对象了,将子类的prototype=new F(); 纳尼?子类只是加入了F的原型链。好吧,我承认我有引导错误的行为,以上的第一种方法(将子类的prototype=父类的prototype)并不是不好,而是要看时机,因为我们害怕它们会相互绑定。但是时机来了,F类,我们并不会修改它任何属性(是的,它只是一个用来做空对象了,谁改了我和谁急)。Year,我们很巧妙的将F.prototype=父类的prototype

 

以上说的太认真了,好吧,其实就是那么简单:

 

var C = function(){}
var P = function(){}
var F = function(){}

C.prototype = new F();
F.prototype = P.prototype;

 以上只是完成了继承的大部分。其实由于类的构造函数被绑在类的prototype上,即prototype.constructor方法。好了,我们既然很粗鲁将子类的prototype移情,好在事情还没发展到需要分手的地步,

我们将子类的prototype.constructor=子类,即 

 

C.prototype.constructor = C;

 好了,既养了小三,又不失原配。我的GOD,i love javascript!

 

继承完成了,来谈一下闭包吧

 

 

(function(){

})();

 有此方法可以保护局部函数和局部变量,产生类的private效果。

 

可以把一个外部对象在期间进行封装,封装过程产生的局部函数和局部变量不会被外部访问。

 

var Js3={};  
  
(function(){  
          
        var ua = navigator.userAgent.toLowerCase(),  
        check = function(r) {  
            return r.test(ua);  
        },  
       isChrome = check(/\bchrome\b/);  
  
  
       Js3.isChrome = isChrome;  
  
}(); 

 

 其中的ua,isChrome变量,check函数只是局部的。

 

有了以上的概念,我们即可实现“采有闭包、原型链实现Js的真正继承和封装”。

 

 

Js3.apply = function(o, c) {
    if (o && c && typeof c == 'object') {
        for (var p in c) {
            o[p] = c[p];
        }
    }
    return o;
};
Js3.override = function(origclass, overrides) {
    if (overrides) {
        var p = origclass.prototype;
        Js3.apply(p, overrides);
        if (Js3.isIE && overrides.hasOwnProperty('toString')) {
            p.toString = overrides.toString;
        }
    }
};
Js5.extend = function() {
    var oc = Object.prototype.constructor;
    return function(sb, sp, overrides) {
        var coverrides = overrides;
        if (!overrides) {
            coverrides = sp;
            sp = sb;
        }

        var F = function() {
        }, sbp, spp = sp.prototype;
        F.prototype = spp;

        coverrides = coverrides(spp);  //闭包调用

        if (!overrides) {
            sb = coverrides.constructor != oc ? coverrides.constructor : function() {
                sp.apply(this, arguments);
            };
        }
        sbp = sb.prototype = new F();
        sbp.constructor = sb;

        if (spp.constructor == oc) {
            spp.constructor = sp;
        }

        Js3.override(sb, coverrides);

        return sb;
    };
}();

 

应用如下:

var PClass = function() {
};
var Class = function() {
};
Js5.extend(Class, PClass, function(_super) { 
 //_super = super class,此函数将成为闭包,并被Js5.extend调用。
    var _prv = { // private:

    };
    return {  // public:

    };
});
 
注:类定义中的_prv等变量为静态变量,所有类的实例对象将共享变量。
分享到:
评论

相关推荐

    深度探讨javascript函数的原型链和闭包

    闭包常常用于封装变量和实现私有方法,提高代码的封装性和安全性。 总结一下,JavaScript中的函数不仅是一种数据类型,还是实现面向对象编程的核心工具。通过原型链,我们可以实现基于原型的继承;通过闭包,我们...

    JavaScript作用域、闭包、对象与原型链概念及用法实例总结

    JavaScript是Web开发中不可或缺的一部分,它提供了丰富的特性,如作用域、闭包、对象和原型链,这些都是理解和编写高效代码的关键。以下是对这些概念的详细解释: 1. **JavaScript变量作用域** - **函数作用域**:...

    JS封装和继承-入门级

    本文将深入探讨JavaScript中的封装和继承,以及它们在实际应用中的实现。 ### 封装(Encapsulation) 封装是面向对象编程中的关键概念,它涉及如何管理和保护数据,防止外部代码直接访问或修改对象的内部状态。在...

    JavaScript的模块化:封装(闭包),继承(原型) 介绍

    JavaScript中的对象有其原型,对象从原型继承方法和属性,这就意味着我们可以利用原型链(Prototype Chain)来实现面向对象的继承。 当我们讨论模块化时,常常会遇到模块封装的需求。模块封装的目的是通过提供一个...

    JS继承与闭包及JS实现继承的三种方式

    这是最常见的继承方式,通过设置子类的`prototype`为父类的一个实例,使得子类可以直接访问父类的原型链上的属性和方法。 - 定义父类`Parent` - 定义子类`Son` - 设置`Son.prototype`为`new Parent()`,即`Son....

    原型、作用域、闭包的完整解释(一)

    在JavaScript编程语言中,原型(Prototype)、作用域(Scope)和闭包(Closure)是三个核心概念,对于理解和编写高效、可维护的代码至关重要。本文将深入探讨这三个概念,并通过实例解析它们的工作原理。 首先,...

    005课-继承作用域闭包.rar

    在JavaScript中,主要有两种继承模式:原型链继承和类(ES6中的class)继承。原型链继承是JavaScript早期的主要继承方式,它依赖于对象的原型(prototype)属性。而ES6引入的class语法糖,使得JavaScript的继承更加...

    js高端系列教程(26)——JavaScript探秘:强大的原型和原型链.docx

    通过深入理解JavaScript中的原型和原型链,我们可以更好地设计面向对象的程序结构,实现更加灵活的继承和封装。掌握这些核心概念对于成为一名高效的JavaScript开发者至关重要。希望本文能够帮助读者更深刻地理解...

    Javascript中的封装与继承

    JavaScript使用原型链来实现继承,每个对象都有一个`__proto__`属性,指向其构造函数的原型对象。原型对象又可以通过`__proto__`链接到另一个对象,形成一个链式结构。 ```javascript function Animal(name) { ...

    Javascript面向对象特性实现(封装、继承、接口).doc

    **继承**是JavaScript中通过原型链实现的。在JavaScript中,每个对象都有一个隐含的`__proto__`属性,指向其构造函数的`prototype`对象。如果在实例上查找某个属性或方法不存在,JavaScript会查找`__proto__`,然后...

    javascript 经典封装

    4. **原型链封装**:JavaScript的面向对象特性基于原型继承,通过原型链可以封装共享属性和方法。通过`__proto__`或`Object.create()`,可以创建新对象并链接到现有对象,实现代码复用。 5. **类与构造函数封装**:...

    javascript闭包模型与原型模型(共31张PPT).pptx

    JavaScript中的闭包和原型模型是理解其面向对象编程机制的关键概念。闭包是一种特性,允许函数访问并操作其...在实际编程中,闭包常用于封装变量、创建私有变量和实现模块化,而原型模型则用于实现对象的继承和多态性。

    Advanced JavaScript (closures,prototype,inheritance)

    JavaScript的继承机制主要是基于原型链实现的,但ES6引入了类(class)的概念,让代码看起来更像传统的面向对象语言。尽管如此,JavaScript的类实际上仍然是基于函数和原型的语法糖。你可以使用`extends`关键字创建...

    国内外javascript经典封装

    构造函数、原型链、继承、多态等都是在JavaScript中实现封装的关键概念。 4. **Promise封装**:Promise是处理异步操作的重要工具,它可以解决回调地狱问题,提高代码的可读性和可维护性。Bluebird、Q等库提供了更...

    简洁理解JavaScript中的封装与继承特性_.docx

    JavaScript中的继承主要通过原型链实现。`Book`基类定义了一个简单的书籍对象,包含`name`属性和用于验证名称的`check`及获取名称的`getName`方法。要实现继承,可以使用如下的`extend`函数: ```javascript ...

    JavaScript 继承 封装 多态实现及原理详解

    JavaScript中的继承封装多态特性,不仅可以使得代码更加模块化和易于维护,还能帮助实现更加丰富和灵活的应用程序。理解这些面向对象的特性,对于提高编程技能和编写高质量的JavaScript代码具有重要意义。

    国内外 JavaScript 经典封装

    1. **面向对象编程(OOP)**:在JavaScript中,面向对象编程主要通过构造函数、原型链和类(ES6引入)来实现。理解如何创建对象、继承和封装是提升代码复用性和可维护性的重要一环。 2. **模块化**:JavaScript的...

    JavaScript实现多态和继承的封装操作示例

    在JavaScript中,多态、继承和封装是面向对象编程的核心概念。封装是将数据和方法组织在一起,使得数据不被外部直接访问,从而保护数据的安全性。继承则是通过创建一个新类(子类)来继承已有类(父类)的属性和方法...

Global site tag (gtag.js) - Google Analytics