我一直试图看看我是否可以尽可能直观地构建我的JavaScript对象,同时确保它尽可能“正确”。我一直在通过Crockford的JSLint.com运行一系列不同的场景,并且运气不佳。我似乎修复了一个错误,然后由于更改而弹出另一个错误。以下是我能得到的最好的。有人对此有另一种看法吗?
这是我构建对象的典型方式:
function gizmo(id) {
/* private variables */
var myId = id;
/* private methods */
var init = function () {
if (myId < 1) {
setId(1);
}
};
var setId = function (newId) {
myId = newId;
};
// run 'constructor'
init();
/* public methods */
return {
getId: function () {
return myId;
},
setId: function (newId) {
setId(newId);
},
incrementId: function (inc) {
setId(myId + inc);
}
};
}
// creating an instance of gizmo
var myGizmo = gizmo(-2);
console.log(myGizmo.getId()); // outputs 1
myGizmo.setId(5);
console.log(myGizmo.getId()); // outputs 5
myGizmo.incrementId(2);
console.log(myGizmo.getId()); /// outputs 7
这似乎运作良好。但是,当我通过JSLint运行它时,它给出了一个错误,指出我的两个私有函数是'Implied Globals。'
我能想到的最好的方法是使用如下变量在顶部声明我的函数:
function gizmo(id) {
/* private variables */
var myId = id,
init,
setId;
/* private methods */
init = function () {
if (myId < 1) {
setId(1);
}
};
setId = function (newId) {
myId = newId;
};
// run 'constructor'
init();
/* public methods */
return {
getId: function () {
return myId;
},
setId: function (newId) {
setId(newId);
},
incrementId: function (inc) {
setId(myId + inc);
}
};
}
答案 0 :(得分:3)
JSLint期望在init中引用setId之前定义它。
这传递了JSLint。
function gizmo(id) {
/* private variables */
var myId = id;
/* private methods */
var setId = function (newId) {
myId = newId;
};
var init = function () {
if (myId < 1) {
setId(1);
}
};
// run 'constructor'
init();
/* public methods */
return {
getId: function () {
return myId;
},
setId: function (newId) {
setId(newId);
},
incrementId: function (inc) {
setId(myId + inc);
}
};
}
答案 1 :(得分:1)
我很确定这是JSLint中的一个错误。它还没有看到setId
,所以它假定它是全局的。但实际上,它没有任何区别,因为所有var
都被提升,每ECMAScript 5 10.5。这意味着您的第一个示例和第二个示例在语义上是相同的。立即处理函数中的局部变量声明 where ,并且绑定最初设置为具有undefined
值。但是当函数(例如init)实际运行时,封闭值不再是undefined
。
要看到setId
最初未定义,但从未引用全局,请执行此测试:
function setId()
{
alert("Global setId");
}
function f()
{
var init = function()
{
setId();
}
alert(typeof(setId));
init();
var setId = function()
{
}
}
它会提示未定义,然后抛出TypeError
错误。
答案 2 :(得分:0)
我不了解JSlint,但在阅读“javascript the good parts”之后,我总是将对象声明为文字。
例如:
Mogwai={
has_crazy_thoughts:True,
reacts_to_water:True,
name: 'Gizmo',
eat:function(food){
// code
},
become_gremlin:function(){
// code
},
cause_havoc:function(){
// code
}
}
你实际上并没有声明上面的任何物体。只是一个功能。内部函数在Javascript中并不存在 - 它根本不像Java。
编辑:我强烈推荐上面提到的这本书(没有隶属关系):http://oreilly.com/catalog/9780596517748 ......它是由Douglas Crockford写的,他给我们带来了JSlint。答案 3 :(得分:0)
自从我认真编写JavaScript以来,已经很长时间了(几年),所以我对最佳实践细节的记忆已经消失了。我所做的就是回过头来挖出一些可以帮助你做出明智决定的资源。
首先,您创建对象的方式似乎让人想起Module Pattern。据我所知,我所链接的文章对此非常了解。其次,也许你更喜欢instantiate your objects的另一种方式。那篇文章给你一个不同的看法。