在普通的JS中,我可以这样做:
function Droppable() {
this.relevant = true;
this.uuid = generateUUID();
};
var generateUUID = function() {
return '12345';
}
console.log(new Droppable); // returns Droppable {relevant: true, uuid: "12345"}
但是在Angular我有这个:
angular.module('myApp').controller('MyCtrl', ['$scope', function($scope) {
function Droppable() {
this.relevant = true;
this.uuid = generateUUID();
}
var generateUUID = function() {
return '12345';
}
// initalize droppable areas
$scope.region1 = [new Droppable];
$scope.region2 = [new Droppable];
$scope.region3 = [new Droppable];
}]);
我正在尝试使用UUID创建3个可放置的区域。
但是当我这样做时,我得到' undefined不是函数' 引用this.uuid = generateUUID();
function Droppable() {...}
为什么?
答案 0 :(得分:1)
function Droppable() {
this.relevant = true;
this.uuid = generateUUID();
}
var generateUUID = function() {
return '12345';
}
好的,这不是关于AngularJS的问题,但它更多的是关于Javascript。 阅读Javascript变量提升。 使用var关键字声明函数时,会发生两件事:创建变量,然后为其分配变量。由于javascript提升,变量声明(var generateUUID)将被提升到顶部,声明发生在你编写它的地方。
var generateUUID; //undefined
function Droppable() {
this.relevant = true;
this.uuid = generateUUID(); //you are invoking undefined here.
}
generateUUID = function() {
return '12345';
}
正确的做法是:
function Droppable() {
this.relevant = true;
this.uuid = generateUUID();
}
function GenerateUUID() {
return '12345';
}
在这里,因为你使用"函数GenerateUUID()",整个事物被提升到顶部而不仅仅是变量
答案 1 :(得分:1)
将我的评论回答。您的问题是由于在分配函数表达式之前保留函数表达式,在这种情况下,变量generateUUID
尚未定义。
var generateUUID = function() {
return '12345';
}
修复它的一种方法是将其转换为函数声明,以便将其自动提升到范围的顶部。
function generateUUID () {
return '12345';
}
或在变量generateUUID
可能的用法之前将其定义为函数引用。
//Some variable declarations, start of the scope
var generateUUID = function() {
return '12345';
}
function Droppable() {
this.relevant = true;
this.uuid = generateUUID();
}
当你这样做时: -
.... Some Code ....
var generateUUID = function() {
return '12345';
}
.... Some Code ...
它与: -
相同var generateUUID;
.... Some Code ....
//Any usage of this till here will cause the error that you are facing, since there is no value assigned to generateUUID yet
generateUUID = function() {
return '12345';
}
.... Some Code ...
和 Plnkr
注意: - 这个问题不应该在你的例子中发生,因为你在赋值构造函数(generateUUID
)之后调用了值,可能是一个不同的用例(问题中不存在) )可能有这个问题。
答案 2 :(得分:1)
给出一些简单的例子
function Droppable() {
this.relevant = true;
this.uuid = generateUUID();
}
// this will throw an error because you are calling generateUUID before it initialize
console.log(new Droppable);
var generateUUID = function() {
return '12345';
}
// this will give you actuall output what you wanted
console.log(new Droppable);
因此,当您在调用Droppable之前调用函数generateUUID时,它将起作用。像这样 -
// initializes
var generateUUID = function() {
return '12345';
}
// initializes
function Droppable() {
this.relevant = true;
this.uuid = generateUUID();
}
// this will work as expected
console.log(new Droppable);
在JavaScript中,您可以用两种方法定义函数
var varibaleName = function(){
}
和
function variableName(){
}
存在显着差异。当您使用变量声明函数时,则在调用该变量需要注册的函数之前。
如果你这样打电话 -
varibaleName();
var varibaleName = function(){
}
这会给你一个错误。
但是,如果你这样打电话会起作用 -
varibaleName();
function varibaleName (){
}
所以这也应该有效 -
function Droppable() {
this.relevant = true;
this.uuid = generateUUID();
}
// this will work as expected
console.log(new Droppable);
function generateUUID() {
return '12345';
}
希望这是有道理的。
然而在角度中这将起作用 -
var myApp = angular.module("myApp", []);
myApp.controller("MyCtrl", function($scope){
function Droppable() {
this.relevant = true;
this.uuid = generateUUID();
}
var generateUUID = function() {
return '12345';
}
// initalize droppable areas
$scope.region1 = [new Droppable];
$scope.region2 = [new Droppable];
$scope.region3 = [new Droppable];
console.log( $scope.region1 );
});
但最佳做法是 -
myApp.controller("MyCtrl", function($scope){
// you can call this before Droppable or after
$scope.generateUUID = function() {
return '12345';
}
$scope.Droppable = function () {
this.relevant = true;
this.uuid = $scope.generateUUID();
}
// initalize droppable areas
$scope.region1 = [new $scope.Droppable];
console.log( $scope.region1 );
});
为什么我要调用带有$scope.
前缀的那些,因为稍后您可能需要在控制器与控制器之间进行通信,即使是在指令中!
快乐的编码和快乐的原型设计!这有助于您了解事情的运作方式。