【问题标题】:variables not hoisting as expected in angularjsangularjs中的变量未按预期提升
【发布时间】:2014-10-08 16:34:25
【问题描述】:

我一直在关注 John Papa 和他的 Angular 风格指南建议。我喜欢将所有可用于视图的变量和方法放在控制器顶部并依靠 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 值未初始化。 如果把赋值语句移到变量声明下,ng-model就被初始化了。

为什么 javascript 不将 var dumbValue 提升到分配上方,或者是它,我不理解 Angular 处理它的方式?

【问题讨论】:

  • 嗨,变量像往常一样被提升。但与 JavaScript 的其余部分一样,赋值不会提升!这意味着,在这种情况下,您的 $scope.dumbValue 将被分配为空/未定义。
  • 如果您考虑一下,提升分配没有意义,因为 RHS 可能依赖于必须首先计算的其他值。

标签: javascript angularjs hoisting


【解决方案1】:

您必须将我链接到 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
}

然而,正如我所说,Papa 正在谈论将绑定到 $scope 的函数。他说而不是这样做:

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

    $scope.foo = foo;
}

这样做:

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

    function foo () {};
}

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

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

    foo = function () {};

    $scope.foo = foo;
}

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

就个人而言,我不喜欢爸爸在这里的建议。虽然我个人理解提升并且不被它所理解,但我看到许多开发人员通过编写代码来创建问题,这些代码在提升中会发生变化。在这种情况下,为了避免大多数开发人员误解我的代码,我非常特别地写我的代码,就像起重机会转换它一样。这也是JSLint's 默认设置让您编写它的方式。

【讨论】:

  • 感谢您的详尽解释。你是对的 - 我很困惑,因为我可以依靠函数语句来提升我使用变量声明的方式。
【解决方案2】:

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

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';
}

因此变量被提升,但设置为未定义。后来它得到了它的价值,但在这种情况下为时已晚。这就是不建议提升变量的原因。总是把它们放在首位。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-02
    相关资源
    最近更新 更多