【问题标题】:JS Function declarations should not be placed in blockJS 函数声明不应该放在块中
【发布时间】:2023-07-26 19:22:01
【问题描述】:

我已将 95% 的 'parentCtrl'(控制器)包裹在 'IF' 语句中,这样可以防止在用户未登录和授权时触发任何函数。由于这样做,我不断收到以下 JSHint 错误!

错误
JSHint 104:5 函数声明不应放在块中?

如果我删除 'IF' 语句,错误就会消失!

有关如何解决此问题的建议会很有帮助!

IF 声明

if($scope.user){}

控制器 JS

var fittingControllers = angular.module('fittingControllers',[]);
// 1. Parent Controller
fittingControllers.controller('parentCtrl', ['$scope', 'Auth', '$localStorage', '$filter', '$timeout', 'Notification', '$sce', '$state', function($scope, Auth, $localStorage, $filter, $timeout, Notification, $sce, $state) {
  //// Setup Authentication
  $scope.auth = Auth;
  $scope.user = $scope.auth.$getAuth();
  //// Facebook Login
  $scope.facebookLogin = function() {
    var scope = {scope: 'email,user_birthday'};
    $scope.auth.$authWithOAuthPopup('facebook', scope).then(function(auth){
      $state.go('main.statistics');
    })['catch'](function (error){
      console.log(error);
    });
  };
  //// Authentication Functions
  if($scope.user){
    //// Facebook Provider
    if($scope.user.provider === 'facebook'){
      //// Facebook Data
      $scope.uid = $scope.user.uid;
      $scope.displayName = $scope.user.facebook.displayName;
      $scope.firstName = $scope.user.facebook.cachedUserProfile.first_name;
      $scope.lastName = $scope.user.facebook.cachedUserProfile.last_name;
      $scope.dob = $scope.user.facebook.cachedUserProfile.birthday;
      $scope.emailAddress = $scope.user.facebook.email;
      $scope.profileImageURL = $scope.user.facebook.profileImageURL;
    }
    //// Password Provider
    else if($scope.user.provider === 'password'){
        //// Password Data TBC
    }
    //// Provider Results
    var uid = $scope.uid;
    var displayName = $scope.displayName;
    var firstName = $scope.firstName;
    var lastName = $scope.lastName;
    var dob = $scope.dob;
    var emailAddress = $scope.emailAddress;
    var profileImageURL = $scope.profileImageURL;
    //// Aditional Data (Test)
    var weddingDate = '21/09/2017';
    var bodyType = 'triangle';
    //// LocalStorage
    $scope.$storage = $localStorage;
    //// $localStorage.$reset();
    //// Storage Data
    if($scope.$storage.app === undefined) {
      $scope.$storage.app = ({
        //// User Account
        'account': [{
          //// User Information
          'userInfo': [
            {'id':uid,'username':displayName,'age':dob,'emailAddress':emailAddress,'telephoneNumber':'','weddingDate':weddingDate,'bodyType':bodyType}
          ]
        },{
          //// User BodyType
          'bodyInfo': [
            {'height':524,'chest':32,'waist':30,'hips':32,'thighs':20,'BodyType':''}
          ]
        },{
          //// User Love List
          'lovelist': [
            {'heart': [],'brokenheart': []}
          ]
        }],
        //// App Settings
        'settings': [{
          'introMsg': [
            {'lovelist': false},
            {'showStyle': false},
            {'secondOpionion': false}
          ]
        },{
          'introBtn': [
            {'lovelist': false},
            {'showStyle': false},
            {'secondOpionion': false}
          ]
        }],
        //// App Data
        'courtyard': [{
          //// Dress Collection
          'dresses': [
            {'id':'1','name':'Ritva Westenius 1','designer':'Ritva Westenius 2','description':'Pellentesque ultricies, sem vel pellentesque tempus, quam massa posuere mauris, gravida semper massa ante non risus. Ut scelerisque hendrerit arcu, ac scelerisque mi maximus in. Sed non bibendum sapien, ut blandit purus. Aenean a scelerisque mauris. Pellentesque augue augue, feugiat et dignissim sit amet, rhoncus sit amet metus.','bodyType': 'triangle','imageURL': '../img/dress1-body-small@2x.jpg'},
            {'id':'2','name':'Stephanie Allin 1','designer':'Stephanie Allin 2','description':'Vivamus mattis posuere eleifend. Etiam vitae mauris neque. Sed at quam quis felis elementum mattis eu id diam.','bodyType':'triangle','imageURL':'../img/dress1-body-medium@2x.jpg'},
            {'id':'3','name':'Allure Bridals 1','designer':'Allure Bridals 2','description':'Phasellus lorem urna, blandit in vestibulum vel, consectetur nec ipsum. Pellentesque tellus ipsum, tincidunt eget arcu euismod, vestibulum molestie dui.','bodyType':'round','imageURL': '../img/dress1-body-large@2x.jpg'},
            {'id':'10','name':'Pronovias Barcelona 1','designer':'Pronovias Barcelona 2','description': 'Vestibulum libero odio, suscipit vitae aliquam in, maximus eu purus. Morbi luctus elit nec elit euismod iaculis. Ut mi nisi, dignissim quis libero id, sagittis rhoncus leo. Pellentesque placerat mi non nunc tincidunt vestibulum. Suspendisse in ornare tortor.','bodyType':'triangle','imageURL':'../img/dress1-body-large@2x.jpg'},
            {'id':'11','name':'Chanticleer 1','designer':'Chanticleer 2','description':'Nulla ante mi, commodo vitae diam sed, aliquam consectetur ex. In maximus nisl urna, non aliquet leo finibus et. Donec rhoncus ipsum eget elementum accumsan. Nullam id tellus in magna molestie facilisis quis et tellus. Nunc nec feugiat ipsum.','bodyType':'triangle','imageURL':'../img/dress1-body-small@2x.jpg'},
            {'id':'7','name':'Alan Hannah 1','designer':'Alan Hannah 2','description':'Etiam non sagittis nisl. Suspendisse potenti. Quisque sed dolor vitae sem molestie interdum. Praesent leo lectus, cursus ac bibendum quis, accumsan in metus. Phasellus sagittis, lectus eget iaculis molestie, magna tortor fringilla neque, sit amet ultrices nunc erat sed augue.','bodyType':'triangle','imageURL':'../img/dress1-body-large@2x.jpg'}
          ]
        }]
      });
    } else {
      $scope.$storage.app = $scope.$storage.app;
    }
    //// Notification Function
    function notification(){
      $timeout(function(){
        Notification.bethan(
          {message:'Hi '+firstName+'! you’re not sure what to do? Hover the menu in the top right and click',positionY:'bottom',positionX:'left',delay:10000,templateUrl:"views/notification.html"}
        );
      }, 3000);
      $timeout(function() {
        Notification.rhiannon(
          {message:'This dress is perfect for a Triangle body shape like yours!',positionY:'bottom',positionX:'left',delay:null,templateUrl:"views/notification.html"}
        );
      }, 6000);
    }
    //// Alert Function
    function alertMessage(id) {
      //// Message ID
      var messageID = id;
      //// Alert Collection
      var messages = {
        "results": [
          {'id':'1','icon':'','button':true,'title':'Welcome','subtitle':'Hi '+firstName+', welcome to the Virtual Fitting room','content':'Here you will be able to browse through a selection of our dresses<br/>and shortlist them for future refrence. To help us find the best<br/>dress for you, please let us know a bit about yourself'},
          {'id':'2','icon':'','button':false,'title':'Raiding the Rails','subtitle':'','content':'From the measurments you have supplied, we see you have a triangle body shape.<br/>Please wait while we get together the 5 best dresses for your shape.'},
          {'id':'3','icon':'','button':false,'title':'My Love List','subtitle':'','content':'Any dresses you mark with a &#9829; will store<br/> into your Love list you can review at any<br/> point by clicking the heart icon.'},
          {'id':'4','icon':'','button':false,'title':'Show me the Style','subtitle':'','content':'Feel free to look through the rest of our<br/> collection and &#9829; any that you like.'},
          {'id':'5','icon':'','button':false,'title':'Second Optionions','subtitle':'','content':'It can be tough to choose, so why not ask<br/> the ones who know you best to help<br/>by voting for their favourites.'}
        ]
      };
      var messageResult = $filter('filter')(messages.results, {id: messageID})[0];
      var message = '<h2>'+messageResult.title+'</h2><h3>'+messageResult.subtitle+'</h3><p>'+messageResult.content+'</p>';
      $scope.message = $sce.trustAsHtml(message);
      $scope.showMessage = {active: true};
      //// Close Alert
      $scope.hideMessage = function() {
        $scope.showMessage.active = !$scope.showMessage.active;
        notification();
      };
      $scope.hideButton = {active: true};
      if (messageResult.button === true) {
        $scope.hideButton.active = !$scope.hideButton.active;
      }
    }
    alertMessage(1);
    //// Child Alert
    $scope.$on('eventName', function(event, args) {
      var getBodyType = $scope.$storage.app.account[0].userInfo[0].bodyType;
      var getID = $filter('filter')($scope.$storage.app.courtyard[0].dresses,{bodyType: getBodyType})[0].id;
      $scope.id = args.id;
      alertMessage($scope.id);
      $timeout(function() {
        if ($scope.id === 2) {
          $state.go('main.rail', {id: getID});
        } else if ($scope.id === 3) {}
      }, 3000);
      $timeout(function() {
        $scope.showMessage = {active: false};
      }, 6000);
    });
    //// Menu Function
    function menu(){
      $scope.hidden = false;
      //// Menu Collection
      $scope.items = [
        {name: 'Help',icon: 'svg/help.svg',direction: 'left',backgroundColor: 'rgb(239, 149, 73)'},
        {name: 'Book',icon: 'svg/book.svg',direction: 'left',backgroundColor: 'rgb(95, 205, 155)'},
        {name: 'Contact',icon: 'svg/contact.svg',direction: 'left',backgroundColor:'rgb(32, 133, 188)'},
        {name: 'Share',icon: 'svg/share.svg',direction: 'left',backgroundColor: 'rgb(102, 181, 215)'},
        {name: 'Exit',icon: 'svg/exit.svg',direction: 'left',backgroundColor: 'rgb(255, 206, 97)'}
      ];
    }
    menu();
    //// Menu Triggers
    $scope.menuButton = function(button) {
      if (button === 'Help') {
        alert('Help');
      } else if (button === 'Book') {
        alert('Book');
      } else if (button === 'Contact') {
        alert('Contact');
      } else if (button === 'Share') {
        alert('Share');
      } else if (button === 'Exit') {
        //// Remove Notifications
        Notification.clearAll();
        //// Unauthenticate
        $scope.auth.$unauth();
        //// State Change
        $timeout(function() {
          //// Remove Notifications (Again)
          Notification.clearAll();
          //// State Change
          $state.go('authentication');
        }, 3000);
      }
    };
    //// App Buttons (Love List, Show me the Style (Collection) & Second Opinion)
    $scope.$watch(function() {
      return angular.toJson([$scope.$storage.app.settings[1].introBtn[0]]);
    }, function() {
      if ($scope.$storage.app.settings[1].introBtn[0].lovelist === true) {
        $scope.loveListBtn = true;
      }
      if ($scope.$storage.app.settings[1].introBtn[0].showStyle === true) {
        $scope.showStyleBtn = true;
      }
      if ($scope.$storage.app.settings[1].introBtn[0].secondOpionion === true) {
        $scope.secondOpionionBtn = true;
      }
    });
    //// View Navigator (Pager)
    $scope.pager = function(url) {$state.go(url);};
  }
  //// Authentication End
}]);

【问题讨论】:

标签: javascript angularjs function jshint function-declaration


【解决方案1】:

将您的所有function 定义放在if 块之外

function notification()

function alertMessage(id)

function menu()

JavaScript 没有块作用域,它只有函数作用域。所以,不管你是否在 if 块中写函数定义,它在整个封闭的函数块中都是可用的。

因此 JSHint 会抛出该错误,因为它可能会给读者带来模棱两可的含义,即该函数仅在 if 块内可用

由于提升,如果您将函数声明放在同一个函数块中的调用/使用之后并不重要。

【讨论】:

  • 感谢@kulbhushan!
  • 将其标记为答案,因为它可能对其他社区成员有所帮助,很高兴它对您有所帮助
  • “所以,函数定义是否写在 if 块中并不重要,它在整个封闭函数块中都可用。” 这实际上不是真的。根据 ES5,declarations 函数在块中是被禁止的。但是,浏览器实现了不同的行为:Chrome 提升它们,Firefox 将它们视为函数表达式。我认为 ES6 解决了这个问题,但我不知道以哪种方式。
  • 例如这在 Chrome 和 Firefox 中的行为不同:foo(); if(false) { function foo() { console.log('hello chrome'); } } .