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是Web开发中不可或缺的一部分,它提供了丰富的特性,如作用域、闭包、对象和原型链,这些都是理解和编写高效代码的关键。以下是对这些概念的详细解释: 1. **JavaScript变量作用域** - **函数作用域**:...
本文将深入探讨JavaScript中的封装和继承,以及它们在实际应用中的实现。 ### 封装(Encapsulation) 封装是面向对象编程中的关键概念,它涉及如何管理和保护数据,防止外部代码直接访问或修改对象的内部状态。在...
JavaScript中的对象有其原型,对象从原型继承方法和属性,这就意味着我们可以利用原型链(Prototype Chain)来实现面向对象的继承。 当我们讨论模块化时,常常会遇到模块封装的需求。模块封装的目的是通过提供一个...
这是最常见的继承方式,通过设置子类的`prototype`为父类的一个实例,使得子类可以直接访问父类的原型链上的属性和方法。 - 定义父类`Parent` - 定义子类`Son` - 设置`Son.prototype`为`new Parent()`,即`Son....
在JavaScript编程语言中,原型(Prototype)、作用域(Scope)和闭包(Closure)是三个核心概念,对于理解和编写高效、可维护的代码至关重要。本文将深入探讨这三个概念,并通过实例解析它们的工作原理。 首先,...
在JavaScript中,主要有两种继承模式:原型链继承和类(ES6中的class)继承。原型链继承是JavaScript早期的主要继承方式,它依赖于对象的原型(prototype)属性。而ES6引入的class语法糖,使得JavaScript的继承更加...
通过深入理解JavaScript中的原型和原型链,我们可以更好地设计面向对象的程序结构,实现更加灵活的继承和封装。掌握这些核心概念对于成为一名高效的JavaScript开发者至关重要。希望本文能够帮助读者更深刻地理解...
JavaScript使用原型链来实现继承,每个对象都有一个`__proto__`属性,指向其构造函数的原型对象。原型对象又可以通过`__proto__`链接到另一个对象,形成一个链式结构。 ```javascript function Animal(name) { ...
**继承**是JavaScript中通过原型链实现的。在JavaScript中,每个对象都有一个隐含的`__proto__`属性,指向其构造函数的`prototype`对象。如果在实例上查找某个属性或方法不存在,JavaScript会查找`__proto__`,然后...
4. **原型链封装**:JavaScript的面向对象特性基于原型继承,通过原型链可以封装共享属性和方法。通过`__proto__`或`Object.create()`,可以创建新对象并链接到现有对象,实现代码复用。 5. **类与构造函数封装**:...
JavaScript中的闭包和原型模型是理解其面向对象编程机制的关键概念。闭包是一种特性,允许函数访问并操作其...在实际编程中,闭包常用于封装变量、创建私有变量和实现模块化,而原型模型则用于实现对象的继承和多态性。
JavaScript的继承机制主要是基于原型链实现的,但ES6引入了类(class)的概念,让代码看起来更像传统的面向对象语言。尽管如此,JavaScript的类实际上仍然是基于函数和原型的语法糖。你可以使用`extends`关键字创建...
构造函数、原型链、继承、多态等都是在JavaScript中实现封装的关键概念。 4. **Promise封装**:Promise是处理异步操作的重要工具,它可以解决回调地狱问题,提高代码的可读性和可维护性。Bluebird、Q等库提供了更...
JavaScript中的继承主要通过原型链实现。`Book`基类定义了一个简单的书籍对象,包含`name`属性和用于验证名称的`check`及获取名称的`getName`方法。要实现继承,可以使用如下的`extend`函数: ```javascript ...
JavaScript中的继承封装多态特性,不仅可以使得代码更加模块化和易于维护,还能帮助实现更加丰富和灵活的应用程序。理解这些面向对象的特性,对于提高编程技能和编写高质量的JavaScript代码具有重要意义。
1. **面向对象编程(OOP)**:在JavaScript中,面向对象编程主要通过构造函数、原型链和类(ES6引入)来实现。理解如何创建对象、继承和封装是提升代码复用性和可维护性的重要一环。 2. **模块化**:JavaScript的...
在JavaScript中,多态、继承和封装是面向对象编程的核心概念。封装是将数据和方法组织在一起,使得数据不被外部直接访问,从而保护数据的安全性。继承则是通过创建一个新类(子类)来继承已有类(父类)的属性和方法...