Javascript 方法不是构造函数
Javascript method is not a constructor
在我所在的公司,我们使用 jquery 并且很多代码都是非常杂乱无章的代码。因此,为了更好地组织它,我正在研究实施 article
中描述的发布子模型
所以我做了一个非常基本的版本:
var topics = {};
jQuery.Topic = function( id ) {
var callbacks, method,
topic = id && topics[ id ];
if ( !topic ) {
callbacks = jQuery.Callbacks();
topic = {
publish: callbacks.fire,
subscribe: callbacks.add,
unsubscribe: callbacks.remove
};
if ( id ) {
topics[ id ] = topic;
}
}
return topic;
};
$(function() {
var testService = new TestService();
testService.subscribe();
var testView = new TestView(testService);
testView.initEvents();
});
/* ---------------------VIEW----------------- */
var TestView = function(testService) {
this.testService = testService;
};
TestView.prototype.initEvents = function () {
this.publishers();
};
TestView.prototype.publishers = function() {
$("#search").on("click", function () {
var isValid = this.testService.validateForm("#container");
if(isValid){
$.Topic( "search" ).publish();
}
})
};
/* ---------------------SERVICE----------------- */
var TestService = function() {
this.testIdea = [];
};
TestService.prototype.validateForm = function (section) {
var referralValid = true;
$(section).find('input,select').filter('[required]:visible').each(function (i, requiredField) {
if(requiredField.value === '') {
//'breaks' the loop out
referralValid = false;
return referralValid;
}
});
return referralValid;
};
TestService.prototype.search = function() {
};
TestService.prototype.subscribe = function() {
var self = this;
$.Topic("search").subscribe( function() {
self.search()
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<div id="container">
<input type="text">
</div>
<button id="search">Search</button>
</div>
然而,当我把它放在 jsfiddle 中时,我得到了 Uncaught TypeError: TestService is not a constructor
的错误
在 Whosebug 片段和我的本地版本中,我得到了一个不同的错误 Uncaught TypeError: Cannot read 属性 'validateForm' of undefined。我看不出我做错了什么。有什么指点吗?
您可以按照自己的方式声明构造函数(将构造函数分配给变量):
var TestView = function(testService) {
this.testService = testService;
};
就像这个简单的例子:
var myClass = function(name) {
this.name = name;
}
myClass.prototype = {
hello: function() {
console.log('Hello ' + this.name);
}
}
var me = new myClass('Andrew');
me.hello();
但是你必须记得在使用它们之前声明它们。如果你使用函数语句(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function) as suggested by Chad Watkins it helps only because of hoisting(http://adripofjavascript.com/blog/drips/variable-and-function-hoisting.html)不是因为函数语句对构造函数是强制性的。
您的代码中的错误在行:
$("#search").on("click", function () {
var isValid = this.testService.validateForm("#container");
你在回调中引用 jQuery 对象而不是 TestView 实例,你可能想要这样的东西(双关语不是故意的):
...
var self = this;
$("#search").on("click", function () {
var isValid = self.testService.validateForm("#container");
...
在我所在的公司,我们使用 jquery 并且很多代码都是非常杂乱无章的代码。因此,为了更好地组织它,我正在研究实施 article
中描述的发布子模型所以我做了一个非常基本的版本:
var topics = {};
jQuery.Topic = function( id ) {
var callbacks, method,
topic = id && topics[ id ];
if ( !topic ) {
callbacks = jQuery.Callbacks();
topic = {
publish: callbacks.fire,
subscribe: callbacks.add,
unsubscribe: callbacks.remove
};
if ( id ) {
topics[ id ] = topic;
}
}
return topic;
};
$(function() {
var testService = new TestService();
testService.subscribe();
var testView = new TestView(testService);
testView.initEvents();
});
/* ---------------------VIEW----------------- */
var TestView = function(testService) {
this.testService = testService;
};
TestView.prototype.initEvents = function () {
this.publishers();
};
TestView.prototype.publishers = function() {
$("#search").on("click", function () {
var isValid = this.testService.validateForm("#container");
if(isValid){
$.Topic( "search" ).publish();
}
})
};
/* ---------------------SERVICE----------------- */
var TestService = function() {
this.testIdea = [];
};
TestService.prototype.validateForm = function (section) {
var referralValid = true;
$(section).find('input,select').filter('[required]:visible').each(function (i, requiredField) {
if(requiredField.value === '') {
//'breaks' the loop out
referralValid = false;
return referralValid;
}
});
return referralValid;
};
TestService.prototype.search = function() {
};
TestService.prototype.subscribe = function() {
var self = this;
$.Topic("search").subscribe( function() {
self.search()
});
};
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<div id="container">
<input type="text">
</div>
<button id="search">Search</button>
</div>
然而,当我把它放在 jsfiddle 中时,我得到了 Uncaught TypeError: TestService is not a constructor
的错误在 Whosebug 片段和我的本地版本中,我得到了一个不同的错误 Uncaught TypeError: Cannot read 属性 'validateForm' of undefined。我看不出我做错了什么。有什么指点吗?
您可以按照自己的方式声明构造函数(将构造函数分配给变量):
var TestView = function(testService) {
this.testService = testService;
};
就像这个简单的例子:
var myClass = function(name) {
this.name = name;
}
myClass.prototype = {
hello: function() {
console.log('Hello ' + this.name);
}
}
var me = new myClass('Andrew');
me.hello();
但是你必须记得在使用它们之前声明它们。如果你使用函数语句(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function) as suggested by Chad Watkins it helps only because of hoisting(http://adripofjavascript.com/blog/drips/variable-and-function-hoisting.html)不是因为函数语句对构造函数是强制性的。
您的代码中的错误在行:
$("#search").on("click", function () {
var isValid = this.testService.validateForm("#container");
你在回调中引用 jQuery 对象而不是 TestView 实例,你可能想要这样的东西(双关语不是故意的):
...
var self = this;
$("#search").on("click", function () {
var isValid = self.testService.validateForm("#container");
...