我正试图在javascript中创建一个简单的数据对象。这是代码。
var roverObject = function(){
var newRover = {};
var name;
var xCord;
var ycord;
var direction;
newRover.setName = function(newName) {
name = newName;
};
newRover.getName = function() {
return name;
};
newRover.setDirection = function(newDirection) {
direction = newDirection;
};
newRover.getDirection = function() {
return direction;
};
newRover.setXCord = function(newXCord) {
xCord = newXCord;
};
newRover.getXCord = function() {
return xCord;
};
newRover.setYCord = function(newYCord) {
yCord = newYCord;
};
newRover.getYCord = function() {
return yCord;
};
newRover.where = function(){
return "Rover :: "+ name +" is at Location("+xCord+","+yCord+") pointing to "+direction;
};
return newRover;
};
rover1 = new roverObject();
rover2 = new roverObject();
rover1.setName("Mars Rover");
rover1.setDirection("NORTH");
rover1.setXCord(2);
rover1.setYCord(2);
console.log(rover1.where());
console.log(rover1);
rover2.setName("Moon Rover");
rover2.setDirection("SOUTH");
rover2.setXCord(1);
rover2.setYCord(1);
console.log(rover2.where());
console.log(rover2);
关于这个创作我几乎没有问题。
newObject.prototype = roverObject
那会有用吗?这最有意义。最后我有一个奇怪的问题。注意objet“where”的最后一个方法,它返回一个连接的字符串。在这里,我尝试使用以下代码。
newRover.where = function(){
return "Rover :: "+ name +" is at Location("+xCord+","+yCord+") pointing to "+direction;
}();
然后执行了以下console.log
console.log(rover1.where);
console.log(rover2.where);
它给我留下了以下错误:
cannot access optimized closure
为什么会这么说?我做错了什么?
感谢所有帮助。任何评论意见也将不胜感激! 干杯
答案 0 :(得分:6)
我成功了吗?我真的不能访问对象属性吗?
事实上。您没有对象属性,roverObject
函数中有局部变量。局部变量不能从外部访问,只能从roverObject
函数内部的函数中访问它们。
您使用roverObject
作为构造函数调用new roverObject
是无关紧要的,因为您正在从函数返回不同的对象。在没有var rover1= roverObject()
的情况下说new
会做同样的事情。值得注意的是,[new] roverObject
返回的对象是Object
创建的对象{}
; rover1 instanceof roverObject
为false
。
如果您希望instanceof
能够正常工作,则必须使用new
进行调用,并在构造函数中使用this
代替newRover
。
如果我想继承这个对象,我应该做一个newObject.prototype = roverObject会有用吗?这最有意义。
没有。您目前没有进行原型设计的补贴。您正在为roverObject
的每个实例使用每种方法的单独副本。你可以用这种方式做对象,但它与原型设计不同。如果你想在你现在的安排中创建类似roverObject
的子类的东西,你会说:
function AdvancedRover() {
var rover= new roverObject();
rover.doResearch= function() {
return rover.where()+' and is doing advanced research';
};
return rover;
}
注意,因为基类构造函数中的'private'局部变量确实是私有的,所以即使是子类也无法获取它们。没有'受保护'。
newRover.where = function(){...}();
这是做什么的?我无法得到你做的错误;以上所做的就是将字符串赋给where
的位置(在调用setter方法之前,所以它充满了未定义的内容)。
有没有更好的方法来创建这种对象?
也许。有关JavaScript中类/实例策略的讨论,请参阅this question。
答案 1 :(得分:2)
Q1:你可以在javascript'classes'中创建'私人'成员。在javascript中,隐私不是由任何访问说明符决定的。相反,访问需要专门检测。例如:
function MyClass() {
this.val = 100; // public;
var privateVal = 200;
function getVal() { return this.val; } // private method;
this.getPrivateVal = function() { // public method, accessor to private variable
return privateVal;
}
}
javascript中的对象范围由名为闭包的奇怪概念控制。 AFAIK,在C + / Java等任何其他流行的语言中都没有并行概念。
虽然我理解闭包是什么,但我不能用语言表达。也许演示会对你有所帮助:
function closureDemo() {
var done=false;
function setDone() { done=true; }
doLater(setDone);
}
function doLater(func) { setTimeout(func,1000); }
closureDemo();
现在,虽然从doLater中调用setDone,但它仍然可以在closureDemo中访问done
,即使done
在范围内不是(在传统的程序意义上) 。
我想您在阅读this时会了解更多。
function RoverObject() {
var newRover = {}; // privates
var name;
var xCord;
var ycord;
var direction;
this.setName = function(newName) {
name = newName;
};
this.getName = function() {
return name;
};
this.setDirection = function(newDirection) {
direction = newDirection;
};
// and so on...
this.where = function(){
return "Rover :: "+ name +" is at Location("+xCord+","+yCord+") pointing to "+direction;
};
}
var rover1 = new RoverObject();
注意事项:
问题3:如果你想继承,那么我的方法(使用它)将不起作用。相反,公共方法应该是prototype
RoverObject
的一部分。阅读this。优秀的材料。
希望有所帮助。
编辑:您的代码工作方式存在问题。问题:
createRoverObject
,因为这正是它正在做的事情。它不像类构造函数那样工作答案 2 :(得分:1)
关于4. - 您正在尝试记录该函数,而不是调用该函数的结果。应该是console.log(rover1.where());
我的猜测firebug(我认为它是firebug的console.log)不喜欢记录函数定义。
编辑哦,我明白了,当你指定rover.where
时,你实际上正在执行where funcion。你是否试图将看起来像属性的东西真正变成一个函数?如果是这样的话它就行不通了。如果你想在被调用时对它进行评估,它必须是一个函数。
在你的情况下where
在构造函数中执行会发生什么。那时你仍然在创建roverObject
闭包,因此现在访问它的私有变量还为时过早。
答案 3 :(得分:0)
这只是解决你帖子的第1点。
这是一篇关于javascript私有成员的好文章及更多:
Private Members in JavaScript
答案 4 :(得分:0)
像这样定义你的对象会给你私人成员。
function RolloverObject() {
var name;
var xCord;
var ycord;
var direction;
this.setName = function(newName) { name = newName; };
this.getName = function() { return name; };
this.setDirection = function(newDirection) { direction = newDirection; };
this.getDirection = function() { return direction; };
this.setXCord = function(newXCord) { xCord = newXCord; };
this.getXCord = function() { return xCord; };
this.setYCord = function(newYCord) { yCord = newYCord; };
this.getYCord = function() { return yCord; };
this.where = function() {
return "Rover :: " + name + " is at Location(" + xCord + "," + yCord + ") pointing to " + direction;
};
}
var rolloverObject = new RolloverObject();