JavaScript类/对象可以具有构造函数吗? 它们是如何创建的?


#1楼

这是一个构造函数:

function MyClass() {}

当你做

var myObj = new MyClass();

执行MyClass ,并返回该类的新对象。


#2楼

我想我会发布有关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);}};
};

欢迎对此解决方案提出意见和建议。 :)


#3楼

这是我有时在JavaScript中用于OOP相似行为的模板。 如您所见,您可以使用闭包来模拟私有(静态和实例)成员。 new MyClass()将返回的对象是仅具有分配给this对象的属性,并且位于“类”的prototype对象中。

var MyClass = (function () {// private staticvar nextId = 1;// constructorvar cls = function () {// privatevar 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 staticcls.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;
})();

有人问我使用这种模式的继承,所以去了:

// 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 () {// constructorvar 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;
})();

并使用所有示例:

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

如您所见,这些类之间可以正确交互(它们共享MyClass的静态ID, announce方法使用正确的get_name方法,等等)。

需要注意的一件事是需要对实例属性进行阴影处理。 实际上,您可以使inherit函数遍历作为函数的所有实例属性(使用hasOwnProperty ),并自动添加super_<method name>属性。 这样您就可以调用this.super_get_name()而不是将其存储在一个临时值中并使用call对其进行绑定。

对于原型上的方法,您无需担心上述问题,如果您要访问超类的原型方法,则可以调用this.constructor.super.prototype.methodName 。 如果您想使其更简洁一些,您当然可以添加便捷属性。 :)


#4楼

使用原型:

function Box(color) // Constructor
{this.color = color;
}Box.prototype.getColor = function()
{return this.color;
};

隐藏“颜色”(有点像私有成员变量):

function Box(col)
{var color = col;this.getColor = function(){return color;};
}

用法:

var blueBox = new Box("blue");
alert(blueBox.getColor()); // will alert bluevar greenBox = new Box("green");
alert(greenBox.getColor()); // will alert green

#5楼

在我看来,你们中的大多数人都在提供getter和setter的示例而不是构造函数,即http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming) 。

Lunched-dan更近了,但是该示例在jsFiddle中不起作用。

本示例创建一个私有构造函数,该函数仅在对象创建期间运行。

var color = 'black';function Box()
{// private propertyvar color = '';// private constructor var __construct = function() {alert("Object Created.");color = 'green';}()// getterthis.getColor = function() {return color;}// setterthis.setColor = function(data) {color = data;}}var b = new Box();alert(b.getColor()); // should be greenb.setColor('orange');alert(b.getColor()); // should be orangealert(color); // should be black

如果要分配公共属性,则可以按以下方式定义构造函数:

var color = 'black';function Box()
{// public propertythis.color = '';// private constructor var __construct = function(that) {alert("Object Created.");that.color = 'green';}(this)// getterthis.getColor = function() {return this.color;}// setterthis.setColor = function(color) {this.color = color;}}var b = new Box();alert(b.getColor()); // should be greenb.setColor('orange'); alert(b.getColor()); // should be orangealert(color); // should be black

#6楼

这种模式对我很好。 使用这种模式,您可以在单独的文件中创建类,然后“根据需要”将它们加载到整个应用程序中。

// 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" varsp.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");

#7楼

我发现本教程非常有用。 大多数jQuery插件都使用这种方法。

http://www.htmlgoodies.com/html5/tutorials/create-an-object-oriented-javascript-class-constructor.html#fbid=OVYAQL_TDpK

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;
};

现在,

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]"

#8楼

此处的示例: http : //jsfiddle.net/FZ5nC/

试试这个模板:

<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>

如果要定义静态类,则必须调整名称空间:

<script>
//============================================================
// Register Namespace
//------------------------------------------------------------
var Shape = Shape||{};
Shape.Rectangle = Shape.Rectangle||{};
// In previous example, Rectangle was defined in the constructor.
</script>

示例类:

<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>

示例实例:

<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>

注意函数定义为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>

#9楼

从上面使用Blixt的出色模板时,我发现它不能与多级继承(MyGrandChildClass扩展MyChildClass扩展MyClass)配合使用-反复调用第一个父级的构造函数。 因此,这是一个简单的解决方法–如果您需要多级继承,而不是使用this.constructor.super.call(this, surName); 使用chainSuper(this).call(this, surName); 链函数定义如下:

function chainSuper(cls) {if (cls.__depth == undefined) cls.__depth = 1; else cls.__depth++;var depth = cls.__depth;var sup = cls.constructor.super;while (depth > 1) {if (sup.super != undefined) sup = sup.super;depth--;}return sup;
}

#10楼

如果您使用Typescript,它们会执行-MicroSoft开放源代码:-)

class BankAccount {balance: number;constructor(initially: number) {this.balance = initially;}deposit(credit: number) {this.balance += credit;return this.balance;}
}

Typescript可让您“伪造”已编译为javascript构造的OO构造。 如果您正在启动一个大型项目,则可能会节省大量时间,并且它刚刚达到里程碑1.0版本。

http://www.typescriptlang.org/Content/TypeScript%20Language%20Specification.pdf

上面的代码被“编译”为:

var BankAccount = (function () {function BankAccount(initially) {this.balance = initially;}BankAccount.prototype.deposit = function (credit) {this.balance += credit;return this.balance;};return BankAccount;
})();

#11楼

http://www.jsoops.net/对于Js中的oop非常有用。 如果提供私有,受保护的公共变量和函数,以及继承功能。 示例代码:

var ClassA = JsOops(function (pri, pro, pub)
{// pri = private, pro = protected, pub = publicpri.className = "I am A ";this.init = function (var1)// constructor{pri.className += var1;}pub.getData = function (){return "ClassA(Top=" + pro.getClassName() + ", This=" + pri.getClassName()+ ", ID=" + pro.getClassId() + ")";}pri.getClassName = function () { return pri.className; }pro.getClassName = function () { return pri.className; }pro.getClassId = function () { return 1; }
});var newA = new ClassA("Class");//***Access public function
console.log(typeof (newA.getData));
// function
console.log(newA.getData());
// ClassA(Top=I am A Class, This=I am A Class, ID=1)//***You can not access constructor, private and protected function
console.log(typeof (newA.init));            // undefined
console.log(typeof (newA.className));       // undefined
console.log(typeof (newA.pro));             // undefined
console.log(typeof (newA.getClassName));    // undefined

#12楼

只是为了提供一些变化。 ds.oop是用javascript中的构造函数声明类的好方法。 它支持所有可能的继承类型(包括甚至c#不支持的1种继承)以及很好的接口。

var Color = ds.make.class({type: 'Color',constructor: function (r,g,b) { this.r = r;                     /* now r,g, and b are available to   */this.g = g;                     /* other methods in the Color class  */this.b = b;                     }
});
var red = new Color(255,0,0);   // using the new keyword to instantiate the class

#13楼

在大多数情况下,您必须以某种方式声明所需的属性,然后才能调用传递此信息的方法。 如果您不必最初设置属性,则可以像这样在对象内调用方法。 可能不是最漂亮的方法,但这仍然有效。

var objectA = {color: ''; callColor : function(){console.log(this.color);}this.callColor();
}
var newObject = new objectA();

#14楼

在JavaScript中,调用类型定义了函数的行为:

  • 直接调用func()
  • 对对象obj.func()方法调用
  • 构造函数调用new func()
  • 间接调用func.call()func.apply()

使用new运算符进行调用时,该函数作为构造函数被调用:

function Cat(name) {this.name = name;
}
Cat.prototype.getName = function() {return this.name;
}var myCat = new Cat('Sweet'); // Cat function invoked as a constructor

JavaScript中的任何实例或原型对象都有一个属性constructor ,它是指构造函数。

Cat.prototype.constructor === Cat // => true
myCat.constructor         === Cat // => true

检查这个职位约constructor属性。


#15楼

是的,您可以在类声明中定义一个构造函数,如下所示:

class Rectangle {constructor(height, width) {this.height = height;this.width = width;}
}

#16楼

也许它变得更简单了,但是下面是我现在在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;}
}

在使用上面的类时,我有以下内容:

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());

如您所见,构造函数接受两个参数,然后我们设置对象的属性。 我们还使用setter函数更改了对象的颜色和形状,并证明在这些更改后调用getInfo()保留其更改。

有点晚了,但是我希望这会有所帮助。 我已经通过mocha单元测试对此进行了测试,并且运行良好。


#17楼

这里我们需要注意Java脚本中的一点,它是一种无类语言,但是我们可以通过使用Java脚本中的函数来实现。 实现此目的的最常见方法是,需要在Java脚本中创建一个函数,并使用new 关键字创建一个对象,然后使用 关键字定义属性和方法。下面是示例。

// Function constructorvar calculator=function(num1 ,num2){this.name="This is function constructor";this.mulFunc=function(){return num1*num2};};var objCal=new calculator(10,10);// This is a constructor in java script
alert(objCal.mulFunc());// method call
alert(objCal.name);// property call//Constructors With Prototypesvar calculator=function(){this.name="Constructors With Prototypes";
};calculator.prototype.mulFunc=function(num1 ,num2){return num1*num2;
};
var objCal=new calculator();// This is a constructor in java script
alert(objCal.mulFunc(10,10));// method call
alert(objCal.name); // property call

#18楼

那么“构造函数”属性的意义是什么? 无法找出在哪里有用的任何想法?

构造器属性的重点是提供一种伪装JavaScript has classes的方法。 您无法做的一件事是在创建对象后更改对象的构造函数。 情况很复杂。

几年前,我在上面写了一篇相当全面的文章: http : //joost.zeekat.nl/constructors-considered-mildly-confusing.html


#19楼

使用上面的Nick的示例,您可以使用return语句作为对象定义中的最后一条语句,为不带参数的对象创建构造函数。 返回如下所示的构造函数,每次创建对象时,它将在__construct中运行代码:

function Box()
{var __construct = function() {alert("Object Created.");this.color = 'green';}this.color = '';this.getColor = function() {return this.color;}__construct();
}var b = new Box();

JavaScript对象中的构造方法相关推荐

  1. 如何通过其值获取JavaScript对象中的键?

    本文翻译自:How to get a key in a JavaScript object by its value? I have a quite simple JavaScript object, ...

  2. 如何从JavaScript对象中删除项目[重复]

    本文翻译自:How to remove item from a JavaScript object [duplicate] Possible Duplicate: 可能重复: How to remov ...

  3. 如何从JavaScript对象中删除键? [重复]

    本文翻译自:How do I remove a key from a JavaScript object? [duplicate] This question already has an answe ...

  4. 检查键是否存在于JavaScript对象中?

    如何检查JavaScript对象或数组中是否存在特定键? 如果密钥不存在,而我尝试访问它,它将返回false吗? 还是抛出错误? #1楼 它将返回undefined . var aa = {hello ...

  5. 删除JavaScript对象中的元素

    参考http://stackoverflow.com/questions/208105/how-to-remove-a-property-from-a-javascript-object 通过dojo ...

  6. 如何从 JavaScript 对象中删除属性?

    假设我创建一个对象如下: let myObject = {"ircEvent": "PRIVMSG","method": "new ...

  7. JavaScript对象中的this属性

    this属性表示当前对象,如果在全局作用范围内使用this,则指代当前页面对象window: 如果在函数中使用this,则this指代什么是根据运行时此函数在什么对象上被调用. 我们还可以使用appl ...

  8. JavaScript对象中的可枚举属性和不可枚举属性

    在JavaScript中,对象的属性有可枚举和不可枚举之分,它是由对象属性描述符enumerable决定的.如果该属性是可枚举性的那么这个属性就能被for-in查找遍历到. 对象的属性描述符 在Jav ...

  9. JavaScript 对象中this的指向问题

    this运行在哪个对象下,就指向哪个对象. 转载于:https://www.cnblogs.com/songsongblue/p/11051683.html

最新文章

  1. 5个java框架及其优缺点_各种Java Web框架的优缺点是什么?
  2. oracle修改时区无效,Linux 7 修改时区不生效
  3. 计算机网络实验arp协议分析,计算机网络ARP地址协议解析实验报告
  4. power bi函数_在Power BI中的行上使用聚合函数
  5. 前端学习(1557):安全问题
  6. PHP多线程的实现(PHP多线程类)
  7. 美国计算机专业硏究生,2014年美国计算机专业研究生排名
  8. winform listbox 没有listitem的问题
  9. 产品案例分析 - 华为软件开发云
  10. 基于Android平台的x264的移植与应用(一):移植篇
  11. 我们到底能从《别逗了,费曼先生》中学到什么?
  12. 【从零开始的SDN学习之路】之闲话Neutron与SDN的联系
  13. Netron 可视化
  14. python输入一个数字n、计算1到n的和_怎么用python求1到n所有整数的和
  15. php高性能框架phaicon,3分钟快速入门php高性能框架Phalcon
  16. Wos/Pubmed/Scopus数据库一键去重+清洗数据 CiteSpace Vosviewer
  17. android 酷炫启动页,RxJava实践之打造酷炫启动页
  18. win10家庭中文版安装Hyper-V 解决Hyper-V.cmd闪退问题
  19. c语言字符串输入的陷阱
  20. 为什么需要强制类型转换

热门文章

  1. 【剑指offer-Java版】04替换空格
  2. 了解ViewConfiguration
  3. 小程序开发填坑汇总贴
  4. common-IO.jar相关
  5. mysql期末考试试卷_MySQL数据库考试试题及答案
  6. 编译-C语言库FFTW支持iOS平台的静态库
  7. 精益创新之设计思维研磨——《设计改变一切》书评
  8. 学习笔记--Spark
  9. 自定义封装ajax,复制即可用
  10. Leetcode 252, 253. Meeting Rooms