我正在研究JS中一个相当复杂的对象,我遇到了问题:
我有以下(删节)代码:
var LocationSelector;
LocationSelector = function(container) {
this.selectors = {
container: container,
city_name: container.find('input.city_name'),
city_id: container.find('input.city_id')
};
return this.initialize();
};
LocationSelector.prototype = {
initialize: function() {
return this.city.checkStatus();
},
city: {
status: null,
message: null,
id: null,
checkStatus: function() {
if (LocationSelector.selectors.city_name.val() && LocationSelector.selectors.city_id.val()) {
return LocationSelector.city.setStatus('success');
}
},
setStatus: function(status) {
return alert(status);
}
}
};
两个问题:
1)子对象函数this
内部不再引用根对象。如果我写出LocationSelector.object.method( args )
,我似乎可以回复父母,但是要输入很多内容。有没有办法定义回到父对象的快捷方式?
2)在某些情况下,我需要在每个页面上有多个这样的实例,因此对我来说很重要的是我可以在实例化新对象时设置各种selectors
,然后引用实例选择器。原型。在子对象方法中引用父对象(即LocationSelector
)甚至可行吗? JS如何知道保留当前活动对象的存储属性?
基本上,我正在尝试实现一个类,我对JS完全不熟悉并且不知道该怎么做。所以,任何帮助或建议都表示赞赏。谢谢!
答案 0 :(得分:6)
您当前的方法存在许多问题。虽然我不明白为什么LocationSelector
个实例拥有city
成员,但这里更接近你想要的东西。
function LocationSelector(container) {
this.selectors = {
container: container,
city_name: container.find("input.city_name"),
city_id: container.find("input.city_id")
};
this.city = new City(this);
this.city.checkStatus();
}
function City(locationSelector) {
this.status = null;
this.message = null;
this.id = null;
this.locationSelector = locationSelector;
}
City.prototype.checkStatus = function () {
if (this.locationSelector.selectors.city_name.val() && this.locationSelector.selectors.city_id.val()) {
this.setStatus("success");
}
};
City.prototype.setStatus = function () {
alert("status");
};
注意事项:
City
显然是它自己的类,所以你应该把它变成一个。在您的代码中,LocationSelector
的所有实例之间共享一个城市,因为它被放在原型上。在此代码中,它在LocationSelector
构造函数中被指定为实例属性。LocationSelector.selectors
。 LocationSelector.selectors
将用于LocationSelector
没有的“静态”属性。相反,您需要在特定实例上引用selectors
属性;在此示例中,该实例由this.locationSelector
提供。City
实例在没有具体实例的情况下无法引用“父”LocationSelector
类的属性。以下是对我更有意义的代码版本,删除LocationSelector
具有city
属性(不使用)的部分。
function LocationSelectors(container) {
this.city_name = container.find("input.city_name");
this.city_id = container.find("input.city_id");
}
function City(locationSelectors) {
this.locationSelector = locationSelector;
}
City.prototype.checkStatus = function () {
if (this.locationSelectors.city_name.val() && this.locationSelectors.city_id.val()) {
this.setStatus("success");
}
};
City.prototype.setStatus = function () {
alert("status");
};
function checkCityStatus(container) {
var locationSelectors = new LocationSelectors(container);
var city = new City(locationSelectors);
city.checkStatus();
}
我给你留下Crockford's "Private Members in JavaScript"的链接,该链接谈到在JavaScript中执行OO。还有其他可能更好的解释,但至少那一个会让你走上正轨。
答案 1 :(得分:2)
了解Closures,我很肯定你会找到你需要的东西。
以下是您要完成的一个简单示例:
function MyCoolObject(name){
var self_myCoolObject = this;
this.name = name;
this.popAlertWithNameInFiveSeconds = function(){
setTimeout(function(){
alert('Incorrect reference to name "this.name" returns ' + this.name);
alert('Correct reference to name "self_myCoolObject.name" returns ' + self_myCoolObject.name);
},5000)
}
}
//TO TEST
var MyObj = new MyCoolObject('MySuperCoolName')
MyObj.popAlertWithNameInFiveSeconds();
答案 2 :(得分:0)
这是我所拥有的JS代码片段。在我进入点击处理程序之前,我通过调用SlideShow
来引用对象(var parent = this
)。然后在以后的嵌套函数中,您可以确保使用parent.function()
/* Slide Show object */
function SlideShow(parentContainerId) {
this.BEGINNING = 'Beginning';
this.END = 'End of list';
this.FIRSTINDEX = 0;
this.length = jQuery(parentContainerId + ' img').length;
this.container = jQuery(parentContainerId);
this.imgs = jQuery(parentContainerId + ' img');
this.index = this.FIRSTINDEX;
this.status = 'beginning'; // beginning, end
this.init = function() {
// get it started
this.moveTo(this.FIRSTINDEX);
this.process();
// ****GET OBJECT SCOPE*****
var parent = this;
// set up click listener
this.container.find('img').click(function(e) {
var item_width = jQuery(this).width();
var x_click_ps = e.clientX - jQuery(this).offset().left;
var x_diff = x_click_ps / item_width;
console.log(this);
if (x_diff < .5) {
parent.moveByIncrement(-1)
parent.process();
} else {
parent.moveByIncrement(1);
parent.process();
}
});
}
.
.
.
}