前端JavaScript规范


摘要: JavaScript规范 目录 类型 对象 数组 字符串 函数 属性 变量 条件表达式和等号 块 注释 空白 逗号 分号 类型转换 命名约定 存取器 构造器 事件 模块 jQuery ES5 兼容性 HTML、CSS、JavaScript分离 使用jsHint 前端工具 类型 原始值: 相当于传值(JavaScript对象都提供了字面量),使用字面量创建对象。

JavaScript规范

目录

  1. 类型
  2. 对象
  3. 数组
  4. 字符串
  5. 函数
  6. 属性
  7. 变量
  8. 条件表达式和等号
  9. 注释
  10. 空白
  11. 逗号
  12. 分号
  13. 类型转换
  14. 命名约定
  15. 存取器
  16. 构造器
  17. 事件
  18. 模块
  19. jQuery
  20. ES5 兼容性
  21. HTML、CSS、JavaScript分离
  22. 使用jsHint
  23. 前端工具

类型

  • 原始值: 相当于传值(JavaScript对象都提供了字面量),使用字面量创建对象。

    • string
    • number
    • boolean
    • null
    • undefined
    var foo = 1, bar = foo; bar = 9; console.log(foo, bar); // => 1, 9
  • 复杂类型: 相当于传引用

    • object
    • array
    • function
    var foo = [1, 2], bar = foo; bar[0] = 9; console.log(foo[0], bar[0]); // => 9, 9

对象

  • 使用字面值创建对象

    // bad
    var item = new Object(); // good var item = {};
  • 不要使用保留字 reserved words 作为键

    // bad
    var superman = { class: 'superhero', default: { clark: 'kent' }, private: true }; // good var superman = { klass: 'superhero', defaults: { clark: 'kent' }, hidden: true };

数组

  • 使用字面值创建数组

    // bad
    var items = new Array(); // good var items = [];
  • 如果你不知道数组的长度,使用push

    var someStack = []; // bad someStack[someStack.length] = 'abracadabra'; // good someStack.push('abracadabra');
  • 当你需要拷贝数组时使用slice. jsPerf

    var len = items.length, itemsCopy = [], i; // bad for (i = 0; i < len; i++) { itemsCopy[i] = items[i]; } // good itemsCopy = items.slice();
  • 使用slice将类数组的对象转成数组.

    function trigger() { var args = [].slice.apply(arguments); ... }

字符串

  • 对字符串使用单引号 ''(因为大多时候我们的字符串。特别html会出现")

    // bad
    var name = "Bob Parr"; // good var name = 'Bob Parr'; // bad var fullName = "Bob " + this.lastName; // good var fullName = 'Bob ' + this.lastName;
  • 超过80(也有规定140的,项目具体可制定)个字符的字符串应该使用字符串连接换行

  • 注: 如果过度使用,长字符串连接可能会对性能有影响. jsPerf & Discussion

    // bad
    var errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.'; // bad var errorMessage = 'This is a super long error that \ was thrown because of Batman. \ When you stop to think about \ how Batman had anything to do \ with this, you would get nowhere \ fast.'; // good var errorMessage = 'This is a super long error that ' + 'was thrown because of Batman.' + 'When you stop to think about ' + 'how Batman had anything to do ' + 'with this, you would get nowhere ' + 'fast.';
  • 编程时使用join而不是字符串连接来构建字符串,特别是IE: jsPerf.

    var items,messages, length, i; messages = [{ state: 'success', message: 'This one worked.' },{ state: 'success', message: 'This one worked as well.' },{ state: 'error', message: 'This one did not work.' }]; length = messages.length; // bad function inbox(messages) { items = '<ul>'; for (i = 0; i < length; i++) { items += '<li>' + messages[i].message + '</li>'; } return items + '</ul>'; } // good function inbox(messages) { items = []; for (i = 0; i < length; i++) { items[i] = messages[i].message; } return '<ul><li>' + items.join('</li><li>') + '</li></ul>'; }

函数

  • 函数表达式:

    // 匿名函数表达式
    var anonymous = function() { return true; }; // 有名函数表达式 var named = function named() { return true; }; // 立即调用函数表达式 (function() { console.log('Welcome to the Internet. Please follow me.'); })();
  • 绝对不要在一个非函数块里声明一个函数,把那个函数赋给一个变量。浏览器允许你这么做,但是它们解析不同。

  • 注: ECMA-262定义把定义为一组语句,函数声明不是一个语句。阅读ECMA-262对这个问题的说明.

    // bad
    if (currentUser) { function test() { console.log('Nope.'); } } // good if (currentUser) { var test = function test() { console.log('Yup.'); }; }
  • 绝对不要把参数命名为 arguments, 这将会逾越函数作用域内传过来的 arguments 对象.

    // bad
    function nope(name, options, arguments) { // ...stuff... } // good function yup(name, options, args) { // ...stuff... }

属性

  • 当使用变量和特殊非法变量名时,访问属性时可以使用中括号(. 优先).

    var luke = { jedi: true, age: 28 }; function getProp(prop) { return luke[prop]; } var isJedi = getProp('jedi');

变量

  • 总是使用 var 来声明变量,如果不这么做将导致产生全局变量,我们要避免污染全局命名空间。

    // bad
    superPower = new SuperPower(); // good var superPower = new SuperPower();
  • 使用一个 var 以及新行声明多个变量,缩进4个空格。

    // bad
    var items = getItems(); var goSportsTeam = true; var dragonball = 'z'; // good var items = getItems(), goSportsTeam = true, dragonball = 'z';
  • 最后再声明未赋值的变量,当你想引用之前已赋值变量的时候很有用。

    // bad
    var i, len, dragonball, items = getItems(), goSportsTeam = true; // bad var i, items = getItems(), dragonball, goSportsTeam = true, len; // good var items = getItems(), goSportsTeam = true, dragonball, length, i;
  • 在作用域顶部声明变量,避免变量声明和赋值引起的相关问题。

    // bad
    function() { test(); console.log('doing stuff..'); //..other stuff.. var name = getName(); if (name === 'test') { return false; } return name; } // good function() { var name = getName(); test(); console.log('doing stuff..'); //..other stuff.. if (name === 'test') { return false; } return name; } // bad function() { var name = getName(); if (!arguments.length) { return false; } return true; } // good function() { if (!arguments.length) { return false; } var name = getName(); return true; }

条件表达式和等号

  • 合理使用 === 和 !== 以及 == 和 !=.
  • 合理使用表达式逻辑操作运算.
  • 条件表达式的强制类型转换遵循以下规则:

    • 对象 被计算为 true
    • Undefined 被计算为 false
    • Null 被计算为 false
    • 布尔值 被计算为 布尔的值
    • 数字 如果是 +0, -0, or NaN 被计算为 false , 否则为 true
    • 字符串 如果是空字符串 '' 则被计算为 false, 否则为 true
    if ([0]) { // true // An array is an object, objects evaluate to true }
  • 使用快捷方式.

    // bad
    if (name !== '') { // ...stuff... } // good if (name) { // ...stuff... } // bad if (collection.length > 0) { // ...stuff... } // good if (collection.length) { // ...stuff... }
  • 阅读 Truth Equality and JavaScript 了解更多

  • 给所有多行的块使用大括号

    // bad
    if (test) return false; // good if (test) return false; // good if (test) { return false; } // bad function() { return false; } // good function() { return false; }

注释

  • 使用 /** ... */ 进行多行注释,包括描述,指定类型以及参数值和返回值

    // bad
    // make() returns a new element // based on the passed in tag name // // @param <String> tag // @return <Element> element function make(tag) { // ...stuff... return element; } // good /** * make() returns a new element * based on the passed in tag name * * @param <String> tag * @return <Element> element */ function make(tag) { // ...stuff... return element; }
  • 使用 // 进行单行注释,在评论对象的上面进行单行注释,注释前放一个空行.

    // bad
    var active = true; // is current tab // good // is current tab var active = true; // bad function getType() { console.log('fetching type...'); // set the default type to 'no type' var type = this._type || 'no type'; return type; } // good function getType() { console.log('fetching type...'); // set the default type to 'no type' var type = this._type || 'no type'; return type; }
  • 如果你有一个问题需要重新来看一下或如果你建议一个需要被实现的解决方法的话需要在你的注释前面加上 FIXME 或 TODO 帮助其他人迅速理解

    function Calculator() { // FIXME: shouldn't use a global here total = 0; return this; }
    function Calculator() { // TODO: total should be configurable by an options param this.total = 0; return this; }
  • 满足规范的文档,在需要文档的时候,可以尝试jsdoc.

空白

  • 缩进、格式化能帮助团队更快得定位修复代码BUG.
  • 将tab设为4个空格

    // bad
    function() { ∙∙var name; } // bad function() { ∙var name; } // good function() { ∙∙∙∙var name; }
  • 大括号前放一个空格

    // bad
    function test(){ console.log('test'); } // good function test() { console.log('test'); } // bad dog.set('attr',{ age: '1 year', breed: 'Bernese Mountain Dog' }); // good dog.set('attr', { age: '1 year', breed: 'Bernese Mountain Dog' });
  • 在做长方法链时使用缩进.

    // bad
    $('#items').find('.selected').highlight().end().find('.open').updateCount(); // good $('#items') .find('.selected') .highlight() .end() .find('.open') .updateCount(); // bad var leds = stage.selectAll('.led').data(data).enter().append('svg:svg').class('led', true) .attr('width', (radius + margin) * 2).append('svg:g') .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') .call(tron.led); // good var leds = stage.selectAll('.led') .data(data) .enter().append('svg:svg') .class('led', true) .attr('width', (radius + margin) * 2) .append('svg:g') .attr('transform', 'translate(' + (radius + margin) + ',' + (radius + margin) + ')') .call(tron.led);

逗号

  • 不要将逗号放前面

    // bad
    var once , upon , aTime; // good var once, upon, aTime; // bad var hero = { firstName: 'Bob' , lastName: 'Parr' , heroName: 'Mr. Incredible' , superPower: 'strength' }; // good var hero = { firstName: 'Bob', lastName: 'Parr', heroName: 'Mr. Incredible', superPower: 'strength' };
  • 不要加多余的逗号,这可能会在IE下引起错误,同时如果多一个逗号某些ES3的实现会计算多数组的长度。

    // bad
    var hero = { firstName: 'Kevin', lastName: 'Flynn', }; var heroes = [ 'Batman', 'Superman', ]; // good var hero = { firstName: 'Kevin', lastName: 'Flynn' }; var heroes = [ 'Batman', 'Superman' ];

分号

  • 语句结束一定要加分号

    // bad
    (function() { var name = 'Skywalker' return name })() // good (function() { var name = 'Skywalker'; return name; })(); // good ;(function() { var name = 'Skywalker'; return name; })();

类型转换

  • 在语句的开始执行类型转换.
  • 字符串:

    //  => this.reviewScore = 9;// bad var totalScore = this.reviewScore + ''; // good var totalScore = '' + this.reviewScore; // bad var totalScore = '' + this.reviewScore + ' total score'; // good var totalScore = this.reviewScore + ' total score';
  • 对数字使用 parseInt 并且总是带上类型转换的基数.,如parseInt(value, 10)

    var inputValue = '4'; // bad var val = new Number(inputValue); // bad var val = +inputValue; // bad var val = inputValue >> 0; // bad var val = parseInt(inputValue); // good var val = Number(inputValue); // good var val = parseInt(inputValue, 10); // good /** * parseInt was the reason my code was slow. * Bitshifting the String to coerce it to a * Number made it a lot faster. */ var val = inputValue >> 0;
  • 布尔值:

    var age = 0; // bad var hasAge = new Boolean(age); // good var hasAge = Boolean(age); // good var hasAge = !!age;

命名约定

  • 避免单个字符名,让你的变量名有描述意义。

    // bad
    function q() { // ...stuff... } // good function query() { // ..stuff.. }
  • 当命名对象、函数和实例时使用驼峰命名规则

    // bad
    var OBJEcttsssss = {}; var this_is_my_object = {}; var this-is-my-object = {}; function c() {}; var u = new user({ name: 'Bob Parr' }); // good var thisIsMyObject = {}; function thisIsMyFunction() {}; var user = new User({ name: 'Bob Parr' });
  • 当命名构造函数或类时使用驼峰式大写

    // bad
    function user(options) { this.name = options.name; } var bad = new user({ name: 'nope' }); // good function User(options) { this.name = options.name; } var good = new User({ name: 'yup' });
  • 命名私有属性时前面加个下划线 _

    // bad
    this.__firstName__ = 'Panda'; this.firstName_ = 'Panda'; // good this._firstName = 'Panda';
  • 当保存对 this 的引用时使用 self(python 风格),避免this issue.Angular建议使用vm(MVVM模式中view-model)

    // good
    function() { var self = this; return function() { console.log(self); }; }

存取器

  • 属性的存取器函数不是必需的
  • 如果你确实有存取器函数的话使用getVal() 和 setVal(‘hello’),java getter、setter风格或者jQuery风格

  • 如果属性是布尔值,使用isVal() 或 hasVal()

    // bad
    if (!dragon.age()) { return false; } // good if (!dragon.hasAge()) { return false; }
  • 可以创建get()和set()函数,但是要保持一致

    function Jedi(options) { options || (options = {}); var lightsaber = options.lightsaber || 'blue'; this.set('lightsaber', lightsaber); } Jedi.prototype.set = function(key, val) { this[key] = val; }; Jedi.prototype.get = function(key) { return this[key]; };

构造器

  • 给对象原型分配方法,而不是用一个新的对象覆盖原型,覆盖原型会使继承出现问题。

    function Jedi() { console.log('new jedi'); } // bad Jedi.prototype = { fight: function fight() { console.log('fighting'); }, block: function block() { console.log('blocking'); } }; // good Jedi.prototype.fight = function fight() { console.log('fighting'); }; Jedi.prototype.block = function block() { console.log('blocking'); };
  • 方法可以返回 this 帮助方法可链。

    // bad
    Jedi.prototype.jump = function() { this.jumping = true; return true; }; Jedi.prototype.setHeight = function(height) { this.height = height; }; var luke = new Jedi(); luke.jump(); // => true luke.setHeight(20) // => undefined // good Jedi.prototype.jump = function() { this.jumping = true; return this; }; Jedi.prototype.setHeight = function(height) { this.height = height; return this; }; var luke = new Jedi(); luke.jump() .setHeight(20);
  • 可以写一个自定义的toString()方法,但是确保它工作正常并且不会有副作用。

    function Jedi(options) { options || (options = {}); this.name = options.name || 'no name'; } Jedi.prototype.getName = function getName() { return this.name; }; Jedi.prototype.toString = function toString() { return 'Jedi - ' + this.getName(); };

事件

  • 当给事件附加数据时,传入一个哈希而不是原始值,这可以让后面的贡献者加入更多数据到事件数据里而不用找出并更新那个事件的事件处理器

    // bad
    $(this).trigger('listingUpdated', listing.id); ... $(this).on('listingUpdated', function(e, listingId) { // do something with listingId });

    更好:

    // good
    $(this).trigger('listingUpdated', { listingId : listing.id }); ... $(this).on('listingUpdated', function(e, data) { // do something with data.listingId });

模块

  • 这个文件应该以驼峰命名,并在同名文件夹下,同时导出的时候名字一致
  • 对于公开API库可以考虑加入一个名为noConflict()的方法来设置导出的模块为之前的版本并返回它
  • 总是在模块顶部声明 'use strict';,引入[JSHint规范](http://jshint.com/)

    // fancyInput/fancyInput.js(function(global) {  'use strict'; var previousFancyInput = global.FancyInput; function FancyInput(options) { this.options = options || {}; } FancyInput.noConflict = function noConflict() { global.FancyInput = previousFancyInput; return FancyInput; }; global.FancyInput = FancyInput; })(this);

jQuery

  • 对于jQuery对象以$开头,以和原生DOM节点区分。

    // bad
    var menu = $(".menu"); // good var $menu = $(".menu");
  • 缓存jQuery查询

    // bad
    function setSidebar() { $('.sidebar').hide(); // ...stuff... $('.sidebar').css({ 'background-color': 'pink' }); } // good function setSidebar() { var $sidebar = $('.sidebar'); $sidebar.hide(); // ...stuff... $sidebar.css({ 'background-color': 'pink' }); }
  • 对DOM查询使用级联的 $('.sidebar ul') 或 $('.sidebar ul'),jsPerf

  • 对有作用域的jQuery对象查询使用 find

    // bad
    $('.sidebar', 'ul').hide(); // bad $('.sidebar').find('ul').hide(); // good $('.sidebar ul').hide(); // good $('.sidebar > ul').hide(); // good (slower) $sidebar.find('ul'); // good (faster) $($sidebar[0]).find('ul');
  • 每个页面只使用一次document的ready事件,这样便于调试与行为流跟踪。

    $(function(){ //do your page init. });
  • 事件利用jQuery.on从页面分离到JavaScript文件。

    // bad
    <a id="myLink" href="#" onclick="myEventHandler();"></a> // good <a id="myLink" href="#"></a> $("#myLink").on("click", myEventHandler); 
  • 对于Ajax使用promise方式。

        // bad$.ajax({ ... success : function(){ }, error : function(){ } }) // good $.ajax({. .. }).then( function( ){ // success }, function( ){ // error })
  • 利用promise的deferred对象解决延迟注册问题。

    var dtd = $.Deferred(); // 新建一个deferred对象   var wait = function(dtd){     var tasks = function(){       alert("执行完毕!");       dtd.resolve(); // 改变deferred对象的执行状态     };     setTimeout(tasks,5000);     return dtd;   };
  • HTML中Style、以及JavaScript中style移到CSS中class,在HTML、JavaScript中引入class,而不是直接style。

ECMAScript 5兼容性

尽量采用ES5方法,特别数组map、filter、forEach方法简化日常开发。在老式IE浏览器中引入ES5-shim。或者也可以考虑引入underscore、lodash 常用辅助库. 
- 参考Kangax的 ES5 compatibility table 
- JavaScript工具库之Lodash 
- Babel-现在开始使用 ES6

HTML、CSS、JavaScript分离

  • 页面DOM结构使用HTML,样式则采用CSS,动态DOM操作JavaScript。不要混用在HTML中
  • 分离在不同类型文件,文件link。
  • HTML、CSS、JavaScript变量名都需要有业务价值。CSS以中划线分割的全小写命名,JavaScript则首字母小写的驼峰命名。
  • CSS可引入Bootstrap、Foundation等出名响应式设计框架。以及SASS、LESS工具书写CSS。
  • 对于CSS、JavaScript建议合并为单文件,减少Ajax的连接数。也可以引入AMD(Require.js)加载方式。
  • 对于内部大部分企业管理系统,可以尝试采用前端 MVC框架组织代码。如Angular、React + flux架构、Knockout等。
  • 对于兼容性可用Modernizr规范库辅助。

使用jsHint

  • 前端项目中推荐引入jshint插件来规范项目编码规范。以及一套完善的IDE配置。
  • 注意:jshint需要引入nodejs 工具grunt或gulp插件,建议企业级nodejs npm私服。

前端工具

  • 前端第三方JavaScript包管理工具bower(bower install jQuery),bower可以实现第三方库的依赖解析、下载、升级管理等。建议建立企业级bower私服。
  • 前端构建工具,可以采用grunt或者gulp工具,可以实现html、css、js压缩、验证、测试,文件合并、watch和liveload等所有前端任务。建议企业级nodejs npm私服。
  • 前端开发IDE: WebStorm( Idea )、Sublime为最佳 。项目组统一IDE。IDE统一配置很重要。

转载于:https://www.cnblogs.com/luyuan/p/8512413.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/281112.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

修改onlyoffice存储为手动存储关闭浏览器时不进行保存

原文同步自作者博客&#xff1a;https://www.daxueyiwu.com/post/704 相关官方API地址&#xff1a; 文件保存 回调处理程序 配置-编辑-定制-自动保存 配置-编辑-定制-forcesave 需要将: config.editorConfig.customization.forcesave改为true, 并且config.editorConfig.…

如何使用NVIDIA ShadowPlay录制PC游戏

NVIDIA’s ShadowPlay, now known as NVIDIA Share, offers easy gameplay recording, live streaming, and even an FPS counter overlay. It can automatically record gameplay in the background–just on the PlayStation 4 and Xbox One–or only record gameplay when y…

.Net 7 的 R2R,Crossgen2是什么?

楔子来下这些概念R22,Crossgen2这两个东西&#xff0c;跟前面讲的AOT和CLR有异曲同工之妙&#xff0c;到底什么呢&#xff1f;本篇来看下。R2RR2R(ReadyToRun),是一种结合了AOT和CLR编译模式&#xff0c;取其优点&#xff0c;抛其缺点的一种编译方式。具体的呢&#xff0c;R2R包…

Java流

流分类 字节流字符流输入流InputStreamReader输出流OutputStream WriterInputStream:BufferedInputStream、DataInputStream、ObjectInputStreamOutputStream:BufferedOutputStream、DataOutputStream、ObjectOutputStream、PrintStream 标准流: System.in 、Syst…

Win7安装OnlyOffice(不使用Docker)

原文同步自作者博客&#xff1a;https://www.daxueyiwu.com/post/741 1、安装准备 &#xff08;1&#xff09;安装Elang&#xff1a; 【注意事项】 a)Elang是为了给RabbitMQ使用的&#xff0c;因此在安装Elang之前应确定RabbitMQ的版本及其所需的Elang版本。RabbitMQ的地址…

geek_享受How-To Geek用户样式脚本的好处

geekMost people may not be aware of it but there are two user style scripts that have been created just for use with the How-To Geek website. If you are curious then join us as we look at these two scripts at work. 大多数人可能不知道它&#xff0c;但是已经创…

.NET Core统一参数校验、异常处理、结果返回

我们开发接口时&#xff0c;一般都会涉及到参数校验、异常处理、封装结果返回等处理。如果每个后端开发在参数校验、异常处理等都是各写各的&#xff0c;没有统一处理的话&#xff0c;代码就不优雅&#xff0c;也不容易维护。所以&#xff0c;我们需要统一校验参数&#xff0c;…

Memcached 在linux上安装笔记

第一种yum 方式安装 Memcached 支持许多平台&#xff1a;Linux、FreeBSD、Solaris、Mac OS&#xff0c;也可以安装在Windows上。 第一步 Linux系统安装memcached&#xff0c;首先要先安装libevent库 Ubuntu/Debian sudo apt-get install libevent libevent-deve 自动下…

onlyoffice回调函数controller方式实现

原文同步自作者博客&#xff1a;https://www.daxueyiwu.com/post/706 springboot实现的onlyoffice协同编辑网盘项目可以去作者博客。 上代码&#xff1a; //新建报告GetMapping("report/createReport")public String CreatReport(HttpServletRequest request,Stri…

读Bilgin Ibryam 新作 《Dapr 是一种10倍数 平台》

Bilgin Ibryam 最近加入了开发者软件初创公司Diagrid Inc&#xff0c;他是Apache Software Foundation 的 committer 和成员。他也是一个开源的布道师&#xff0c;并且是书籍 Kubernetes设计模式 和 Camel Design Patterns 的作者。早在2020年初 提出的Multi-Runtime Microserv…

如何在iPhone或iPad上使用Safari下载文件

Khamosh PathakKhamosh PathakIn your work or personal life, you’ll sometimes need to download a file on your iPhone or iPad. Using the new feature introduced in iOS 13 and iPadOS 13, you can now do this directly in Safari. No third-party app needed! 在工作…

java版左右手桌面盯盘软件dstock V1.0

V1.0功能比较简陋&#xff0c;先满足自己桌面盯盘需要 V1.0 版本功能介绍&#xff1a; 1. 1s实时刷新盯盘数据 主要市面上的&#xff0c;符合我要求的桌面应用要VIP,穷啊&#xff0c;还是月月付&#xff0c;年年付&#xff0c;还是自己搞吧&#xff01; 2. 配置文件配置股票…

放大倍数超5万倍的Memcached DDoS反射攻击,怎么破?

欢迎大家前往腾讯云社区&#xff0c;获取更多腾讯海量技术实践干货哦~ 作者&#xff1a;腾讯游戏云 背景&#xff1a;Memcached攻击创造DDoS攻击流量纪录 近日&#xff0c;利用Memcached服务器实施反射DDoS攻击的事件呈大幅上升趋势。DDoS攻击流量首次过T&#xff0c;引发业界热…

C# WPF TabControl控件用法详解

概述TabControl我之前有讲过一节&#xff0c;内容详见&#xff1a;C# WPF TabControl用法指南(精品)&#xff0c;上节主要讲解了tabcontrol控件的左右翻页&#xff0c;以及页面筛选&#xff0c;以及数据绑定等内容&#xff0c;这节内容继续接续上节内容进行扩展讲解&#xff0c…

pixel 解锁_如何在Google Pixel 4和Pixel 4 XL上禁用面部解锁

pixel 解锁Justin Duino贾斯汀杜伊诺(Justin Duino)Face Unlock is one of the Google Pixel 4 and Pixel 4 XL’s flagship features. But if the facial recognition is a form of biometric security you’re uncomfortable with, you can delete your face data right off …

【实战】将多个不规则多级表头的工作表合并为一个规范的一维表数据结果表...

最近在项目里&#xff0c;有个临时的小需求&#xff0c;需要将一些行列交叉结构的表格进行汇总合并&#xff0c;转换成规范的一维表数据结构进行后续的分析使用。从一开始想到的使用VBA拼接字符串方式&#xff0c;完成PowerQuery的M语言查询字符串&#xff0c;然后转换成使用插…

#if defined(__cplusplus)

由于C编译器需要支持函数的重载&#xff0c;会改变函数的名称&#xff0c;因此dll的导出函数通常是标准C定义的。这就使得C和C的互相调用变得很常见。但是有时可能又会直接用C来调用&#xff0c;不想重新写代码&#xff0c;让标准C编写的dll函数定义在C和C编译器下都能编译通过…

happiness[国家集训队2011(吴确)]

【试题来源】 2011中国国家集训队命题答辩【问题描述】 高一一班的座位表是个n*m的矩阵&#xff0c;经过一个学期的相处&#xff0c;每个同学和前后左右相邻的同学互相成为了好朋友。这学期要分文理科了&#xff0c;每个同学对于选择文科与理科有着自己的喜悦值&#xff0c;而一…

sketch怎么移动图层_什么是Photoshop Express,Fix,Mix和Sketch移动应用程序?

sketch怎么移动图层Adobe’s approach to mobile apps seems to be “The More, The Better”. Right now, there are five Photoshop branded apps available for iOS and Android. Adobe的移动应用程序方法似乎是“越多越好”。 目前&#xff0c;有五个适用于iOS和Android的P…

imessage_如何在iPhone和iPad上的iMessage组中提及某人

imessageKhamosh PathakKhamosh PathakSometimes, it’s difficult to get someone’s attention in a large iMessage group chat on your iPhone or iPad. However, if you mention that person specifically in a message, your friend will receive a notification about i…