我找到了不同的方式。
教科书和互联网中最常推荐的方式:
var Person = function() {
this.age = 23;
}
Tony = new Person();
这似乎也有效:
function Person() {
this.age = 23;
}
Tony = new Person();
有区别吗?还有一个问题:通常你不能简单地省略括号。这可能是{new Person
而不是new Person()
)。这是因为使用了new关键字,对吗?
我刚试过的第三种奇怪的方式是这样的:
function Person() {
return {age: 2};
}
Tony = new Person();
Tony = Person(); // both ways work! It seems that you can leave out 'new' here.
在这里,我没有得到一个具有我的类名称的对象,但我的属性也是可访问的,看起来它与上述两种方法非常相似。
我应该使用什么以及技术差异是什么?谢谢!
答案 0 :(得分:2)
JavaScript是一种无类语言。类不存在,但是对象可以通过使用原型来相互继承属性。这意味着您不限于以类似方式实现继承。就个人而言,我喜欢使用BackboneJS启发的方法(代码需要UnderscoreJS):
var BaseObject = function(){}; //Create a function so that we may use the new operator.
//There may be code in the constructor
BaseObject.extend = function(obj) { //Add a static function to the BaseObject to extend it
var base = this; //Save a reference for later
//Create the constructor for the sub object. We need to extend it, so we can't use the base constructor. AFAIK, this is the only way to clone the base constructor, i.e. by creating a new function that calls it
var SubObject = _.extend(function(){
base.apply(this, arguments); //Call base constructor
}, this);
SubObject.prototype= _.extend({}, this.prototype, obj); //Create new prototype that extends the super prototype, but does not overwrite it.
return SubObject; //Return the new constructor + prototype
};
这可以让你像这样做类酷的东西:
var Car = BaseObject.extend({
speed: 0,
acceleration: 5,
accelerate: function(){
this.speed += this.acceleration;
}
});
var RaceCar = Car.extend({
acceleration: 10,
});
var car = new Car();
var raceCar = new RaceCar();
car.accelerate();
raceCar.accelerate();
if(raceCar.speed > car.speed){
console.log('raceCar won');
}else{
console.log('car won');
}
有关JavaScript继承的更多信息,我强烈建议您阅读Douglas Crockford的JavaScript:The Good Parts。
关于您的示例:
1和2之间的差异很小。有关更多信息,请参阅this question。
在3中,您只是返回一个对象文字。新关键字仅影响您未使用的函数中的this关键字,因此使用new无效。有关详细信息,请参阅this quesion
答案 1 :(得分:2)
1和2(var x =函数与函数x)非常相似。 3是完全不同的事情。
1和2之间的差异与类无关,之前已经在SO上询问过(多次)。我认为最完整的答案是这一个: https://stackoverflow.com/a/338053/1669279 简而言之,第一个x指向一个匿名函数,一些调试工具可能会遇到问题。第一个可以从它定义的行中获得,而第二个可以在整个范围内使用。阅读链接的答案以获取详细信息。
第3个“解决方案”根本不是一个类。它只是一个返回对象的函数(可能称为Factory方法)。
从构造函数中返回内容并不是一个好主意,尤其是return this
。如果要覆盖创建对象的正常过程(例如,实现单例模式),则应该只返回内容。
作为附注,在实例化类时应始终使用new
。以下是当您尝试智能并保存字符时会发生的情况:
function X () {
return this;
}
console.log(X()); // outputs the window object
在没有参数的情况下调用构造函数之后的括号是可选的,但是为了避免使用它们是不受欢迎的,因为它会导致稍微混乱的代码。
总结一下,我通常使用模式1.模式2也可以。
模式2的一个问题可能就是这个问题:
var x = new X(); // works
console.log(x.message); // works, I am X
x.method(); // doesn't work, method hasn't been defined yet
function X() {
this.message = 'I am X';
}
X.prototype.method = function() {
console.log(this.message);
};
答案 2 :(得分:0)
这就是我的做法:
;(function (window) {
"use strict";
//-- Private Vars
var opt, obj, rm, Debug;
//-- construtor
function App(requestedMethod) {
//-- set up some vars
if(typeof requestedMethod !== 'undefined') {
rm = requestedMethod;
}
opt = {
rMethod: (typeof rm !== 'undefined') ? (rm != null) ? rm : false : false
}
//-- containe resulable objects
obj = {}
//-- call the init method
this.init();
}
/** Public Methods **/
/**
* The Init method called on every page load
*/
App.prototype.init = function () {
var om = opt.rMethod;
//-- Once all init settings are performed call the requested method if required
if(om) {(typeof App.prototype[om] == 'function') ? App.prototype[om]() : _DB('Call to Method [' + om + '] does not exsist.');}
};
/**
* testmethod
*/
App.prototype.testmethod = function () {
};
/** Private Methods **/
function PrivateMethod(){
}
/**
* A console output that should enable to remain enable js to work in IE
* just incase i forget to remove it when checking on those pesky IE browsers....
*/
function _DB(msg){
if(window.console && window.console.log){
var logDate = new Date();
window.console.log('------------------- ' + logDate + ' ----------------------------------');
window.console.log(msg);
}
};
window.App = App;
})(window);
然后称之为:
<script src="ptha/to/your/app.js"></script>
<script>$(function() { new App('testmethod'); });</script>
加载代码后,新的App()将在所有页面加载数据完成后运行
希望这会有所帮助。要在外部访问它,请将新内容添加到var
var App = new App('testmethod);
然后您可以访问
之类的内容 App.testmethod()...
答案 3 :(得分:-1)
var Person = function() {
this.age = 23;
}
Person是包含(被引用)匿名函数的变量
function Person() {
this.age = 23;
}
但是你在这里声明了一个名为&#34; Person&#34;
的函数function Person() {
return {age: 2};
}
因此您声明了一个返回新静态对象的函数。
最好的方法取决于需求,如果要声明类使用第二种,而创建模块则使用第三种。对于第一种方法,请查看此处:http://helephant.com/2008/08/23/javascript-anonymous-functions/