Nic*_*ick 408
使用原型:
function Box(color) // Constructor
{
this.color = color;
}
Box.prototype.getColor = function()
{
return this.color;
};
Run Code Online (Sandbox Code Playgroud)
隐藏"颜色"(有点类似于私有成员变量):
function Box(col)
{
var color = col;
this.getColor = function()
{
return color;
};
}
Run Code Online (Sandbox Code Playgroud)
用法:
var blueBox = new Box("blue");
alert(blueBox.getColor()); // will alert blue
var greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green
Run Code Online (Sandbox Code Playgroud)
Bli*_*ixt 248
这是我有时在JavaScript中用于OOP类似行为的模板.如您所见,您可以使用闭包模拟私有(静态和实例)成员.什么new MyClass()将返回是只分配给该属性的对象this对象,并在prototype该对象"类".
var MyClass = (function () {
// private static
var nextId = 1;
// constructor
var cls = function () {
// private
var id = nextId++;
var name = 'Unknown';
// public (this instance only)
this.get_id = function () { return id; };
this.get_name = function () { return name; };
this.set_name = function (value) {
if (typeof value != 'string')
throw 'Name must be a string';
if (value.length < 2 || value.length > 20)
throw 'Name must be 2-20 characters long.';
name = value;
};
};
// public static
cls.get_nextId = function () {
return nextId;
};
// public (shared across instances)
cls.prototype = {
announce: function () {
alert('Hi there! My id is ' + this.get_id() + ' and my name is "' + this.get_name() + '"!\r\n' +
'The next fellow\'s id will be ' + MyClass.get_nextId() + '!');
}
};
return cls;
})();
Run Code Online (Sandbox Code Playgroud)
我被问及使用这种模式的继承,所以这里有:
// It's a good idea to have a utility class to wire up inheritance.
function inherit(cls, superCls) {
// We use an intermediary empty constructor to create an
// inheritance chain, because using the super class' constructor
// might have side effects.
var construct = function () {};
construct.prototype = superCls.prototype;
cls.prototype = new construct;
cls.prototype.constructor = cls;
cls.super = superCls;
}
var MyChildClass = (function () {
// constructor
var cls = function (surName) {
// Call super constructor on this instance (any arguments
// to the constructor would go after "this" in call(…)).
this.constructor.super.call(this);
// Shadowing instance properties is a little bit less
// intuitive, but can be done:
var getName = this.get_name;
// public (this instance only)
this.get_name = function () {
return getName.call(this) + ' ' + surName;
};
};
inherit(cls, MyClass); // <-- important!
return cls;
})();
Run Code Online (Sandbox Code Playgroud)
以及使用它的一个例子:
var bob = new MyClass();
bob.set_name('Bob');
bob.announce(); // id is 1, name shows as "Bob"
var john = new MyChildClass('Doe');
john.set_name('John');
john.announce(); // id is 2, name shows as "John Doe"
alert(john instanceof MyClass); // true
Run Code Online (Sandbox Code Playgroud)
如您所见,这些类正确地相互交互(它们共享静态id MyClass,announce方法使用正确的get_name方法等)
需要注意的一点是需要影子实例属性.实际上,您可以使该inherit函数遍历作为函数的所有实例属性(使用hasOwnProperty),并自动添加super_<method name>属性.这将允许您调用this.super_get_name()而不是将其存储在临时值中并使用它来调用它call.
对于原型上的方法,您不需要担心上述情况,但如果您想访问超类的原型方法,则可以调用this.constructor.super.prototype.methodName.如果你想减少冗长,你当然可以增加便利性.:)
Jon*_*Jon 166
在我看来,大多数人都给出了getter和setter的例子而不是构造函数,即http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming).
lunched-dan更接近但是这个例子在jsFiddle中不起作用.
此示例创建一个私有构造函数,该函数仅在创建对象期间运行.
var color = 'black';
function Box()
{
// private property
var color = '';
// private constructor
var __construct = function() {
alert("Object Created.");
color = 'green';
}()
// getter
this.getColor = function() {
return color;
}
// setter
this.setColor = function(data) {
color = data;
}
}
var b = new Box();
alert(b.getColor()); // should be green
b.setColor('orange');
alert(b.getColor()); // should be orange
alert(color); // should be black
Run Code Online (Sandbox Code Playgroud)
如果要分配公共属性,则可以将构造函数定义为:
var color = 'black';
function Box()
{
// public property
this.color = '';
// private constructor
var __construct = function(that) {
alert("Object Created.");
that.color = 'green';
}(this)
// getter
this.getColor = function() {
return this.color;
}
// setter
this.setColor = function(color) {
this.color = color;
}
}
var b = new Box();
alert(b.getColor()); // should be green
b.setColor('orange');
alert(b.getColor()); // should be orange
alert(color); // should be black
Run Code Online (Sandbox Code Playgroud)
小智 23
那么"构造函数"属性的意义何在?无法弄清楚它可能有用的地方,任何想法?
构造函数属性的要点是提供一些假装JavaScript的方法.您无法做的事情之一是在创建对象的构造函数后更改它.情况很复杂.
几年前我写了一篇相当全面的文章:http://joost.zeekat.nl/constructors-considered-mildly-confusing.html
bit*_*her 16
试试这个模板:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Name = Name||{};
Name.Space = Name.Space||{};
//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Name.Space.ClassName = function Name_Space_ClassName(){}
//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Name.Space.ClassName.prototype = {
v1: null
,v2: null
,f1: function Name_Space_ClassName_f1(){}
}
//============================================================
// Static Variables
//------------------------------------------------------------
Name.Space.ClassName.staticVar = 0;
//============================================================
// Static Functions
//------------------------------------------------------------
Name.Space.ClassName.staticFunc = function Name_Space_ClassName_staticFunc(){
}
</script>
Run Code Online (Sandbox Code Playgroud)
如果要定义静态类,则必须调整命名空间:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
Shape.Rectangle = Shape.Rectangle||{};
// In previous example, Rectangle was defined in the constructor.
</script>
Run Code Online (Sandbox Code Playgroud)
示例类:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
//============================================================
// Constructor - MUST BE AT TOP OF FILE
//------------------------------------------------------------
Shape.Rectangle = function Shape_Rectangle(width, height, color){
this.Width = width;
this.Height = height;
this.Color = color;
}
//============================================================
// Member Functions & Variables
//------------------------------------------------------------
Shape.Rectangle.prototype = {
Width: null
,Height: null
,Color: null
,Draw: function Shape_Rectangle_Draw(canvasId, x, y){
var canvas = document.getElementById(canvasId);
var context = canvas.getContext("2d");
context.fillStyle = this.Color;
context.fillRect(x, y, this.Width, this.Height);
}
}
//============================================================
// Static Variables
//------------------------------------------------------------
Shape.Rectangle.Sides = 4;
//============================================================
// Static Functions
//------------------------------------------------------------
Shape.Rectangle.CreateSmallBlue = function Shape_Rectangle_CreateSmallBlue(){
return new Shape.Rectangle(5,8,'#0000ff');
}
Shape.Rectangle.CreateBigRed = function Shape_Rectangle_CreateBigRed(){
return new Shape.Rectangle(50,25,'#ff0000');
}
</script>
Run Code Online (Sandbox Code Playgroud)
示例实例化:
<canvas id="painting" width="500" height="500"></canvas>
<script>
alert("A rectangle has "+Shape.Rectangle.Sides+" sides.");
var r1 = new Shape.Rectangle(16, 12, "#aa22cc");
r1.Draw("painting",0, 20);
var r2 = Shape.Rectangle.CreateSmallBlue();
r2.Draw("painting", 0, 0);
Shape.Rectangle.CreateBigRed().Draw("painting", 10, 0);
</script>
Run Code Online (Sandbox Code Playgroud)
注意函数定义为AB =函数A_B().这是为了使您的脚本更容易调试.打开Chrome的Inspect Element面板,运行此脚本,然后展开调试回溯:
<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Fail = Fail||{};
//============================================================
// Static Functions
//------------------------------------------------------------
Fail.Test = function Fail_Test(){
A.Func.That.Does.Not.Exist();
}
Fail.Test();
</script>
Run Code Online (Sandbox Code Playgroud)
Sat*_*are 10
这是一个构造函数:
function MyClass() {}
Run Code Online (Sandbox Code Playgroud)
当你这样做
var myObj = new MyClass();
Run Code Online (Sandbox Code Playgroud)
MyClass 执行,并返回该类的新对象.
这种模式对我很有帮助.使用此模式,您可以在单独的文件中创建类,并根据需要将它们加载到整个应用程序中.
// Namespace
// (Creating new if not instantiated yet, otherwise, use existing and just add to it)
var myApp = myApp || {};
// "Package"
// Similar to how you would establish a package in other languages
(function() {
// "Class"
var MyClass = function(params) {
this.initialize(params);
}
// "Private Static" vars
// - Only accessible to functions in this class.
// - Doesn't get wiped out when we create a new instance.
var countInstances = 0;
var allInstances = [];
// "Private Static" functions
// - Same as above, but it's a function accessible
// only to other functions in this class.
function doSomething(){
}
// "Public Static" vars
// - Everyone has access.
// - Doesn't get wiped out when we create a new instance.
MyClass.counter = 0;
// "Public Static" functions
// - Same as above, but anyone can call this "static method".
// - Kinda like a singleton class situation.
MyClass.foobar = function(){
}
// Public properties and methods are built into the "prototype"
// - This is how each instance can become unique unto itself.
// - Establishing "p" as "local" (Static Private) variable
// simply so we don't have to keep typing "MyClass.prototype"
// for each property and function.
var p = MyClass.prototype;
// "Public" vars
p.id = null;
p.firstname = null;
p.lastname = null;
// "Private" vars
// - Only used by "this" instance.
// - There isn't "true" privacy for each
// instance so we have to fake it.
// - By tradition, we indicate "privacy"
// by prefixing it with an underscore.
// - So technically, anyone can access, but we simply
// don't tell anyone about it (e.g. in your API)
// so no one knows about it :)
p._foo = null;
p.initialize = function(params){
this.id = MyClass.counter++;
this.firstname = params.firstname;
this.lastname = params.lastname;
MyClass.counter++;
countInstances++;
allInstances.push(this);
}
p.doAlert = function(theMessage){
alert(this.firstname + " " + this.lastname + " said: " + theMessage + ". My id:" + this.id + ". Total People:" + countInstances + ". First Person:" + allInstances[0].firstname + " " + allInstances[0].lastname);
}
// Assign class to app
myApp.MyClass = MyClass;
// Close the "Package"
}());
// Usage example:
var bob = new myApp.MyClass({ firstname : "bob",
lastname : "er"
});
bob.doAlert("hello there");
Run Code Online (Sandbox Code Playgroud)
我发现本教程非常有用.大多数jQuery插件都使用这种方法.
var Class = function(methods) {
var klass = function() {
this.initialize.apply(this, arguments);
};
for (var property in methods) {
klass.prototype[property] = methods[property];
}
if (!klass.prototype.initialize) klass.prototype.initialize = function(){};
return klass;
};
Run Code Online (Sandbox Code Playgroud)
现在,
var Person = Class({
initialize: function(name, age) {
this.name = name;
this.age = age;
},
toString: function() {
return "My name is "+this.name+" and I am "+this.age+" years old.";
}
});
var alice = new Person('Alice', 26);
alert(alice.name); //displays "Alice"
alert(alice.age); //displays "26"
alert(alice.toString()); //displays "My name is Alice and I am 26 years old" in most browsers.
//IE 8 and below display the Object's toString() instead! "[Object object]"
Run Code Online (Sandbox Code Playgroud)
是的,你可以在类声明中定义一个构造函数,如下所示:
class Rectangle {
constructor(height, width) {
this.height = height;
this.width = width;
}
}
Run Code Online (Sandbox Code Playgroud)
我想我会发布我用javascript闭包做的事,因为还没有人使用闭包.
var user = function(id) {
// private properties & methods goes here.
var someValue;
function doSomething(data) {
someValue = data;
};
// constructor goes here.
if (!id) return null;
// public properties & methods goes here.
return {
id: id,
method: function(params) {
doSomething(params);
}
};
};
Run Code Online (Sandbox Code Playgroud)
欢迎对此解决方案提出意见和建议.:)
也许它变得更简单了,但以下是我在 2017 年提出的想法:
class obj {
constructor(in_shape, in_color){
this.shape = in_shape;
this.color = in_color;
}
getInfo(){
return this.shape + ' and ' + this.color;
}
setShape(in_shape){
this.shape = in_shape;
}
setColor(in_color){
this.color = in_color;
}
}
Run Code Online (Sandbox Code Playgroud)
在使用上面的类时,我有以下内容:
var newobj = new obj('square', 'blue');
//Here, we expect to see 'square and blue'
console.log(newobj.getInfo());
newobj.setColor('white');
newobj.setShape('sphere');
//Since we've set new color and shape, we expect the following: 'sphere and white'
console.log(newobj.getInfo());
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,构造函数接受两个参数,我们设置对象的属性。我们还通过使用这些函数来改变对象的颜色和形状setter,并证明在getInfo()这些改变之后调用时它的变化仍然存在。
有点晚了,但我希望这会有所帮助。我已经通过mocha单元测试对此进行了测试,并且运行良好。