AngularJS之代码风格36条建议【一】(九)

前言

其实在新学一门知识时,我们应该注意下怎么书写代码更加规范,从开始就注意养成一个良好的习惯无论是对于bug的查找还是走人后别人熟悉代码都是非常好的,利人利己的事情何乐而不为呢,关于AngularJS中的代码风格分为几节来阐述。希望对打算学习AngularJS的新手或者已经在路上的老手有那么一丢丢的帮助也是可以的。

普遍规则

tips 01(定义一个组件脚本文件时,建议此文件的代码少于400行)

(1)有利于单元测试和模拟测试。

(2)增加可读性、可维护性、避免和团队在源代码控制上的冲突。

(3)当在文件中组合组件时,可能会共享变量、依赖不需要的耦合从而避免潜在的bugs。

避免如下这样做:

angular
    .module('app', ['ngRoute'])
    .controller('SomeController', SomeController)
    .factory('someFactory', someFactory);

function SomeController() { }

function someFactory() { }

相同的组件应该分为各自的文件(推荐如下做):

// app.module.js
angular
    .module('app', ['ngRoute']);
    angular
    .module('app')
    .controller('SomeController', SomeController);

function SomeController() { }
angular
    .module('app')
    .factory('someFactory', someFactory);

function someFactory() { }

JavaScript作用域

tips 02 (包含Angular的组件应该作为匿名函数立即被调用)

(1)匿名函数移除了全局作用域中的变量,能够避免变量冲突以及变量长期存在于内存中。

(2)当代码经过捆绑和压缩到单个文件中,并将其文件部署到生产服务器中时会产生全局变量的冲突。

避免如下这样做:

angular
    .module('app')
    .factory('logger', logger);

function logger() { }

angular
    .module('app')
    .factory('storage', storage);

function storage() { }

推荐如下做:

(function() {
    'use strict';

    angular
        .module('app')
        .factory('logger', logger);

    function logger() { }
})();
(function() {
    'use strict';

    angular
        .module('app')
        .factory('storage', storage);

    function storage() { }
})();

定义模块

tips 03 (声明模块时不要用变量来返回)

一个文件中的组件,很少使用需要引入一个变量的模块。

避免如下这样做:

var app = angular.module('app', [
    'ngAnimate',
    'ngRoute',
    'app.shared',
    'app.dashboard'
]);

推荐如下做:

angular
    .module('app', [
        'ngAnimate',
        'ngRoute',
        'app.shared',
        'app.dashboard'
    ]);

使用模块

tips 04(使用模块时避免使用变量代替的应该是链式语法)

将使代码更加可读,避免变量的冲突和泄漏。

避免如下这样做:

var app = angular.module('app');
app.controller('SomeController', SomeController);

function SomeController() { }

推荐如下这样做:

angular
    .module('app')
    .controller('SomeController', SomeController);

function SomeController() { }

命名函数vs匿名函数

tips 05 (使用命名函数来作为函数的回调而非匿名函数)

使代码易读,易于调试且降低嵌套代码的回调量。

避免如下这样做:

angular
    .module('app')
    .controller('DashboardController', function() { })
    .factory('logger', function() { });

推荐如下这样做:

angular
    .module('app')
    .controller('DashboardController', DashboardController);

function DashboardController() { }
angular
    .module('app')
    .factory('logger', logger);

function logger() { }

控制器 

tips 06(使用controllerAs语法代替$scope语法)

避免如下:

<div ng-controller="CustomerController">
    {{ name }}
</div>

推荐如下:

<div ng-controller="CustomerController as customer">
    {{ customer.name }}
</div>

tips 07(使用控制器内部使用controllerAs语法代替$scope语法即再内部用this代替$scope)

避免如下:

function CustomerController($scope) {
    $scope.name = {};
    $scope.sendMessage = function() { };
}

推荐如下:

function CustomerController() {
    this.name = {};
    this.sendMessage = function() { };
}

tips 08(使用VM代替controllerAs语法即使用一个变量来捕获this,如VM,它代表ViewModel。)

this关键字代表上下文,在控制器内部使用函数时可能会改变它的上下文,用一个变量来捕获this能够避免面临这样的问题。

避免如下:

function CustomerController() {
    this.name = {};
    this.sendMessage = function() { };
}

推荐如下:

function CustomerController() {
    var vm = this;
    vm.name = {};
    vm.sendMessage = function() { };
}

tips 09(在控制器的最顶部按照字母大小来排序,而非通过控制器代码来进行扩展)

(1)在顶部绑定成员易于阅读同时帮助我们识别可以在控制器中绑定的成员并在视图中使用。

(2)使用匿名函数虽然可能,但是一旦代码量超过一定数量则降低了代码的可阅读性。

避免如下:

function SessionsController() {
    var vm = this;

    vm.gotoSession = function() {
      /* ... */
    };
    vm.refresh = function() {
      /* ... */
    };
    vm.search = function() {
      /* ... */
    };
    vm.sessions = [];
    vm.title = 'Sessions';
}

推荐如下:

function SessionsController() {
    var vm = this;

    vm.gotoSession = gotoSession;
    vm.refresh = refresh;
    vm.search = search;
    vm.sessions = [];
    vm.title = 'Sessions';

    ////////////

    function gotoSession() {
      /* */
    }

    function refresh() {
      /* */
    }

    function search() {
      /* */
    }
}

tips 10 (使用声明式函数来隐藏实现细节)

使用声明式函数来隐藏实现细节,并保持绑定的成员在顶部。当在控制器中需要绑定一个函数时,指向它到一个函数式声明紧接着在下面。即将成员绑定在顶部且使用声明式函数。

避免如下:

function AvengersController(avengersService, logger) {
    var vm = this;
    vm.avengers = [];
    vm.title = 'Avengers';

    var activate = function() {
        return getAvengers().then(function() {
            logger.info('Activated Avengers View');
        });
    }

    var getAvengers = function() {
        return avengersService.getAvengers().then(function(data) {
            vm.avengers = data;
            return vm.avengers;
        });
    }

    vm.getAvengers = getAvengers;

    activate();
}

推荐如下:

function AvengersController(avengersService, logger) {
    var vm = this;
    vm.avengers = [];
    vm.getAvengers = getAvengers;
    vm.title = 'Avengers';

    activate();

    function activate() {
        return getAvengers().then(function() {
            logger.info('Activated Avengers View');
        });
    }

    function getAvengers() {
        return avengersService.getAvengers().then(function(data) {
            vm.avengers = data;
            return vm.avengers;
        });
    }
}

tips 11(在控制器中通过服务和工厂将业务逻辑导入其中)

(1)业务逻辑可能在多个控制器中被重用,将服务通过函数进行暴露。

(2)在单元测试中,业务逻辑更容易被隔离,在控制器中进行调用时更容易被模拟。

(3)消除了依赖且在控制器中隐藏了实现的细节。

避免如下:

function OrderController($http, $q, config, userInfo) {
    var vm = this;
    vm.checkCredit = checkCredit;
    vm.isCreditOk;
    vm.total = 0;

    function checkCredit() {
        var settings = {};
        return $http.get(settings)
            .then(function(data) {
               vm.isCreditOk = vm.total <= maxRemainingAmount
            })
            .catch(function(error) {
            });
    };
}

推荐如下:

function OrderController(creditService) {
    var vm = this;
    vm.checkCredit = checkCredit;
    vm.isCreditOk;
    vm.total = 0;

    function checkCredit() {
       return creditService.isOrderTotalOk(vm.total)
          .then(function(isOk) { vm.isCreditOk = isOk; })
          .catch(showError);
    };
}

tips 12 (保持控制器关注)

对一个视图定义一个控制器,对于其他控制器不要重用控制器,代替的是将重用逻辑移到工厂以此来保持控制器简单,更多的是关注视图。

tips 13(分配控制器)

当控制器必须和一个视图配对并且组件会被其他控制器和视图重用时,通过路由来定义控制器。

避免如下:

angular
    .module('app')
    .config(config);

function config($routeProvider) {
    $routeProvider
        .when('/avengers', {
          templateUrl: 'avengers.html'
        });
}

<div ng-controller="AvengersController as vm">
</div>

推荐如下:

angular
    .module('app')
    .config(config);

function config($routeProvider) {
    $routeProvider
        .when('/avengers', {
            templateUrl: 'avengers.html',
            controller: 'Avengers',
            controllerAs: 'vm'
        });
}

<div>
</div>

服务

tips 14(单例)

服务被初始化通过new关键字,使用this关键字来修饰方法和变量,因为所有的服务是单例对象,所以对于每个injector的服务只有唯一的实例。

推荐如下:

// service
angular
    .module('app')
    .service('logger', logger);

function logger() {
  this.logError = function(msg) {
    /* */
  };
}
// factory
angular
    .module('app')
    .factory('logger', logger);

function logger() {
    return {
        logError: function(msg) {
          /* */
        }
   };
}

工厂

tips 15(将访问成员置顶)

(1)在顶部暴露要调用的服务的成员,加强可读性以及单元测试。

(2)当文件足够大时,可能需要滚动才能看到其暴露的函数。

(3)通过服务定义的接口在代码量超过100行时避免降低代码的可阅读性和造成更多的滚动。

避免如下:

function dataService() {
  var someValue = '';
  function save() {
    /* */
  };
  function validate() {
    /* */
  };

  return {
      save: save,
      someValue: someValue,
      validate: validate
  };
}

推荐如下:

function dataService() {
    var someValue = '';
    var service = {
        save: save,
        someValue: someValue,
        validate: validate
    };
    return service;

    ////////////

    function save() {
        /* */
    };

    function validate() {
        /* */
    };
}

服务

tips 16 (重构服务)

对于数据操作和将数据与工厂进行交互时重构逻辑,使数据服务负责ajax等或其他操作。

推荐如下:

angular
    .module('app.core')
    .factory('dataservice', dataservice);

dataservice.$inject = ['$http', 'logger'];

function dataservice($http, logger) {
    return {
        getAvengers: getAvengers
    };

    function getAvengers() {
        return $http.get('/api/maa')
            .then(getAvengersComplete)
            .catch(getAvengersFailed);

        function getAvengersComplete(response) {
            return response.data.results;
        }

        function getAvengersFailed(error) {
            logger.error('XHR Failed for getAvengers.' + error.data);
        }
    }
}

指令

tips 17(为每个指令定义一个文件,并以此指令命名)

(1)很容易将所有指令混合在一个文件中,但是很难对于共享跨应用程序或者共享模块等。

(2)每一个文件一个指令利于代码的可维护性。

避免如下:

angular
    .module('app.widgets')

    .directive('orderCalendarRange', orderCalendarRange)

    .directive('salesCustomerInfo', salesCustomerInfo)

function orderCalendarRange() {

}

function salesCustomerInfo() {
}

推荐如下:

angular
    .module('sales.order')
    .directive('acmeOrderCalendarRange', orderCalendarRange);

function orderCalendarRange() {
}
angular
    .module('sales.widgets')
    .directive('acmeSalesCustomerInfo', salesCustomerInfo);

function salesCustomerInfo() {
}

tips 18 (提供唯一的指令前缀)

提供一个短的、唯一的、描述性的指令前缀。例如cnblogsIngUserInfo,则在html中被声明为cnblogs-ing-user-info。

可以用唯一的指令前缀来标识指令的背景和来源,例如上述的cnblogsIngUserInfo,cnblogs代表博客园,而Ing代表闪存,User代表用户,info代表信息。

tips 19(对元素和特性进行约束) 

在AngularJS 1.3+默认的是EA,在此之下需要用Restrict来进行限制。

避免如下:

<div class="my-calendar-range"></div>

推荐如下:

<my-calendar-range></my-calendar-range>
<div my-calendar-range></div>

tips 20 (在指令中使用controllerAs语法与控制器和视图中使用该语法要一致)

推荐如下:

<div my-example max="77"></div>
angular
    .module('app')
    .directive('myExample', myExample);

function myExample() {
    var directive = {
        restrict: 'EA',
        templateUrl: 'app/feature/example.directive.html',
        scope: {
            max: '='
        },
        controller: ExampleController,
        controllerAs: 'vm'
    };

    return directive;
}

function ExampleController() {
    var vm = this;
    vm.min = 3;
    console.log('CTRL: vm.min = %s', vm.min);
    console.log('CTRL: vm.max = %s', vm.max);
}
<!-- example.directive.html -->
<div>hello world</div>
<div>max={{vm.max}}<input ng-model="vm.max"/></div>
<div>min={{vm.min}}<input ng-model="vm.min"/></div>

tips 21(在指令添加属性bindToController = true)

当在指令中使用controllerAs语法时,若我们想绑定外部作用域到指令的控制器的作用域令bindToController = true。

如上述tips 20初始化文本值为vm.max为undifined,若设置bindToController = true,则vm.max = 77;

解析promise 

tips 22(控制器激活promise)

在一个activate函数中来启动控制器的逻辑。

(1)在一致的地方放置启动逻辑有利于问题的定位以及测试,同时避免在跨控制器中传播激活逻辑。

(2)控制器激活可以更方便地重用刷新的控制器或者视图逻辑,保持逻辑在一起,使得更快加载视图。

避免如下:

function AvengersController(dataservice) {
    var vm = this;
    vm.avengers = [];
    vm.title = 'Avengers';

    dataservice.getAvengers().then(function(data) {
        vm.avengers = data;
        return vm.avengers;
    });
}

推荐如下:

function AvengersController(dataservice) {
    var vm = this;
    vm.avengers = [];
    vm.title = 'Avengers';

    activate();

    ////////////

    function activate() {
        return dataservice.getAvengers().then(function(data) {
            vm.avengers = data;
            return vm.avengers;
        })
    }
}

tips 23(路由解析promise) 

在控制器被激活之前,若控制器依赖于promise需要被解析时,在控制器逻辑执行之前通过$routerProvider来解析这些依赖。在控制器激活之前,如果需要依据条件来取消路由,通过路由解析来进行。

(1)在控制器加载之前之前它可能需要获取数据,数据可能来源于自定义的工厂或$http的promise。使用路由解析使得promise在控制器逻辑执行之前被解析,因此它可能根据在promise的数据来采取不同的动作。

(2)在路由和控制器的激活函数中的代码执行之后,视图开始被正确加载,当激活promise解析时,数据绑定开始进行。

避免如下:

angular
    .module('app')
    .controller('AvengersController', AvengersController);

function AvengersController(movieService) {
    var vm = this;
    // unresolved
    vm.movies;
    // resolved asynchronously
    movieService.getMovies().then(function(response) {
        vm.movies = response.movies;
    });
}

推荐如下:

// route-config.js
angular
    .module('app')
    .config(config);

function config($routeProvider) {
    $routeProvider
        .when('/avengers', {
            templateUrl: 'avengers.html',
            controller: 'AvengersController',
            controllerAs: 'vm',
            resolve: {
                moviesPrepService: function(movieService) {
                    return movieService.getMovies();
                }
            }
        });
}

// avengers.js
angular
    .module('app')
    .controller('AvengersController', AvengersController);

AvengersController.$inject = ['moviesPrepService'];
function AvengersController(moviesPrepService) {
    var vm = this;
    vm.movies = moviesPrepService.movies;
}

或者推荐如下操作(更易于调试和处理依赖注入):

// route-config.js
angular
    .module('app')
    .config(config);

function config($routeProvider) {
    $routeProvider
        .when('/avengers', {
            templateUrl: 'avengers.html',
            controller: 'AvengersController',
            controllerAs: 'vm',
            resolve: {
                moviesPrepService: moviesPrepService
            }
        });
}

function moviesPrepService(movieService) {
    return movieService.getMovies();
}

// avengers.js
angular
    .module('app')
    .controller('AvengersController', AvengersController);

AvengersController.$inject = ['moviesPrepService'];
function AvengersController(moviesPrepService) {
      var vm = this;
      vm.movies = moviesPrepService.movies;
}

tips 24(用promise来处理异常) 

一个promise的catch模块必须要返回一个reject的promise来在promise链中维护异常。

在服务或者工厂中一定要处理异常。

(1)如果一个catch模块没有返回一个reject的promise,那么此时这个promise的调用者不知道异常的出现,接着调用者的then然后被执行,用户根本不知道发生了什么。

(2)避免隐藏的错误以及误导用户。

避免如下:

function getCustomer(id) {
    return $http.get('/api/customer/' + id)
        .then(getCustomerComplete)
        .catch(getCustomerFailed);

    function getCustomerComplete(data, status, headers, config) {
        return data.data;
    }

    function getCustomerFailed(e) {
        var newMessage = 'XHR Failed for getCustomer'
        if (e.data && e.data.description) {
          newMessage = newMessage + '\n' + e.data.description;
        }
        e.data.description = newMessage;
        logger.error(newMessage);
        // ***
        // Notice there is no return of the rejected promise
        // ***
    }
}

推荐如下:

function getCustomer(id) {
    return $http.get('/api/customer/' + id)
        .then(getCustomerComplete)
        .catch(getCustomerFailed);

    function getCustomerComplete(data, status, headers, config) {
        return data.data;
    }

    function getCustomerFailed(e) {
        var newMessage = 'XHR Failed for getCustomer'
        if (e.data && e.data.description) {
          newMessage = newMessage + '\n' + e.data.description;
        }
        e.data.description = newMessage;
        logger.error(newMessage);
        return $q.reject(e);
    }
}

手动标注依赖注入

tips 25(手动识别依赖)

使用$inject来识别AngularJS组件中的依赖。

避免如下:

angular
    .module('app')
    .controller('DashboardController',
        ['$location', '$routeParams', 'common', 'dataservice',
            function Dashboard($location, $routeParams, common, dataservice) {}
        ]);

避免如下:

angular
  .module('app')
  .controller('DashboardController',
      ['$location', '$routeParams', 'common', 'dataservice', Dashboard]);

function Dashboard($location, $routeParams, common, dataservice) {
}

推荐如下:

angular
    .module('app')
    .controller('DashboardController', DashboardController);

DashboardController.$inject = ['$location', '$routeParams', 'common', 'dataservice'];

function DashboardController($location, $routeParams, common, dataservice) {
}

注意:当函数是如下一个返回语句,此时$inject可能无法访问(例如在指令中),此时解决这个问题的办法是将$inject移动到控制器的外面。

tips 26($inject无效的情况)

避免如下:

function outer() {
    var ddo = {
        controller: DashboardPanelController,
        controllerAs: 'vm'
    };
    return ddo;

    DashboardPanelController.$inject = ['logger']; // Unreachable
    function DashboardPanelController(logger) {
    }
}

推荐如下:

function outer() {
    var ddo = {
        controller: DashboardPanelController,
        controllerAs: 'vm'
    };
    return ddo;
}

DashboardPanelController.$inject = ['logger'];
function DashboardPanelController(logger) {
}

tips 27(手动解析路由依赖)

使用$inject来手动识别Angular组件的路由解析依赖。

推荐如下:

function config($routeProvider) {
    $routeProvider
        .when('/avengers', {
            templateUrl: 'avengers.html',
            controller: 'AvengersController',
            controllerAs: 'vm',
            resolve: {
                moviesPrepService: moviesPrepService
            }
        });
}

moviesPrepService.$inject = ['movieService'];
function moviesPrepService(movieService) {
    return movieService.getMovies();
}

异常处理 

tips 28(用decorators来配置处理异常)

配置时使用$provider服务,当异常出现时在$exceptionHandler中使用decorator来处理异常。

提供一致的方式在运行时来处理未捕获的异常。

推荐如下:

angular
    .module('blocks.exception')
    .config(exceptionConfig);

exceptionConfig.$inject = ['$provide'];

function exceptionConfig($provide) {
    $provide.decorator('$exceptionHandler', extendExceptionHandler);
}

extendExceptionHandler.$inject = ['$delegate', 'toastr'];

function extendExceptionHandler($delegate, toastr) {
    return function(exception, cause) {
        $delegate(exception, cause);
        var errorData = {
            exception: exception,
            cause: cause
        };
        toastr.error(exception.msg, errorData);
    };
}

tips 29(创建工厂并暴露其接口来捕获异常) 

在代码执行过程中可能会抛出异常,我们需要提供统一的方式来捕获异常。

推荐如下:

angular
    .module('blocks.exception')
    .factory('exception', exception);

exception.$inject = ['logger'];

function exception(logger) {
    var service = {
        catcher: catcher
    };
    return service;

    function catcher(message) {
        return function(reason) {
            logger.error(message, reason);
        };
    }
}

tips  30(使用$document和$window代替document和window)

在AngularJS中存在$document和$window两个服务来代替document和window利于模拟和测试。

tips 31(使用$interval和$timeout代替interval和timeout)

 在AngularJS中存在$interval和$timeout两个服务来代替interval和timeout利于测试和处理Angular的digest生命周期从而保持数据同步绑定。

命名

通过使用统一的命名方式来为所有组件命名,推荐的方式为feature.type.js。如下:

文件名:cnblogs.controller.js。

注册的组件名:CnblogsController。

tips 32(文件命名的特点)

避免如下:

// Controllers
avengers.js
avengers.controller.js
avengersController.js

// Services/Factories
logger.js
logger.service.js
loggerService.js

推荐如下:

// controllers
avengers.controller.js
avengers.controller.spec.js

// services/factories
logger.service.js
logger.service.spec.js

// constants
constants.js

// module definition
avengers.module.js

// routes
avengers.routes.js
avengers.routes.spec.js

// configuration
avengers.config.js

// directives
avenger-profile.directive.js
avenger-profile.directive.spec.js

tips 33(控制器命名后缀为Controller)

控制器命名后缀是最常用且更明确、具体的描述。

推荐如下:

angular
    .module
    .controller('AvengersController', AvengersController);

function AvengersController() { }

tips 34(工厂和服务命名) 

根据其特征来统一为所有服务和工厂来命名,使用骆驼风格来命名。避免工厂和服务前缀使用$。

(1)提供一致的方式来快速识别和引用工厂。

(2)避免命名冲突。

(3)清除服务名称,如logger,不需要其后缀。

推荐如下:

// logger.service.js
angular
    .module
    .factory('logger', logger);

function logger() { }
// credit.service.js
angular
    .module
    .factory('creditService', creditService);

function creditService() { }

// customer.service.js
angular
    .module
    .service('customerService', customerService);

function customerService() { }

tips 36(指令组件命名)

通过使用骆驼风格来为指令组件统一命名,使用短前缀来描述这个区域信息(例如:前缀可为公司名称或者项目名称)。

提供统一的方式来快速识别和引用组件

推荐如下:

// cnblogs-profile.directive.js
angular
    .module
    .directive('xxCnblogsProfile', xxCnblogsrProfile);

// usage is <xx-cnblogs-profile> </xx-cnblogs-profile>

function xxCnblogsProfile() { }

总结

本节我们讲了在AngularJS中的代码风格,我们可以一定不需要这样做,但是我们推荐这样做。

时间: 2024-09-13 14:44:03

AngularJS之代码风格36条建议【一】(九)的相关文章

优化PHP代码的53条建议_php技巧

1.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. 2.$row['id'] 的速度是$row[id]的7倍. 3.echo 比 print 快,并且使用echo的多重参数(译注:指用逗号而不是句点)代替字符串连接,比如echo $str1,$str2. 4.在执行for循环之前确定最大循环数,不要每循环一次都计算最大值,最好运用foreach代替. 5.注销那些不用的变量尤其是大数组,以便释放内存. 6.尽量避免使用__get,__set,__autol

C# 开发者审查代码的41条建议

1. 确保没有任何警告(warnings). 2.如果先执行Code Analysis(启用所有Microsoft Rules)再消除所有警告就更好了. 3. 去掉所有没有用到的usings.编码过程中去掉多余代码是个好习惯.(参考:msdn) 4. 在合理的地方检查对象是否为'null',避免运行的时候出现Null Reference Exception. 5. 始终遵循命名规范.一般而言变量参数使用驼峰命名法,方法名和类名使用Pascal命名法.(参考:msdn) 6. 请确保你了解SOLI

JAVA代码编写的30条建议

JAVA代码编写的30条建议 (1) 类名首字母应该大写.字段.方法以及对象(句柄)的首字母应小写.对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母.例如: ThisIsAClassName thisIsMethodOrFieldName 若在定义中出现了常数初始化字符,则大写static final基本类型标识符中的所有字母.这样便可标志出它们属于编译期的常数. Java包(Package)属于一种特殊情况:它们全都是小写字母,即便中间的单词亦是如此.对于域名扩展名称

工商联建议发改委牵头制订新36条实施细则

肖明 5月19日,中央统战部礼堂一个关于"新36条"的座谈会,几乎成了诉苦会. 与会企业界人士几乎异口同声地表示,希望由国家发改委牵头,敦促各个部门和地方政府出台落实<国务院关于鼓励与引导民间投资健康发展的若干 意见>("新36条")的细则,否则可能还是和5年前出台的"非公36条"一样成为一纸空文. 全国政协副主席.全国工商联主席黄孟复建议,国务院应有一个部门和一个领导专门负责牵头制订"新36条"实施细则,其中国资

新36条鼓励民企参与国企改革专家建议实行金股制

新非公36条鼓励民企参与国企改革 专家建议可实行黄金股制度 4月14日下午消息 国务院昨日发布<关于鼓励和引导民间投资健康发展的若干 意见>,鼓励民企参与国企改制重组,合理降低国有控股企业中的国资比例. <若干意见>又被称为"新非公经济36条",这是改革开放以来国务院出台的第一份专门针对民间投资发展.管理和调控方面的综合性政策文件. <若干意见>称,鼓励和引导民间资本重组联合和参与国有企业改革.通过参股.控股.资产收购等多种方式,参与国有企业改制重组

写出高效jquery代码的19条指南

 讨论jQuery和javascript性能的文章并不罕见.然而,本文我计划总结一些速度方面的技巧和我本人的一些建议,来提升你的jQuery和javascript代码.好的代码会带来速度的提升.快速渲染和响应意味着更好的用户体验 首先,在脑子里牢牢记住jQuery就是javascript.这意味着我们应该采取相同的编码惯例,风格指南和最佳实践. 首先,如果你是一个javascript新手,我建议您阅读 <给JavaScript初学者的24条最佳实践> ,这是一篇高质量的javascript教程

JavaScript代码风格要素

1920年,由威廉·斯特伦克(William Strunk jr .)撰写的<英语写作手册:风格的要素(The Elements of Style)>出版了,这本书列举了7条英文写作的准则,过了一个世纪,这些准则并没有过时.对于工程师来说,你可以在自己的编码风格中应用类似的建议来指导日常的编码,提高自己的编码水平. 需要注意的是,这些准则不是一成不变的法则.如果违背它们,能够让代码可读性更高,那么便没有问题,但请特别小心并时刻反思.这些准绳是经受住了时间考验的,有充分的理由说明:它们通常是正确

代码风格

头文件的作用 申明将被程序用到的函数.变量和定义类型(包括:常量.类定义.模板定义--) 正确使用头文件 第1点:  头文件中应该只包含函数和变量的申明,而不是定义. 例如: 在 main.cpp中 int mousex; 在 headers.h 中 extern int mousex; 如果多个cpp文件include了一个定义了变量的头文件,那么你将看到下面的错误信息 "error LNK2005: "int mousex" (?mousex@@3HA) already

写出高效jquery代码的19条指南_jquery

首先,在脑子里牢牢记住jQuery就是javascript.这意味着我们应该采取相同的编码惯例,风格指南和最佳实践.首先,如果你是一个javascript新手,我建议您阅读 <给JavaScript初学者的24条最佳实践> ,这是一篇高质量的javascript教程,接触jQuery之前最好先阅读.当你准备使用jQuery,我强烈建议你遵循下面这些指南:1.缓存变量DOM遍历是昂贵的,所以尽量将会重用的元素缓存. 复制代码 代码如下: // 糟糕 h = $('#element').heigh