在使用一些 Java
script
框架时,或许会看到类似的代码
var MyClass = new Class({
initialize:
function(param, ...) {
this.param =
param;
...
},
func1: function(...)
{
...
}
});
var myObj = new
MyClass(param);
myObj.func1(...);
这是一种典型的面向对象的类机制应用,与原生的
Javascript 类机制相比,显得更为清晰和自然。并且,在此基础上,实现类的继承也较为方便。那么,这是如何实现的呢?
众所周知,在
Javascript 中,将一个函数作为构造器,可以创建出一个对象,上面的代码可以简单的写成:
function
MyClass(param) {
this.param = param;
this.func1 = function(..)
{
...
};
}
var myObj = new
MyClass(param);
myObj.func1();
其实还是蛮简单的,也不难理解。不过如果要构建一套大型的
Javascript
类库,可能就会比较混乱,从一堆代码中,要找出哪些是类,哪些是函数,哪些是类方法,哪些是类属性,是一件痛苦的事。
当然,这里并不是要比较它们的优劣,只是好奇
new Class 的实现方式而已。
在上面的代码中,使用 new MyClass() 这样的语句,意味着 MyClass
必须是一个函数,同时也就意味着 new Class 需要返回一个函数对象,从字面的意思上可以看出,函数 initialize
是当做构造函数来使用的,所以,new Class 返回的函数中,必须使用 initialize
来对对象进行初始化。基于这样的分析,可以得出以下代码:
function Class(argu) {
return
function() {
var init = argu['initialize'] || function() {}; //如果没有构造函数
initialize,使用一个空函数作为默认构造函数
for(var p in argu) {
this[p] =
argu[p];
}
init.apply(this, arguments); //使用当前函数的 this 来代替函数
initialize 原有的 this
}
}
上面的代码并不够严谨,但用来说明问题
已经足够了。需要注意 init.apply(this, arguments)
这一句,这里有几个变量的指代,一个是 this,原本 initialize 中默认的 this,现在已被替代为返回的这个匿名函数的
this,而这个匿名函数,是通过 new Class 新建的自定义类的构造器。另外一个是 arguments,它指代的是匿名函数的参数,也就是上面的 new
MyClass(param) 中的 param。
this
的转换有些让人头晕,那么有没有更为简单的方法呢?请看下面的代码:
function Class(argu) {
var
obj = argu['initialize'] || function() {};
for(var p in argu)
{
obj.prototype[p] = argu[p]; //注意,这里用的是
prototype
}
return obj; //
其實还是返回一個函數
}
呵呵,感觉直白了许多。
这就完成了一个简单的类机制的构建。通过这种机制,可以创建类的构造函数、方法及属性,但这些显然都是公有的,那么,如何实现私有变量及方法呢?
我们知道,Javascript
类的私有变量可以通过闭包的机制来完成。但使用 new Class({...})
的方式转换后,显然很难形成有效的闭包。如何绕过这个问题呢?
Javascript 提供了两个方法:eval() 及函数对象的 toString()
方法,前者较为常见,而后者,可用于获取函数的具体代码。通过这两个方法,可以简单的模拟类的私有变量:
function
Class(argu) {
var _ = argu['private'] || {};
eval('var obj = ' +
(argu['initialize'] || function() {}).toString());
for(var p in argu)
{
if(p == 'initialize' || p ==
'private')
continue;
if(typeof argu[p] ==
'function')
eval('obj.prototype[p] = ' +
argu[p].toString());
else
obj.prototype[p] =
argu[p];
}
return obj;
}
通过函数对象的 toString()
方法提取出函数的代码,并使用 eval
方法执行这些代码,这样就可以构造出一个有效的闭包范围,从而实现私有机制。我们可以如下应用:
var Person = new
Class({
private: {
height: 160,
weight:
50
},
initialize: function(name, height, weight)
{
this.name = name;
_.height = height ||
_.height;
_.weight = weight || _.weight;
},
show:
function() {
alert('Name:' + this.name + '\nheight:' + _.height +
'\nweight:' + _.weight);
}
});
var my = new
Person("Zh");
my.show();
看起来不不错,不过在实际应用中,其实并没有太大的用途。主要是效率上,相比通常的实现方式,大概需要多花四倍的时间。在大型类库的构建上,这是不可容忍的,而小型的应用中,实现下面的代码更为简单直接:
function
MyClass(param) {
var privateVar = ...;
this.param =
param;
this.func = function()
{
alert(privateVar);
};
} |
相关推荐
JavaScript模拟类机制及私有变量方法思路 在JavaScript中,原生并不支持传统的类继承和私有成员,而开发中有时需要类似的功能。于是,开发者们就发明了各种方法来模拟类机制,以及实现类似私有变量的功能。本文将...
在JavaScript中,通常使用构造函数来模拟类的行为。构造函数内部定义的变量可以分为两种类型:公有变量(Public Variable)和私有变量(Private Variable)。 - **公有变量**:可以在构造函数外部被访问和修改的...
### JavaScript ES6 实现类的私有变量方法详解 #### 一、背景介绍 随着ECMAScript 2015(通常称为ES6)的引入,JavaScript语言经历了一次重大更新,提供了许多新特性和改进,其中包括对面向对象编程的支持增强。...
在JavaScript中,虽然没有像Java或C++那样的内置关键字来直接声明私有变量或方法,但我们可以通过一些技巧来模拟这种行为。 1. **闭包**:这是JavaScript中实现私有变量和私有函数最常见的方法。闭包是一种特殊的...
在JavaScript中,由于没有真正的私有变量(不像Java或C#等语言),我们可以利用闭包特性来模拟私有变量。闭包可以让内部函数访问其外部函数的变量,即使外部函数已经执行完毕,闭包仍然能保留对外部变量的引用。 ...
了解并熟练掌握JavaScript中的面向对象和私有变量的概念,能够帮助开发者编写更加安全、模块化的代码,提高软件的可维护性和可扩展性。同时,这也涉及到JavaScript的其他高级特性,如闭包、作用域以及函数作为一等...
综上所述,ProtectJS库通过JavaScript的闭包机制实现了模拟私有属性和方法的功能,为开发者提供了更安全、更模块化的代码组织方式。它在浏览器和Node.js环境下均适用,使得私有化编程在JavaScript世界中成为可能。...
需要注意的是,虽然闭包可以保护变量不被外部直接访问,但并非所有的 JavaScript 开发者都推荐使用闭包来模拟私有变量和方法。这是因为闭包会阻止变量所占用的内存被垃圾回收,这可能会导致内存泄漏,尤其是在闭包...
- **执行效率**:访问闭包中的私有变量可能比直接访问对象属性稍慢,因为需要额外的函数调用和作用域查找。 在实际应用中,这些影响通常是微不足道的,除非在性能至关重要的场景下。对于大多数JavaScript应用程序来...
JavaScript中的私有成员是通过巧妙地利用闭包和作用域规则来实现的,因为JavaScript本身并不直接支持传统的类和私有变量。以下我们将详细探讨如何创建和使用私有成员。 首先,JavaScript对象是由一系列键值对组成的...
在给定的代码示例中,aa是一个私有变量,fun1和fun2是私有方法,它们都只能在类的内部访问。 另一方面,公开成员是指通过this关键字声明的变量和方法,它们可以被外部访问。例如,在类的外部,bb是一个公开变量,...
在JavaScript中,闭包可以用来模拟类的机制,并实现基于类的面向对象编程。 在本文中,我们首先介绍了闭包的概念和特征,然后介绍了基于闭包的JavaScript面向对象编程框架的设计和实现。该框架包括三个主要部分:类...
现在,我们通过一个具体的例子来说明如何在JavaScript中使用JSON对象来模拟类定义语法,并实现私有成员、受保护成员和静态成员。 示例代码中,首先定义了一个自定义函数Class,该函数接收两个参数:第一个是类名字...
在JavaScript中,虽然没有内置的私有变量或方法,但可以通过一些技巧来模拟实现。本文将深入探讨如何在JavaScript中实现私有化。 首先,我们可以利用闭包来实现私有变量。闭包是一种特殊的作用域,它可以访问并操作...
闭包允许函数访问和修改外部环境的状态,为实现私有变量和模拟类的封装提供了可能。 6. **原型扩展与自定义**: 通过`Object.create()`方法或者直接修改`__proto__`属性,可以为对象添加新的方法或属性,实现对...
JavaScript中的原型机制是实现继承的基础。每个JavaScript对象都有一个内部链接指向另一个对象——它的原型。当尝试访问一个对象的属性时,如果找不到该属性,JavaScript引擎会沿着原型链查找。 **静态属性和方法**...
虽然JavaScript没有提供严格的封装机制,但我们可以通过设置私有变量和公共方法来实现类似的功能。通常,开发者会使用闭包或者ES6的类来模拟封装。 **示例代码:** ```javascript function Person(name, age) { ...
- **构造函数**:虽然JavaScript不支持类的概念,但可以通过构造函数来模拟类的行为,创建具有相同属性和方法的对象实例。 - **闭包**:JavaScript中的闭包特性使得私有成员的实现成为可能,通过闭包可以实现封装,...