变量没有像angularjs那样在预期中提升

时间:2014-10-08 16:34:26

标签: javascript angularjs hoisting

我一直在关注John Papa和他的角度风格指南建议。我喜欢将所有变量和方法都放在控制器顶部的视图中,并依赖javascript在运行时提升变量。我显然不明白吊装和我想的那样。在下面的例子中,我希望将dumbValue变量声明悬挂在$ scope.dumbValue赋值语句之上;

var app = angular.module('plunker', []);
app.controller('MainCtrl', [$scope, $http]);
function MainCtrl($scope,$http)
{
    $scope.dumbValue = dumbValue;
    var dumbValue = 'dumb';
}

但是在this Plunker你可以看到情况并非如此;选择的模型值未初始化。 如果在变量声明下移动赋值语句,则初始化ng-model。

为什么javascript不会将var dumbValue提升到作业之上,或者它是否存在与角度处理它的方式有关的东西,我不明白?

2 个答案:

答案 0 :(得分:4)

你必须把我与Papa为我推荐的地方联系起来,但我只看到Papa recommend doing this for "bindable members."他谈论的是功能 - 而不是标量值。你试图做后者,这样你就遇到了问题。

您可以看到,将变量的声明移动到作用域的顶部,而不是它们的定义(又名赋值)。如果您在一个陈述中声明和定义,则吊装将其分为两个陈述并提升前者。

所以这段代码:

var MainCtrl = function ($scope,$http) {
    $scope.dumbValue = dumbValue;

    var dumbValue = 'dumb';
}

与编写此代码相同(因为提升将其转换为此代码):

var MainCtrl = function ($scope,$http) {
    var dumbValue; // declared, not defined (hence the value `undefined`)

    $scope.dumbValue = dumbValue; // assignment of `undefined` to a property of $scope

    dumbValue = 'dumb'; // definition of your variable with a string value
}
然而,正如我所说,爸爸正在谈论将被$scope约束的功能。他说而不是这样做:

var MainCtrl = function ($scope,$http) {
    function foo () {};

    $scope.foo = foo;
}

这样做:

var MainCtrl = function ($scope,$http) {
    $scope.foo = foo;

    function foo () {};
}

这是因为提升将命名函数语句转换为变量声明,并将新变量定义为函数,然后将它们拆分为两个单独的语句并将它们放在顶部。所以Papa推荐的版本(最后一个代码块)通过吊装转换为:

var MainCtrl = function ($scope,$http) {
    var foo;

    foo = function () {};

    $scope.foo = foo;
}

如您所见,对命名函数语句的这种不同处理允许在绑定到foo之前将$scope定义为函数。

就个人而言,我不喜欢爸爸在这里的推荐。虽然我个人理解提升并且不了解它,但我已经看到许多开发人员通过编写代码来创建问题,这些代码在提升时会发生变化。在这种情况下,我非常特别地编写我的代码,因为提升器会对其进行转换,以避免我的代码被大多数开发人员误解。这是您JSLint's默认设置的方式。

答案 1 :(得分:1)

当你这样做时......

var app = angular.module('plunker', []);
app.controller('MainCtrl', [$scope, $http]);
function MainCtrl($scope,$http)
{
    $scope.dumbValue = dumbValue;
    var dumbValue = 'dumb';
}

这实际上是发生了什么。

var app = angular.module('plunker', []);
app.controller('MainCtrl', [$scope, $http]);
function MainCtrl($scope,$http)
{
    var dumbValue = undefined;
    $scope.dumbValue = dumbValue;
    dumbValue = 'dumb';
}

因此变量被挂起,但设置为undefined。然后它会得到它的价值,但在这种情况下为时已晚。这就是不建议吊装变量的原因。总是把它们放在首位。