了解 Javascript 中的类和继承 - 新模式
Understanding Classes and Inheritance in Javascript - New Pattern
我正在为我正在构建的许多应用程序设计OOP继承模式。 Javascript有很多方法可以做到这一点,但我偶然发现了一种我非常喜欢的模式。但是现在我正在努力解决类和实例分离的需求。
我有一个名为 Root 的基本对象。它有一个称为继承的主方法。创建您使用的新对象
var Person = Root.inherit({
name : "",
height : 0,
walk : function() {},
talk : function() {}
});
然后要创建一个"实例",您将
var sally = Person.inherit({
name : "sally",
height : "5'6"
});
Sally 可以 .talk((,她可以 walk((,她有一个 .name 和一个 .height你可以用同样的方式让更多的人。
如果你想要一个构造函数,你使用
var Person = Root.inherit({
_construct : function() {
// do things when this object is inherited from
},
name : "",
height : 0,
walk : function() {},
talk : function() {}
});
它还具有 init 的能力,当对象首次在代码中定义时(单例使用此(
var Person = Root.inherit({
_init : function() {
// called at runtime, NOT called if an object is inherited from me
},
name : "",
height : 0,
walk : function() {},
talk : function() {}
});
如您所见,一切都使用 .inhert((。实际上没有类,也没有实例。一切都是某事的实例。到目前为止,我发现的唯一真正的问题是没有"类型"的概念,但是如果需要,您可以随时检查方法。此外,您不能保护"类",因为如果开发人员意外更改了"类",或者打算更改它,则可以在执行过程中更改"类"。
所以我的问题是:在javascript中是否需要对类结构和类的实例进行显式和受控的分离?将每个对象视为实例是否存在任何问题?
不,没有必要,因为Javascript是一种基于原型的语言,这意味着不涉及类。您只是在创建对象的克隆。
http://en.wikipedia.org/wiki/Prototype-based_programming
就类型的概念而言,类型是对象。
有关这方面的更多信息,一个很好的阅读是Stoyan Stefanov的Javascript模式,他有几种不同的创建模式来解决你的问题,包括从四人帮的设计模式中实现设计模式的示例。http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752
所以我的问题是:在javascript中是否需要对类结构和类的实例进行显式和受控的分离?将每个对象视为实例是否存在任何问题?
不是真的,如果你对它感到满意,那就好了。
更正常的 JavaScript 继承形式也做了同样的事情。你会经常看到这样的结构(为了简洁起见,严重削减了结构(:
function Base() {
}
Base.prototype.foo = function() {
};
function Derived() {
}
Derived.prototype = new Base();
。当然,new Base()
也是您创建Base
实例的方式。所以你的系统非常相似。
同样,以上是草图,而不是完整的示例。首先,通常你会看到构造和初始化是分开的,所以你不会从字面上看到Derived.prototype = new Base()
的东西,就像创建一个具有Base
prototype
的对象但没有实际调用Base
的东西(Derived
稍后会这样做(,但你明白了。当然,这种说法在某种程度上削弱了与您的系统的相似性,但我认为它根本没有破坏它。
归根结底,这都是关于对象(实例(的,这些对象可以直接使用(您的sally
(,也可以通过克隆或将它们设置为其他对象的原型来间接地为其他对象提供功能(Person
,Root
(。
Javascript的继承是典型的,这意味着所有对象都是一个实例。您实际上必须做额外的工作才能获得经典继承。
这就是我在javascript中的工作方式
// this is class
function person(){
// data is member variable
this.name = null;
this.id = null;
//member functions
this.set_name = _set_name;
this.get_name = _get_name;
this.set_id = _set_id;
this.get_id = _get_id;
function _set_name(name){
this.name = name;
}
function _get_name(name){
return this.name;
}
function _set_id(id){
this.id = id;
}
function _get_id(id){
return this.id;
}
}
// this is instance
var yogs = new person();
yogs.set_id(13);
yogs.set_name("yogs");
希望它可能会有所帮助
从一些基本对象开始...
// javascript prototypes - callback example - javascript objects
function myDummyObject () {
that = this;
} // end function myDummyObject ()
// begin dummy object's prototype
myDummyObject.prototype = {
that : this,
// add a simple command to our dummy object and load it with a callback entry
say : function () {
var that = this;
console.log('speaking:');
that.cb.run("doSay");
}
} // end myDummyObject proto
使用子原型扩展。
// here we addon the callback handler... universally self sufficient object
var cb = {
that : this, // come to papa ( a link to parent object [ myDummyObject ] )
jCallback : new Array(new Array()), // initialize a javascript 2d array
jCallbackID : -1, // stores the last callback id
add: function(targetFnc, newFunc) {
var that = this;
var whichID = that.jCallbackID++;
// target, addon, active
that.jCallback[that.jCallback.length] = { 'targetFunc' : targetFnc, 'newFunc' : newFunc, 'active' : true, 'id': whichID };
return whichID; // if we want to delete this later...
}, // end add
run: function(targetFnc) {
var that = this;
for(i=0;i <= that.jCallback.length - 1;i++) // go through callback list
if( that.jCallback[i]['targetFunc'] == targetFnc && that.jCallback[i]['active'] == true )
that.jCallback[i]['newFunc'](); // run callback.
}, // end run
remove: function (whichID) {
var that = this;
console.log('removing:' + whichID);
for(i=0;i <= that.jCallback.length - 1;i++) // go through callback list
if( that.jCallback[i]['id'] == whichID )
that.jCallback[i]['newFunc'](); // run callback.
} // end remove
}
// add the object to the dummy object...
myDummyObject.prototype.cb = cb;
例:
var testing = new myDummyObject();
testing.cb.add('doSay', function () { console.log('test: 213123123'); } );
// test remove...
var testid = testing.cb.add('doSay', function () { console.log('test: 12sad31'); } );
testing.cb.remove(testid);
testing.cb.add('doSay', function () { console.log('test: asdascccc'); } );
testing.cb.add('doSay', function () { console.log('test: qweqwe'); } );
testing.cb.add('doSay', function () { console.log('test: d121d21'); } );
testing.cb.add('doSay', function () { console.log('test: wwww'); } );
testing.say();
这对我来说似乎总是最容易理解的......只需创建继承类的新实例,然后遍历其变量和方法并将它们添加到主实例中。
var myPerson = new Person()
var myPerson.firstName = 'john';
var myPerson.lastName = 'smith';
var myPerson.jobTitle = 'Programmer';
var Person = function(){
//Use this to inherit classes
this._extendedClass = new Person_Job();
for(var i in this._extendedClass){
this[i] = this._extendedClass[i];
}
delete this._extendedClass;
this.firstName = '';
this.lastName = '';
}
var Person_Job = function() {
this.jobTitle = '';
}
- 显示模块模式在Knockout中设置模型的新实例
- jQuery自动完成标记新的标签设计模式
- 这是一个新的javascript工厂模式吗
- 防止模式背景覆盖在每个打开的新模式上变得更暗
- 以新模式访问作用域形式ng repeat
- 使用弹出模式中断k-pager-nav以确认/拒绝移动到新页面
- 使用模块模式时,如何创建对象的新实例
- 将 UI 模式对话框添加到新的 DIV 标记
- 用于初始化对象的编码模式 - 构造函数(新)与 Object.create()(Crockford)
- 如何在 Crockford 的新构造函数模式中共享“构造函数”功能
- 模式未使用新数据刷新
- 了解 Javascript 中的类和继承 - 新模式
- 打开一个新页面作为模式窗口
- 防止引导模式窗口在新选项卡/窗口中打开
- 创建新模型的正确控制器/视图模式是什么
- 我们如何使用新的运算符和工厂模式在JavaScript中创建类的实例
- 如何复制JavaScript's的提示函数在一个带有密码字段的新模式中
- 引导模式:关闭电流,打开新
- 如何在新的无模式对话中收集论点
- 代码镜像的新模式:检测流中的空行