yujianAI/segmentfault_upvote5_clean huggingface dataset:
问题：关于npm的小问题
自从看了es6的模块引入之后，对npm一直有个小问题。 
比如在`npm install vue --save`之后，为什么在页面内引入vue只需要`var Vue = require('vue');` 而不是`var Vue = require('./node_modules/vue/vue');`

回答：Node引入模块一般需要经历3个步骤：`路径分析`、`扩展名分析`、`编译执行`。
Node查找模块的先后顺序：`缓存模块 > 核心模块 > 路径形式文件模块 > 自定义文件模块`。
`缓存模块`：Node引入过的模块都会被缓存下来。无论是核心模块还是文件模块，require对相同模块的第二次加载一律采用缓存优先的方式，其中`核心模块`的缓存检查优先于`文件模块`的缓存检查。
`核心模块：`Node提供的模块，已经是编译后二进制文件。
`路径形式文件模块:`以.、..和./开头的模块。
`自定义文件模块:`第三方npm包，查找此类模块最耗时且最慢，查找先后顺序：`当前目录下node_modules目录`、`父目录下node_modules目录`、`向上逐级递归直到根目录下下node_modules目录`，因为node_modules文件目录一般都比较深入，所以最耗时最慢。
希望对您有所帮助！
参考资料：`深入浅出NodeJS`

标签: node.js
问题：js 数组合并问题
业务描述，在日历上显示一个月跑步的日期
日历这快完全是用前端js实现的，所以只需要后台给一个跑步日期的数组插进日历的数组里就行了，我的思路是做两层循环，但是这样计算量很大，有没有更好的方法？
后台返回一个月中跑步的日期
```
[1,4,6,8,21]
```
前端某月 日历数组
```
[{day:1},{day:2}......{day:31}]

```
希望合并的最后的结果是
```
[{day:1,isrun:false},{day:2,isrun:false}...{day:4,isrun:true}...{day:6,isrun:true}....{day:31,isrun:false}]
```

回答： 首先，反对推荐答案，indexOf只是语法糖，内部还是循环 
如果这样做，我想了很久，没有想到什么好办法，
但是上面的答案也绝对不对，你想下map、indexOf、include这些方法内部原理是不是还是循环？
只是被封装的很好，使你的代码看起来很优雅。
那么，我们换个思路
```
let days = [2, 4, 5, 7];
let run = [{ day: 1 }, { day: 2 }......{ day: 31 }];
for(let i=0;i<days.length;i++){
  run[days[i]-1].isrun=true;
}
```
run数组里的下标是可以利用起来的，实际天数-1就是下标
写之前没注意看 我赞同 @yszou 的答案，只有这样才能实现单层循环，其他的全是语法糖包装，实质运算量并没有减少

标签: javascript, 前端, react.js, 小程序, node.js
问题：大多数语言的switch语句，不在case后默认break是出于什么考虑？
为什么会选择让编程者手动写break？是出于什么考虑么？

回答：case是从汇编时代留下来的典型“模式”，汇编时代有大量的cmp（比较）然后jmp（跳转），是一种非常常用的写法。C模仿了汇编的cmp+jmp模式设计出了switch-case模式，就这样switch-case就延续下来了，接下来各种模仿语言也就跟着用了。

标签: c++, javascript, switch语句
问题：vue-router使用next()跳转到指定路径时会无限循环
我在路由为 /path 的页面这样写
```
 beforeRouteLeave (to, from, next) {
        console.log('离开路路由')
       if(to.fullPath==='/home'){
         next();
       }else{
         next('/home')
       }
```
这个是组件路由，我想实现的效果是在这个页面点击浏览器的返回按钮后要返回 /home页面而不是上一个页面，上面的代码是没问题的，而我之前的写法就一直死循环
```
// 下面的写法会死循环
     beforeRouteLeave (to, from, next) {
        console.log('离开路路由')
       next('/home')
}
```
问题：
```
 1.我不太明白为什么会死循环，我在home页面也没有写任何钩子函数来跳到result页面啊，我也没有写全局的beforeEach钩子函数。
 2.上面第一段代码是可用的，自己瞎摸索出来的，但是不是很明白为什么要加那个判断？
```

回答：自问自答下吧，通过别人指点，算是大致理解了，当执行钩子函数时如果遇到next('/home')等时会中断当前导航，比如当前导航是去/a,那么遇到next('/home')后就会把to.path改为/home，然后会重新触发这个离开的钩子，注意：此时会重新触发执行这个钩子，而不是在这个钩子函数继续执行的，之前是一直没理解这里，以为是执行next('/home')后就会直接跳到home页面呢，当重新触发后就会继续执行next('/home')所以会一直循环。至于解决办法就是判断下，如果已经是/home了就next()。

标签: javascript
问题：请问dva中 connect()()的用法。
这段代码是dva的基础代码
```
import React from 'react';
import { connect } from 'dva';

function IndexPage() {
  return (
    <div> this is a div </div>
  );
}

export default connect()(IndexPage);
```
【请问】最后一行这个 connect()(IndexPage) 怎么理解？ 
还要请教：这两个括号的在一起的写法是es6语吗？（我在阮一峰的es6指南中没找到这个语法说明，我要看箭头函数一章，还是到哪章去了解这个`()()`）
老司机能提供一个纯js的双括号函数案例吗？
p.s.
我思考了一下：之前见过 `function(){}()` 这样的最后放一个括号表示立即执行。请问和上边的这个有相通的地方吗？
谢谢您前来科普帮助，感谢老司机指路----O(∩_∩)O
```
//▼补充代码，
import React from 'react';
import { connect } from 'dva';
import { Table, Pagination, Popconfirm, Button } from 'antd';
import { routerRedux } from 'dva/router';

function stuIndexPage({ dispatch, list: dataSource, loading, total, page: current }) {
  return (
    <div> index 首页 </div>
  );
}

function mapStateToProps({ stuIndexPage }){
    return {
          stuIndexPage
    };
}
//▼还有这个，两个括号都传参了，搞不太懂是什么作用
export default  connect(mapStateToProps)(stuIndexPage);
```

回答：`connect` 函数的返回值还是一个函数 这样说你懂了没
```
connect()(IndexPage)
// =>
const bindToComponent = connect()
export default bindToComponent(IndexPage)
```
`export default connect(从 model 的 state 中获取数据)(要将数据绑定到哪个组件)`

标签: react.js, dva.js, ecmascript-6
问题： 怎么判断 iphoneX 手机？
要兼容 iosX，需判断手机类型，怎么判断？
ios真的会搞事情！

回答：看到一篇关于 解决iPhoneX适配的文章： https://mp.weixin.qq.com/s?__...
亲测这个其实是针对 ios11系统有效。
1.设置网页在可视窗口的布局方式。
  首先 meta里 添加 `viewport-fit=cover`
```
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no, viewport-fit=cover" />

```
2.页面主体内容限定在安全区域内。
  可以配合 @supports 这样编写样式：
```
@supports (bottom: constant(safe-area-inset-bottom)) {
  div {
    margin-bottom: constant(safe-area-inset-bottom);
  }
}

```
更好的解决方式可以采用媒体查询 ，再加上面的代码 。
```
@media (device-width: 375px) and (device-height: 812px) and (-webkit-min-device-pixel-ratio : 3){
    //如果以后出现375*812,非ios机型，可以加上下面语句
    @supports (bottom: constant(safe-area-inset-bottom)) {
        
    }
}
```

标签: javascript, html5
问题：js字符串拼接
后台让我给他们传图片的时候给图片排序
我现在取到的图片地址是 
`19998321312.jpg`
后台需要的格式是 
`19998321312_01.jpg`
`19998321312_02.jpg`
`19998321312_03.jpg`
...
`19998321312_10.jpg`
`19998321312_11.jpg`
个位数在前边加 0
请问我需要怎么拼接

回答：```
  var arr = [{url: '19998321312.jpg'}];
  var result = arr.map((item,index) => {
      var strIndex = index + 1;
      if((strIndex).toString().length===1){
        strIndex = '0' + strIndex;
      }
      var urlIndex = item.url.lastIndexOf('.');
      var beforeUrl = item.url.slice(0, urlIndex);
      var afterUrl = item.url.slice(urlIndex)
      item.url = beforeUrl + '_' + strIndex + afterUrl;
      return item;
  });
  console.log(result); // [{url: "19998321312_01.jpg"}]
  // 多个改下数组arr即可。
```

标签: javascript
问题：vue中keep-alive中缓存的组件可以主动销毁吗？
在项目中使用会缓存个别路由组件，代码如下：
```
      `<transition name="fade" mode="out-in">
        <keep-alive>
            <router-view v-if="$route.meta.keepAlive"></router-view>
        </keep-alive>
    </transition>
    <transition name="fade" mode="out-in">
        <router-view v-if="!$route.meta.keepAlive"></router-view>
    </transition>`
    
    这儿有一个问题就是：如果我想主动把keep-alive中的个别组件手动销毁，还没有什么方法和头绪。
```

回答：在vue@2.5.0 中 `keep-alive` 新增了一个 `max` 属性可以设置 cache instance 的个数
add max prop for <keep-alive> for limiting max number of instances cached
相关issue
所以个人认为没有太大必要手动来维护 `keep-alive`的组件，当然你想的话可以使用`include` 和 `exclude` 来实现

标签: javascript, vue.js
问题：如何更改<input type="file" />上传文件的名字？
在选择文件后上传文件前，或者是点击提交的时候，如何更改上传文件的名字？
```
<form id="upload_form" method="post" enctype="multipart/form-data">
    <input type="file" name="upload_file">
    <input type="submit">
</form>
```
直接改变`file.name`是无效的；
```
var fileExtension = '.' + file.name.split('.').pop();
file.name = Math.random().toString(36).substring(7) + fileExtension;
console.log(file);
```
应该如何更改呢？

回答：使用FormData进行提交，修改文件名用以下方法：
```
formData.append(name, value, filename);
```
参考地址：https://developer.mozilla.org...
注意：如果是移动端，iphone请注意旋转图片角度。
希望对您有所帮助！

标签: html5, javascript
问题：这样是不是就叫
前后端分离开发了？
以前曾经写过一个后台是用java写的有前后台页面的网站。
被朋友吐槽说我那个网站不是用的前后端分离，很low。说没有用请求api接口，而且用了jsp來改写html，说前后端分离不需要这样套模版的。
问题：
0.现在是不是差不多所有公司都用前后端分离了？没试过这种开发模式咋办…
1.是不是前后端分离与传统的开发其实主要就是以上那些区别？
2.工作中如果后端同事写的接口文档比较难看懂不就坑了前端？
3.看到别人github有前后端分离项目，为啥运行时前后台页面都是同一个端口号如9000，不是应该前端首页localhost:3000/index  后端首页localhost:9000/index这样分开才叫前后端分离吗？  都用9000端口那和我之前写网站访问前后台的方式一样阿…
概念其实在网上了解过，但怕很多地方还是理解错，所以上来求指正

回答：0 NO 前后端分离是趋势，但是也还存在问题（例如SEO，搜索引擎难以识别等），短时间内不可能取代不分离的
1 主要区别是，数据和表现分离，只需要静态的html和动态的接口（例如jsp），数据在浏览器端实现动态加载
2 理想情况是，先出文档（前后端都认可），然后后端、前端都按照文档来，一切以接口规定的为准
3 跟端口没一毛钱关系，重点在于接口！靠 API 来分离前后端，解决前后端大团队、多版本、复杂功能协作的问题
补充：
可以参考淘宝前端的设计，在 java 接口和 html 输出之前用 NodeJS 代理一层，暂时能解决 SEO 的问题
定义好了接口，前端就可以用不用等后端，直接用模拟的数据格式，方便地进行前端测试了
说重点，API 相比前后端混写、模板引擎之类的东西的好处：
方便设计、开发、测试（前端不再需要依赖后端，后端也不需要依赖前端，就可以各干各的，独立测试代码）
方便记录和统计功能使用（后端相同功能的入口位置统一，不同功能的位置也可以合理有序地组织）
方便修改和版本控制等（后端可以提供多版本的 API，不需要修改已有代码，不影响已有 API 的功能）
最重点的是：
你的Team要是分工不明确、人少、功能简单直接、代码修改不多，就完全不需要分离，就酱。
最明显的：
前端代码不用被后端粘贴来粘贴去了，后端的相同代码，也不需要各种位置粘贴来粘贴去了。
隐藏的好处：
到时候出了问题，照着 API 设计文档一对比，就知道是前端用的不对，还是后端写的不对，分分钟找到背锅侠。
Update 2017/10/13:
其实很有一个很大的优势忘了说……
以后网站的功能，要做Windows、Mac、Android、IOS、Linux的客户端，或者需要做成批量处理的脚本，或者需要和别的什么系统对接，什么微信公众号、小程序之类的，等等等等……
有API在就能瞬间解决问题！就这个提供给前端的API！一样的！调用这个接口就行了！

标签: 前后端分离, 前端, 后端
问题：int占4字节，一数占一字符，为什么int能表示5位以上的数字?
我知道这个问题~有点无厘头和傻乎乎。还是想请人解答一下~
----------可能目前脑子正处于抽风阶段----------
首先，我知道int占4个字节，包含正负2的31次方内的数字，也就是基本可以表示10位数字。
那么根据Ascll里，一个数字占用一个字节的规则来思考。
我让int按照这种规则来储存数字，是不是应该只能储存最多4位数字？？？
还请明白人~指出我这样思考的错误点在哪里？或者告知正确的解答方式~。

回答：字符和数值的表示方法是不同的，ascii码里面的数字不是数值，是用编码表示的字符，因此每个数字字符占7位(扩充的ascii码占8位)。比如12，，用ascii码表示为0110001 0110010(它表示的是一二两个数字字符组成的字符串，并没有十二的大小的涵义)，，而用int则表示为00000000 00000000 00000000  00001010，它表示数值为十二的整数，一二两个数是不可分割的。。总之数值与字符在计算机内表示的方法是不同的，，int不是用ascii码表示的

标签: java, 二进制, 数据类型, 内存
问题：用jsx写vue组件，怎样监听.sync修饰符的事件？
用 `jsx` 来写 vue 的组件，需要监听 `.sync` 修饰符的事件，找不到文档，我试过下面的方法，但是并不行。
```
<MyComponent visible={this.visible} {...{['on-update:visible']: console.log}} />
```
求问，正确的写法应该要怎样呢？

回答：在 babel-plugin-transform-vue-jsx 的 example 中找到了答案，可以这样写：
```
<MyComponent visible={this.visible} {...{on:{'update:visible': console.log}}} />
```

标签: vue.js, jsx, javascript
问题：vue-cli 根据不同的环境打包
项目开发中有三个环境，分别是测试环境，预生产环境，生产环境
如题，根据项目需要，目前需要打包，通过vue-cli中的npm run build 打包，这个只能打包到一个环境，但是，项目中有三个环境，每个环境的接口地址都不同，根据process.env分别进行接口的调用，但是如何处理打包呢？
目前的解决方案是复制了几个，build下面的build.js ,感觉这样并不是最优的解决方案，
不知是否有更完美的解决方案？
 感激不尽！

回答：解决此类问题还得靠自己，大神一般都不给力
vue-cli 中build中build.js部分代码做如下修改
```
require('./check-versions')()

// process.env.NODE_ENV = 'production'

var ora = require('ora')
var rm = require('rimraf')
var path = require('path')
var chalk = require('chalk')
var webpack = require('webpack')
var config = require('../config')
var webpackConfig = require('./webpack.prod.conf')

var spinner = ora('building for ' + process.env.NODE_ENV + ' of ' + process.env.env_config+ ' mode...' )
spinner.start()
// var spinner = ora('building for production...')
// spinner.start()
。。。。
```
build中webpack.prod.conf.js做如下修改
```
const env = config.build[process.env.env_config+'Env']
// var env = process.env.NODE_ENV === 'testing' ?
//     require('../config/test.env') :
//     config.build.env
。。。。
```
config中的index.js 部分代码修改如下
```
module.exports = {
    build: {
        prodEnv: require('./prod.env'),
        sitEnv: require('./sit.env'),
        ppeEnv: require('./ppe.env'),
        index: path.resolve(__dirname, '../dist/' + new_dateTime + '/index.html'),
        。。。。。
```
config中 dev.env.js 修改
开发环境用的是测试接口，通过merge进行拷贝
```
var merge = require('webpack-merge')
var sitEnv = require('./sit.env')

module.exports = merge(sitEnv, {
  NODE_ENV: '"development"'
})
```
在config中新建sit.env.js
```
//测试
module.exports = {
  NODE_ENV: '"sitEnvironment"',
  ENV_CONFIG: '"sit"',
  hosturl: '"https://sitxxx"',
。。。
}
```
在config中新建ppe.env.js
```
//预生产
module.exports = {
  NODE_ENV: '"ppeEnvironment"',
  ENV_CONFIG: '"ppe"',
hosturl: '"https://ppexxx"'
。。。
}
```
生产环境是prod.env.js vue-cli 自带
安装cross-env
package.json 修改
```
  "scripts": {
    "dev": "node build/dev-server.js",
    "build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
    "build:ppe": "cross-env NODE_ENV=ppeEnvironment env_config=ppe node build/build.js",
    "build:sit": "cross-env NODE_ENV=sitEnvironment env_config=sit node build/build.js",
    "e2e": "node test/e2e/runner.js",
    "test": "npm run e2e"
  },
```
end

标签: vue-cli, vue.js
问题：element-ui的tree树形组件怎么控制全部展开和全部折叠啊？
element-ui的tree树形组件怎么控制全部展开和全部折叠啊？有一个default-expand-all    是否默认展开所有节点的属性，只在第一次初始化tree的时候有效，改变这个属性的值好像不能控制展开折叠，请问有什么方法吗

回答：```
for(var i=0;i<this.$refs.treeX.store._getAllNodes().length;i++){
           this.$refs.treeX.store._getAllNodes()[i].expanded=this.isexpand;
        }



```
this.$refs.treeX是树对象，通过树对象获取所有的树节点，遍历树节点设置expand属性为true则全部展开，设置为false则全部收起

标签: element-ui, vue.js
问题：如何理解three.js中的buffergeometry？
如何理解three.js中的buffergeometry？
buffergeometry与Geometry 相比优势与劣势是什么？
最适用于什么样的场景？

回答：BufferGeometry 会缓存网格模型，性能要高效点。网格模型生成原理
1、Geometry 生成的模型是这样的  （代码）-> (CUP 进行数据处理，转化成虚拟3D数据) -> (GPU 进行数据组装，转化成像素点，准备渲染) -> 显示器
第二次操作时重复走这些流程。
2、BufferGeometry 生成模型流程   (代码) -> (CUP 进行数据处理，转化成虚拟3D数据) -> (GPU 进行数据组装，转化成像素点，准备渲染) -> (丢入缓存区) -> 显示器
第二次修改时，通过API直接修改缓存区数据，流程就变成了这样
(代码) -> (CUP 进行数据处理，转化成虚拟3D数据) -> (修改缓存区数据) -> 显示器
节约了GPU性能的运算性能

标签: three.js, webgl
问题：js闭包this对象
```
var name = "The Window";
var getNameFunc= {
    name: "My Object",
    getNameFunc: function() {
        return function() {
            return this.name;
        };
    }
};
alert(object.getNameFunc()()); //"The Window"（在非严格模式下）

```
在高级程序设计的第7章，7.2.2关于this对象中，有几句话实在是不太明白：
以上代码先创建了一个全局变量 name，又创建了一个包含 name 属性的对象。这个对象还包含一个方法——getNameFunc()，它返回一个匿名函数，而匿名函数又返回 this.name。由于 getNameFunc()返回一个函数，因此调用 object.getNameFunc()()就会立即调用它返回的函数，结果就是返回一个字符串。然而，这个例子返回的字符串是"The Window"，即全局 name 变量的值。为什么匿名函数没有取得其包含作用域（或外部作用域）的 this 对象呢？
前面曾经提到过，每个函数在被调用时都会自动取得两个特殊变量： this 和 arguments。内部函数在搜索这两个变量时，只会搜索到其活动对象为止，因此永远不可能直接访问外部函数中的这两个变量。
1.只会搜索到其活动对象？？？ 不是有个作用域链吗？匿名活动对象在最下面，在匿名对象中找不到，那就去上面的活动对象去找咯？getNameFunc中找不到就去object去找咯。。。不就找到了吗
2.因此永远不可能直接访问外部函数中的这两个变量？？？是什么意思？外部函数是指哪个？

回答：你可以通过修改尝试对 `this` 加深一下理解 .
1) 将匿名函数独立出来给个名字.
稍微调整如下:
```
var name = "The Window";
function getThisName(){
    return this.name
}
var object = {
    name: "My Object",
    getNameFunc: function() {
        return getThisName
    }
};
var getThisNameFunc = object.getNameFunc()
console.log(getThisNameFunc()); 
```
现在你再来看这个 `getThisName` 这个原来你代码里面的匿名函数,你是不是可以很清楚的看出它的调用方是认谁了? 很显示到最后调用这个方法时是隐式的全局变量 (window, 在浏览器环境)
它跟上面声明的 `object` 没有任何关系. 只是 `object.getNameFunc` 这个函数将这个函数作为返回值.
如果是返回的其他标量,自然也不会发生关系.
另外你上面的书也提到了, `this` 和 `arguments`这两个隐式的变量是在函数调用的时候才获得的.
所以在这个函数被调用的时候明显它的`this` 只能是全局的 `this`.
2) 将 object 直接跟 `getThisName` 建立关系:
```
var name = "The Window";
function getThisName(){
    return this.name
}
var object = {
    name: "My Object",
    getNameFunc:getThisName 
};
console.log(object.getNameFunc()); // 输出: My Object
var getThisNameFunc = object.getNameFunc; 
console.log(getThisNameFunc()); // 输出: The Window
```
观察上面的输出,你再加深以下对这句话的理解:
每个函数在被调用时都会自动取得两个特殊变量
3) 加深对函数调用的理解, 加上 `apply` 和 `call`
你看一下如下代码的输出:
```
var name = "The Window";
function getThisName(){
    return this.name
}
var object = {
    name: "My Object",
    getNameFunc:getThisName 
};
console.log(object.getNameFunc()); 
var getThisNameFunc = object.getNameFunc
console.log(getThisNameFunc()); 
console.log(getThisNameFunc.apply(object)); 
console.log(getThisNameFunc.call(object)); 
```
每个函数在被调用时都会自动取得两个特殊变量
同时你也可以通过使用 `apply`, `call` 等内置函数原型的方法来指定函数调用时所使用的 this 对象. 如上所示.
JavaScript 的这一特点, 跟 Java 等静态语言是很不同的. Java 等静态语言,往往由于你方法(注意这里没有说函数)写的地方就决定了 `this` 对象的指向,但是 JavaScript 是动态语言这一点很不一样. 所以还需要在后面的实践中多多注意总结和理解.

标签: javascript
问题：谁能用自己的话解释init和initWithFrame调用的先后顺序原因
这是一个自定义view：
```
@implementation MyView

- (instancetype)init {
    if (self = [super init]) {
        NSLog(@"调用了init");
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        NSLog(@"调用了initWithFrame");
    }
    return self;
}


@end

```
现在我调用它的init方法：
```
MyView *myView = [[MyView alloc] init];
```
控制台打印信息是：
2017-10-09 11:14:35.224 block[2391:262544] 调用了initWithFrame
2017-10-09 11:14:35.225 block[2391:262544] 调用了init
问：
为什么先打印的是initWithFrame而不是init?

回答：```
MyView *myView = [[MyView alloc] init];
```
代码调用过程如下：

1. 动态查找到  MyView 的 init 方法
2. 调用 super init 方法
3. super init 方法内部执行的是 [super initWithFrame:CGRectZero]
4. 然后 super 会发现 MyView 实现了 initWithFrame 方法
5. 转而执行 [MyView initWithFrame:CGRectZero]
6. 最后再执行 init 其余部分

关键点：OC 里面的 super 实际上是让某个类自己去调用父类的方法, 而不是父类去调用某方法。方法动态调用过程中的顺序是按照继承关系从下到上。

标签: objective-c, ios
问题：关于php解决并发的一些疑惑
首先 并发我是这样理解的:
2 个人同时下单, 库存只有 1, 那么肯定有一个人无法抢到。也就是说, 库存只会减 1, 订单也只会生成一条。
后来我用 Jmemter 模拟 1000 人同时操作, 发现订单确实只有一个, 而且库存也没有负数, 但是我并没有做什么锁啊或者队列这些一谈到并发就会涉及到的东西。
`$a` 是查询到的库存
```
$b = $a-1;

if($b>=0){
    生成订单
    修改库存
}
```
如果没有 `if` 判断, 确实会负。但是如果加了这个 `if` 判断就库存只减少 1, 订单只有一条
那么我的问题来了, 加个 `if` 判断就能解决并发? 还是说实际上真正要处理的是模拟测试后出现的错误率 (Jmemter, 模拟 1000 人, error:59.5%), 或者其他? 
请解答, 如果我的思路有错误, 也请毫不留情

回答：你说的订单问题，其实是：高并发场景下，如何正确扣减库存的问题
`if($b>=0)` 这样的判断，在高并发的场景下并不使用，因为这样的业务逻辑判断并不是 `原子操作`，所以存在 `脏读` 的可能。
例如：
由两个请求同时到达 `服务端`（分别名为：`p1`, `p2`），`p1` 先取到了数据，走到了 `if` 判断，
此时 `p2` 也取到了数据，但是 `p1` 还没有更新数据库，所以 `p2` 取到的数据跟 `p1` 是一样的，所以，`p1` `p2` 得到的 `$b` 值是一样的， `p2` 也可以通过 `if` 条件，但是这两个请求只扣减了一次存库。
如何解决这个问题呢？
- 加锁；
- 队列：改并行为串行，依次扣减；
- 操作转换为原子操作；

加锁；
队列：改并行为串行，依次扣减；
操作转换为原子操作；
不光是数据库操作，高并发场景下，还可能会面对什么问题呢：
- 单点问题（当然 非刚并发场景也会面临这个问题，但是高并发场景，此问题尤为突出）
- 最大连接数问题，eg. `web 服务器` `数据库` ...
- 数据安全问题，eg. `脏读` `重复操作`

单点问题（当然 非刚并发场景也会面临这个问题，但是高并发场景，此问题尤为突出）
最大连接数问题，eg. `web 服务器` `数据库` ...
数据安全问题，eg. `脏读` `重复操作`

标签: 并发, php
问题：如何使用localStorage结合Vuex来保存用户登录信息？
我现在有一个 `headerBar` 组件，上面显示了用户名称（如果设置了昵称显示昵称，否则显示用户名称），当用户点击登录按钮时，调用`api`获取用户信息，保存到`Vuex`的`state`里面，`headerBar`通过`this.$store.getters.xxx`来获取用户登录信息，但是当用户刷新时，state里面的用户信息全没了，所以我考虑加入 `localStorage` 来保存用户信息，但是这部分代码不知道该如何“分布”，因为要考虑`用户登录超时`，请小伙伴们指点指点，谢谢！
代码如下：
```
export default new Vuex.Store({
    state: {
        loginInfo: null,//当前用户简要信息
    },
    getters: {
        GET_LOGININFO(state) {
            //先从state里面获取用户登录信息
            let loginInfo = state.loginInfo;
            //如果 state 里面获取不到，那么从localStorage里面获取
            if(!loginInfo){
                loginInfo = JSON.parse(window.localStorage.getItem('loginInfo') || null)
            }
            return loginInfo;
        },
    },
    mutations: {
        SET_LOGININFO(state, data){
            state.userInfo = data.data;
        }
    },
    actions: {
        Login(context, data) {
            axios.post('/api/login', {
                userName: 'admin',
                pwd: '123456'
            })
            .then((res) => {
                //登录成功，保存当前用户信息到 state 里面，以便其他组建获取
                context.commit('SET_LOGININFO', res.data);
                //保存到localStorage里面
                window.localStorage.setItem('loginInfo', JSON.stringify(items));
                return res;                
            })
            .catch(function (error) {});
        },
    }
})
```
想请教几个问题：
1、这么使用 `localStorage` 正确么？或者合理么？有没有更好的方法呢？
2、在`getters`下面的`GET_LOGININFO`方法里面，如果进入了`if(!loginInfo)`语句，该方法是否可以为 `state `属性`loginInfo`赋值呢（或者调用`mutations`方法来给`loginInfo`赋值）？
3、这样的话，如果用户点击`退出`按钮，是不是意味着需要清空state的loginInfo，还需要清除localStorage下面的loginInfo呢？
4、这样的话，从客户端角度来看，是不是客户就永远保持以登录状态了？这个环节该怎么做好呢？
补充：第二个问题其实就是：getters里面的方法是否可以为state属性赋值（直接访问state属性赋值 或者 调用mutations方法赋值）？

回答：1. **不合理**。用户登录成功以后应该在本地保存一份用户数据，注意我说的是保存到本地不是保存到`localstorage`，因为保存本地的方法有很多种，比如`cookie`、`indexedDB`等，所以，代码中不应该直接调用`window.localStorage`，而是应该封装一个用户数据的读取类，解除代码耦合，将来要改成其他存储方式比较简单：
```
`const USER_INFO='USER_INFO'
function getUserinfo(){}
function setUserinfo(){}`
```
2. **不应该**。个人认为不应该，`getters`语义上就是获取数据，但是却改变了数据，导致不纯净，可能会埋下维护上的隐患。
3. **是的**。理论上应该有一个接口用来更新用户状态，比如判断用户是否需要重新登录之类的，比如`api/refresh`， 所以逻辑应该是：
  - 用户进入app，判断本地是否有用户信息。


    - 有，调用`api/refresh`，判断是否需要重新登录。
      - 不需要（连续登录），将信息保存在`vuex`中，并进入首页，往后数据读取全部走`vuex`。
      - 需要（长时间未登录），删除本地用户信息并跳转到登录流程。
    - 没有， 跳转到登录流程（以下是登录流程）。
      - 调用`api/login`登录。
      - 将保存到本地，并保存到`vuex`中，往后数据读取全部走`vuex`。

4. **看3**，具体还可以看看`jwt`，或者基于`token`的`api`设计相关的文章。

标签: localstorage, vuex, vue.js
问题：js怎样确定两个异步函数的执行顺序
```
const asyncFunction = function() {
  return new Promise(function(resolve, reject) {
    resolve('promise');
  });
};

asyncFunction().then(value => console.log(value));

setTimeout(() => { console.log('settimeout') }, 0);

```
输出
```
// promise
// settimeout
```
请问两个都是异步的函数，为什么`setTimeout`函数后执行？

回答：Promise 是microtask 队列
而setTimeout属于 macrotask 队列
在一个Tasks执行之后会立刻执行microtask队列，而后执行macrotask队列
macrotask永远在 microtask 之后执行

标签: javascript, ecmascript-6, promise
问题：vue 权限控制
项目使用了vue + vue-router作为前端框架, 现在需要做权限控制,
请问怎么设计前端的权限
补充: 抱歉可能我表达不清, 意思是前端对某个角色的权限进行控制, 比如有些页面不显示, 有些按钮不能点击

回答：最近搭建了公司的后台管理系统， 而且系统还比较庞大， 要实现以下几点：
1. 菜单权限，  根据不同权限显示不同的菜单
2. 操作权限，  比如有些账号没有新增权限， 有些没有修改或者删除权限
3. 数据权限，  比如统计概况， 普通管理员不能看到公司营业概况，但能看到自己所属区域的概况
4. 显示权限，  比如列表， 运营能看到那一列的签约金额，但市场不能看到签约金额这一列

到目前为止还在构建中， 已经解决菜单权限和操作权限。

菜单权限：
最开始的时候本地先配置一套路由，然后登陆成功后会从服务器返回一个菜单列表，然后在beforeEach里面把返回的菜单列表和本地配置的路由进行对比， 如果存在则有权限访问。  做了几天发现很难用， 本地得配置一整套路由，还得做几个页面来把这些路由信息写入到服务器，这样来进行权限分配， 当你的权限菜单比较多的时候， 像我们这个后台，光公司内部权限就有好几套， 还有代理商、商家权限等等， 不同的菜单可能会超过几百个， 这样配置太累了，还容易出错。
最后的解决思路是完全不在本地做任何路由配置， 登录页面单独弄，不放到vue组件里面， 登录成功后从后台抓取菜单列表， 因为现在是已经登录成功了，所以抓取的就是拥有全新的菜单。 抓取成功后在配置到路由里面，然后实例化vue , 这样就避免了本地配置一套路由了，完全是服务器上面配置路由。 
这样解决的难点只有一个，那就是路由需要对应的组件，所以我们将所有组件存放到一个对象里面， 服务器的返回的菜单列表里面，会有一个字段配置组件名，  在抓取成功后生成路由配置的时候就使用  router[menuName]就能直接加载到这个组件，非常方便。
main.js代码片段：
```
// 实例化Login类并初始化
  new Login(function (err, data) {
    if (err) {
      // 登录出错
    } else {
      // 登录成功
      init(data);
    }
  }).init();

const init = function (data) {
  // 先配置路由信息
  // componentConfigs 是本地的组件配置
  let routers = assignRouter(data.menus, componentConfigs);
  // 实例化路由
  router = new Router({routes: routers});
  // 再实例化vue
  new Vue({
    el: '#app',
    store,
    router,
    nprogress,
    ...App
  });
};
```
```
componentConfigs.js 代码片段：
```
```
export default {
  Common: {
    Admin: require('../../vue/pages/common/Admin'),
    Index: require('../../vue/pages/common/Index'),
    UpdatePassword: r => require.ensure([], () => r(require('../../vue/pages/users/UpdatePassword')), 'users')
  }
}
```
服务器返回的菜单json:
其中meta 字段里面是当前路由里的操作权限
```
[{
            "path": "\/admin\/index",
            "name": "\u9996\u9875",
            "component": "Common.Index",
            "display": true,
            "icon": "icon-home"
        }, {
            "path": "\/admin\/updatePassword",
            "name": "\u4fee\u6539\u5bc6\u7801",
            "component": "Common.UpdatePassword",
            "display": false
        }, {
            "path": "\/admin\/commodity",
            "name": "\u5546\u54c1\u7ba1\u7406",
            "component": "Content",
            "display": true,
            "icon": "icon-class",
            "children": [{
                "path": "\/admin\/commodity\/publicWarehouse",
                "name": "\u516c\u5171\u5e93\u7ba1\u7406",
                "component": "Commodity.PublicWarehouse",
                "display": true,
                "meta": {"handleAuth": {"add": true, "edit": false, "del": true}}
            }, {
                "path": "\/admin\/commodity\/businessesWarehouse",
                "name": "\u5546\u5bb6\u5e93\u7ba1\u7406",
                "component": "Commodity.BusinessesWarehouse",
                "display": true,
                "meta": {"handleAuth": {"add": true, "edit": false, "del": true}}
            }]
        }]
```
菜单的权限大概就是这样， 至于操作权限， 思路是这样的： 写一个鉴权的vue插件， 然后所有的操作独立放到methods里面;   然后所有的操作 @click里面调用鉴权函数，  $auth('add', arg1, arg2, ...argN) ;  $auth里面判断this.$route.meta 里是否有权限进行这个操作， 如果有则调用 this[authName].apply(null, arg);

标签: javascript, vue.js
问题：jquery 怎么判断一个数组的最大值并显示name
像下面的这种，怎么判断后面的数字大小并输出最大数的 a:7 这种形式。
```
var arr=[{a:7},{b:2},{c:0},{d:5},{e:1}];
```

回答：```
var arr=[{a:7},{b:2},{c:0},{d:5},{e:1}];
arr.sort(function(item1,item2){
    return item2[Object.keys(item2)[0]]-item1[Object.keys(item1)[0]]
})[0] //{a: 7}
```

标签: jquery, javascript
问题：C++ 字符串加字符
```
cout << ("s" + 'a');

```
这样一段代码，为什么输出是一个空行呢？
难道是 `string literal + character` 没有这个运算吗？
没有的话为什么输出是空行呢？
C++ 中， `string literal` 就是 `const char[n]` 吗？

回答：表达式`"s"`的类型是`const char[]`，表达式 `'a'`的类型是`char`。
数组是不能进行内置加法运算的。所以`const char []`会被转换成`const char *`，这里的运算就变成了"指针+整型"(`char`是一种整型)。输出空行的运行结果实际上是数组越界引起的。
String literal
Narrow multibyte string literal. The type of an unprefixed string literal is const char[]
Additive operators
addition. For the built-in operator, lhs and rhs must be one of the following: Both have arithmetic or unscoped enumeration type. In this case, the usual arithmetic conversions are performed on both operands and determine the type of the result. One is a pointer to complete object type, the other has integral or unscoped enumeration type. In this case, the result type has the type of the pointer
Array-to-pointer decay
There is an implicit conversion from lvalues and rvalues of array type to rvalues of pointer type: it constructs a pointer to the first element of an array. This conversion is used whenever arrays appear in context where arrays are not expected, but pointers are.

标签: c++, c
问题：process.nextTick()与promise.then()
```
process.nextTick(function(){
    console.log(7);
});

new Promise(function(resolve){
    console.log(3);
    resolve();
    console.log(4);
}).then(function(){
    console.log(5);
});

process.nextTick(function(){
    console.log(8);
});
```
这段代码运行结果是3，4，7，8，5
process.nextTick和Promise都是Microtasks，为什么process.nextTick会先执行？

回答：process.nextTick 永远大于 promise.then，原因其实很简单。在Node中，_tickCallback在每一次执行完TaskQueue中的一个任务后被调用，而这个_tickCallback中实质上干了两件事：
1.nextTickQueue中所有任务执行掉(长度最大1e4，Node版本v6.9.1)
2.第一步执行完后执行_runMicrotasks函数，执行microtask中的部分(promise.then注册的回调)
所以很明显 process.nextTick > promise.then

标签: javascript, node.js
问题：为什么js里面  0.1+0.2=0.30000000000000004？
```
var a =0.1;
var b =0.2;
log(a+b)//0.30000000000000004
```
这是什么原因

回答：本质是因为浮点数的问题。
其实不用想的太复杂，你把0.1换算成二进制的形式就知道，它的二进制表示是一个无限循环的数。也就说实际上保存到内存里的0.1是一个近似值。
然后一个近似于0.1的二进制数再转回10进制，就会出现这种问题。

标签: javascript
问题：JavaScript中typeof原理探究？
我们都知道 `typeof(null) === 'object'`，关于原因，在小黄书《你不知道的JavaScript》中有这么一段解释：
原理是这样的， 不同的对象在底层都表示为二进制， 在 JavaScript 中二进制前三位都为 0 的话会被判断为 object 类型， null 的二进制表示是全 0， 自然前三位也是 0， 所以执行 typeof 时会返回“object”。
我就想问下，不同的对象对应的二进制数是多少位的，具体值又是多少？比如String类型的二进制表示是多少？

回答：并不完全正确。
我在知乎 有哪些明明是 bug，却被说成是 feature 的例子？ 有介绍过。
javascript 中的 `null`：既是对象，又不是对象，史称「薛定谔的对象」。
```
typeof null === 'object';
null instanceof Object === false
```
而
```
null instanceof null
```
会抛出异常：
```
Uncaught TypeError: Right-hand side of 'instanceof' is not an object
```
这是一个历史遗留下来的 feature(or bug?)，The history of “typeof null”
在 javascript 的最初版本中，使用的 32 位系统，为了性能考虑使用低位存储了变量的类型信息：
- 000：对象
- 1：整数
- 010：浮点数
- 100：字符串
- 110：布尔

有 2 个值比较特殊：
- undefined：用 - （−2^30）表示。
- null：对应机器码的 NULL 指针，一般是全零。

在第一版的 javascript 实现中，判断类型的代码是这么写的：
```
if (JSVAL_IS_VOID(v)) {  // (1)
    type = JSTYPE_VOID;
} else if (JSVAL_IS_OBJECT(v)) {  // (2)
    obj = JSVAL_TO_OBJECT(v);
    if (obj &&
        (ops = obj->map->ops,
            ops == &js_ObjectOps
            ? (clasp = OBJ_GET_CLASS(cx, obj),
            clasp->call || clasp == &js_FunctionClass) // (3,4)
            : ops->call != 0)) {  // (3)
        type = JSTYPE_FUNCTION;
    } else {
        type = JSTYPE_OBJECT;
    }
} else if (JSVAL_IS_NUMBER(v)) {
    type = JSTYPE_NUMBER;
} else if (JSVAL_IS_STRING(v)) {
    type = JSTYPE_STRING;
} else if (JSVAL_IS_BOOLEAN(v)) {
    type = JSTYPE_BOOLEAN;
}
```
（1）：判断是否为 undefined
（2）：如果不是 undefined，判断是否为对象
（3）：如果不是对象，判断是否为数字
（4）：。。。
这样一来，`null` 就出了一个 bug。根据 type tags 信息，低位是 `000`，因此 `null` 被判断成了一个对象。这就是为什么 `typeof null` 的返回值是 `object`。
关于 `null` 的类型在 MDN 文档中也有简单的描述：typeof - javascript | MDN
在 ES6 中曾有关于修复此 bug 的提议，提议中称应该让 `typeof null === 'null'` http://wiki.ecmascript.org/do...:typeof_null 但是该提议被无情的否决了，自此 `typeof null` 终于不再是一个 bug，而是一个 feature，并且永远不会被修复。
这是 JavaScript 最初实现的一个 bug，目前的 JavaScript 引擎已经不这么去实现了，但是这个 bug 却一直流传了下来。
至于对象的内部表示，不同的 JavaScript 引擎实现起来都是不一样的，单说说 V8 吧。
v8引擎是如何知道js数据类型的？ （原文太长我就不贴过来了）

标签: javascript
问题：怎么提高组织语言能力和表达能力？求指导下，主要在项目文档的撰写和开会对项目口语表达
怎么提高组织语言能力和表达能力？求指导下，主要在项目文档的撰写和开会对项目口语表达

回答：提高表达能力的核心是理清思路，我用来提高自己表达能力的方法是复述，具体操作是找几部自己比较喜欢的电影，看15min，然后暂停，并且用1min复述这15min的剧情，每天锻炼1h左右（也就是复述4次），一个月左右就能有较为明显的效果了。
这个方法我在高中毕业的暑假中用过，持续了一个多月。之后在大学四年中，我参与竞选的演讲都十分成功，现在工作后与领导同事的沟通、组会交流，以及项目沟通都十分顺畅。
我比较推荐这个方法，您可以试一下。

标签: java, python, php
问题：git 怎样删除远程仓库的某次错误提交？
在网上找到一种方法：

在本地把远程的master分支删除，再把reset后的分支内容给push上去
本地仓库　彻底回退到某一个版本

git reset –hard
删除远程的master分支 (注意master前有个:)

git push origin :master
重新创建远程master分支(这跟我们第１次提交本地代码库给远程仓库的命令一样吧)

git push origin master
我的问题是除了这种比较暴力的方法，还有别的方法吗？

回答：假设你有3个commit如下：
```
commit 3
commit 2
commit 1

```
其中最后一次提交`commit 3`是错误的，那么可以执行：
```
git reset --hard HEAD~1

```
你会发现，`HEAD is now at commit 2`。
然后再使用`git push --force`将本次变更强行推送至服务器。这样在服务器上的最后一次错误提交也彻底消失了。
值得注意的是，这类操作比较比较危险，例如：在你的`commit 3`之后别人又提交了新的`commit 4`，那在你强制推送之后，那位仁兄的`commit 4`也跟着一起消失了。

标签: github, visual-studio
问题：Vue动态面包屑导航怎么实现
没有思路，求大神解答
补充一下，我的思路是beforeEach获取上一个路由name和即将进入的路由name，然后填加到数组，最后router-link循环，但是不知道从哪下手

回答：```
var routeList = []

router.beforeEach((to, from, next) => {
  var index = routeList.indexOf(to.name)
  if (index !== -1) {
    //如果存在路由列表，则把之后的路由都删掉
    routeList.splice(index + 1, routeList.length - index - 1)
  } else {
    routeList.push(to.name)
  }
  to.meta.routeList = routeList
  next()
})
```
之后在需要用到的页面
```
beforeRouteEnter(to, from, next) {
  next(vm=>{
    vm.routeList = to.meta.routeList
  })
}
```
或者在watch里
```
this.$route.meta.routeList
```

标签: vue.js
问题：webpack配置中devtool项加不加#有什么区别？
用vue-cli生成的项目中，webpack.dev.conf.js里有这么一段
```
// cheap-module-eval-source-map is faster for development
devtool: "#cheap-module-eval-source-map",

```
去webpack官网上看关于devtool的文档，里面没提到说前面需要加#。实际中我去掉或者带上#也不会影响打包。那这个#到底干嘛用的呢？

回答：文档里有说：
Prefixing @, # or #@ will enforce a pragma style. (Defaults to @ in webpack@1 and # in webpack@2; using # is recommended)
翻译成中文就是使用指定的符号来指定预处理风格

标签: javascript
问题：TS中报错说style在element类型中不存在怎么办
我用queryselectorall去获取一个dom元素集合，然而在编译时却报错说property 'style' does not exist on type 'element'。在控制台里看block集合里各个元素是有style属性的，但是用for循环去遍历就没了。求指教一下，是不是要转类型，或者是要用foreach去遍历？
用的是typescript。
代码：
```
        var winWidth = document.body.clientWidth;
        var height = winWidth*1.23;
        let block = document.querySelectorAll(".block");
        for(var i=0;i<block.length;i++){
            block.item(i).style.height = height + "px";
        }
        
        
```

回答：这是typescript的类型检查导致的，需要在你的querySelectorAll方法前面加个类型断言就好了，如下
```
let block = document.querySelectorAll(".block") as NodeListOf<HTMLElement>;
```

标签: typescript, angular2, javascript
问题：js 指定删除数组（树结构数据）
查找相同ID删除对象,ID相同则删除该对象
var data =[{id:1,name:'一级', children:[{id:2,name:'二级', children:[{id:3,name:'一级', children:[{id:31,name:'二级'},{id:32,name:'二级'},{id:33,name:'二级'}],company_id:7}],company_id:8}], company_id:9}]
比如ID==31，得到以下数组
[{id:1,name:'一级', children:[{id:2,name:'二级', children:[{id:3,name:'一级', children:[{id:32,name:'二级'},{id:33,name:'二级'}],company_id:7}],company_id:8}], company_id:9}]

回答：```
function filter (data, id) {
  var newData = data.filter(x => x.id !== id)
  newData.forEach(x => x.children && (x.children = filter(x.children, id)))
  return newData
}
```

标签: javascript
问题：一个电商系统中，消息中间件可以用来做什么呢？
当然不仅仅限于电商 
最近在了解消息中间件，但是一直不太清楚消息中间件到底是干嘛的，到底在一个系统中用来做什么，就好比redis，内存数据库，我可以在系统中缓存数据，缓解db压力，可以充当队列，用于订单系统异步处理，只是拿redis来举个例子，不是和kafka来比较，在网上很多人介绍都只说生产者消费者模式，异步阿，用于消息告知等等，看了之后更是一头雾水，有了解的能否举几个在实际项目中或工作中，场景中的例子，可以更直观的对消息中间件有一个理解，谢谢

回答：就题目和个人理解回答：消息中间件，是解决分布式系统中各个系统相互通信的工具。
举个很常用的例子：
A系统是分布式模块化构成：
包含a子系统--比如用户模块；包含b子系统--比如资产模块。
现在接到这样的一个需求：要求在用户成功注册系统用户时，要赠送积分给该用户。
那么这个流程就是：
```
用户注册——》a子系统新增用户——》a子系统新增用户成功通知b子系统加相应积分——》b子系统接收通知——》b子系统增加用户积分
```
以上的通知和接收即为消息中间件中的发布和订阅概念。
当然，你可能会问为什么不在同一个事物里注册完用户加相应用户积分？
答案是：是可以的，只是这样系统就不能达到模块之间业务解耦的目的。
所以消息中间件又可以用来解决分布式系统各个模块耦合的功效。

标签: java, redis, php
问题：webpack打包生成的文件名问题
webpack入口为多页，每个页面中有懒加载的组件，打包出来懒加载的组件会打成不同id的文件名，但是没有模快名，分辨不出当前这个id属于哪个模块下，如果能让懒加载的文件带上模块名？
如：
```
` a.html  
 a.js
 b.html
 b.js`
```
//懒加载模块，分别对应a,b模块
```
` 1.js
 2.js
 3.js
 4.js
`
```
```
  //webpack配置
output: {
    path: config.build.assetsRoot,
    filename: utils.assetsPath('js/[name].[chunkhash].js'),
    chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
  },
```

回答：代码里的`[name]`默认是`id`覆盖，如果你要给`chunkFilename`重新起名字，要使用`webpack1`的`require.ensure()`或`webpack2`以上的`import()`方法。
webpack1:
```
require.ensure(dependencies: String[], callback: function(require), chunkName: String)
```
上面的`chunkName`对应的就是`webpack`里的`chunkFilename`里的`[name]`
webpack2-3:
```
const Foo = asyncComponent(() => import(/* webpackChunkName: "foo" */ "./foo"))

<Route path="/xx" component={Foo} />

```
上面的`import()`是`webpack2`以上版本的写法，注意`/* webpackChunkName: "foo" */`，这里对应的就是`webpack`里的`chunkFilename`里的`[name]`

标签: vue.js, webpack, javascript
问题：关于vuex的作用。
刚学过vuex,现在自己做了个电商小项目准备用下vuex,于是我就想说到把购物车的商品放vuex里边，方便不同组件调用到购物车里边的数据，但是实际项目中，我想了下又感觉vuex没什么用，原因如下：
当我们点击加入购物车的时候，肯定要把需要加入购物车的商品传给后台呀。那我们进入到购物车组件里边，直接从后台调取数据不就直接可以看到购物车的商品？根本没必要把需要加入购物车的商品传给vuex呀。（当然有一种可能就是传给vuex，可以直接读取，不用再调用后台数据。）
是我vuex用在购物车上本来就是错的？那我可以用在什么地方，举几个例子

回答：在使用库或框架时，需要注意一个「适用性」的问题。
Vuex 或者说实现了 Flux 思想的库，解决了几个问题：
1. 组件之间的数据通信
2. 使用单向数据流的方式进行数据的中心化管理

为什么要解决这样的问题呢？其实是因为当程序逻辑过于复杂的时候，非中心化的数据管理会让整个 app 的逻辑非常混乱。
举一个不使用中心化的数据管理机制的具体例子：
一个 app ，有四个 tab，每个 tab 都需要读取用户的资料。如果数据在每个 tab 的控制器里（或者说组件里）都存了一份，那么在用户手动更新了用户资料之后，就需要在每一个 tab 里都更新一遍用户资料，才能保证用户看到的永远是最新的资料。
如你问题里所说，我每进一个 tab 的时候重新请求一下不就好了吗？
这样的解决方案不是不可以，但弊端也非常明显：
1. 对于服务器端来说，频繁的请求是非常占用资源的，如果你的 app 用户足够多，那么每多出一个请求，对公司来说，都是一大笔钱。如果数据存在了 store 中，并且所有的 tab 都读取同一份数据，在用户更新资料时，在前端更新了 store 中的数据，是不是在切换 tab 时就减少了四个请求呢？
2. 对于前端开发者来说，如果你的项目足够复杂，团队的规模也不仅是一个人，那么前端代码就会因为数据分散管理而产生非常严重的性能和稳定性的隐患（比如你的同事觉得进入模块就刷新用户资料太慢了，手贱把刷新的代码删了，你又没发现）。

另外单向数据流的好处也很明显：
1. 视图组件变得很薄，只包含了渲染逻辑和触发 action 这两个职责，即所谓 "dumb components"。
2. 要理解一个 store 可能发生的状态变化，只需要看它所注册的 actions 回调就可以。
3. 任何状态的变化都必须通过 action 触发，而 action 又必须通过 dispatcher 走，所以整个应用的每一次状态变化都会从同一个地方流过。其实 Flux 和传统 MVC 最不一样的就在这里了。React 在宣传的时候一直强调的一点就是 “理解你的应用的状态变化是很困难的 (managing state changing over time is hard)”，Flux 的意义就在于强制让所有的状态变化都必须留下一笔记录，这样就可以利用这个来做各种 debug 工具、历史回滚等等。
你问题中的场景，业务过于简单，确实是没有必要使用 vuex 的，但这不代表其他大型应用不应该使用这个框架。

标签: vue.js, vuex, vue-cli, javascript
问题：es6如何快速的删除数组元素
有这么一个数组
```
let arr = [
            {id:1,value:2},
            {id:2,value:3},
            .......
          ]
```
想删除数组里id=8的元素，
使用es6如何方便快捷的实现

回答：`ES6 findIndex` MDN :Array.prototype.findIndex()
`findIndex()`方法返回数组中满足提供的测试函数的第一个元素的索引。否则返回-1。
```
arr.splice(arr.findIndex(item => item.id === 8), 1)
```
推荐文章：【深度长文】JavaScript数组所有API全解密 | louis blog

标签: ecmascript-6
问题：懂远程调用Rpc框架的同学来解答一下
看了一下rpc框架的作用，是可以实现远程调用，可以基于http协议，也可以用别的协议。
这里的远程调用，指的应该是后端服务A和后端服务B互调吧（虽然有些地方会把调用方称作客户端，但其实还是服务端和服务端互调）。
那如果前端，就比如浏览器端，想通过post或者get方式去调后端的接口，也能称之为RPC方式吗？应该不是吧，充其量就是基于http的restful接口调用吧。而且前端（浏览器端）想去调后端接口，只能通过http协议，如果那些实现了别的协议的rpc框架，根本没法处理http请求吧
不知道我的理解对不对

回答：HTTP是通信协议，RPC是一种开发方式，他可以基于HTTP协议（比如gRPC)，也可以基于其他协议，比如更基础的TCP
通信协议的选择只是RPC实现中的一小部分，更重要的一部分是编码协议。比如json/xml属于文本编码，还有二进制字节编码，比如protoful，thrift。http对比tcp，最诟病的就是多余的头信息，而且还是使用的文本编码，造成整个数据包体积过大。不过据说http2改进很多，修改为二进制编码了，还支持多路复用，gRPC就是基于http2实现的。
至于restful，其实他本身是一套将资源对象化的设计标准，不过目前都作为技术实现再用，本身又分为严格的和非严格的。从目前上来说restful接口可以认为是一种基于http使用json编码的RPC实现，但还是本身restful是设计规范，更多的是约束资源的访问获取手段，不应当用于复杂的函数调用。
最后前后端，目前javascript也有json-RPC，ajax-RPC一类的更专注于函数调用的RPC实现，可以基于HTTP，也可以基于websocket，如果目的是函数调用，你可以试用一下，会比使用restful舒服很多。

标签: java, rpc, 后端, 全栈工程师, go
问题：vue项目报错如下：(Emitted value instead of an instance of Error) 
`(Emitted value instead of an instance of Error) the "scope" attribute for scoped slots have been deprecated and replaced by "slot-scope" since 2.5. The n
ot-scope" attribute can also be used on plain elements in addition to <template> to denote scoped slots.`

回答：你检查下你的列表组件里，slot 里的  <template> 上面有个 scope 属性，你改成 slot-scope
```
<template scope="xxx">yyyyyyyy</template> 
```
改成
```
<template slot-scope="xxx">yyyyyyyy</template> 
```
scope 属性在2.5以后的版本中已经废弃， 被 slot-scope 替代
slot-scope 不光可以用在 template 元素上，也可以用在其它元素

标签: vue.js, webpack
问题：为什么element ui el-input @click事件无效
```
  <el-form-item label="审批人">
    <el-input v-model="formInline.user" placeholder="审批人" @click="alert(1)"></el-input>
  </el-form-item>
```
如何给el-input添加点击事件

回答：vue.js文档 给组件绑定原生事件
#### 给组件绑定原生事件
有时候，你可能想在某个组件的根元素上监听一个原生事件。可以使用 v-on 的修饰符 .native。例如：
```
<my-component v-on:click.native="doTheThing"></my-component>
```
```
// 使用`navite`修饰符
@click.native="handleClick"
handleClick(){
    alert(1);
}
// 你的写法会报错。会认为alert不是一个函数。好奇是什么场景要绑定点击事件到el-input呢
```

标签: javascript
问题：问一个react更新State的问题？
读react官网：
状态更新可能是动态的
```
// Wrong
this.setState({
  counter: this.state.counter + this.props.increment,
});
```
官网说这种写法是错误的
```
// Correct
this.setState((prevState, props) => ({
  counter: prevState.counter + props.increment
}));
```
这种写法是正确的
我实在搞不懂为什么第一个是错误的，第二种写法是正确的，哪位大神能帮忙解释一下？在哪种需求场景下，会出现上述的情况，最好能写点代码解释下，多谢，大神们指导。

回答：因为 this.props 和 this.state 可能是异步更新的，你不能依赖他们的值计算下一个state(状态)。
setState 方法“或许”是异步的。也许你觉得，看上去更新 state 是如此轻而易举的操作，这并没有什么可异步处理的。但是要意识到，因为 state 的更新会触发 re-rendering，而 re-rendering 代价昂贵，短时间内反复进行渲染在性能上肯定是不可取的。所以，React 采用 batching 思想，它会 batches 一系列连续的 state 更新，而只触发一次 re-render。
setState的机制其实跟浏览器的dom更新类似，等到一定数量或者一定时间间隔才一起更新一次，它们都是异步更新的，所以这样做在一定几率是有问题的。
或者，直接看下面的一个小例子。
比如，最简单的一个场景是
```
function incrementMultiple() {
  this.setState({count: this.state.count + 1});
  this.setState({count: this.state.count + 1});
  this.setState({count: this.state.count + 1});
}
```
直观上来看，当上面的 incrementMultiple 函数被调用时，组件状态的
count 值被增加了3次，每次增加1，那最后 count 被增加了3。但是，实际上的结果只给 state 增加了1。不信你自己试试～
## 让 setState 连续更新的几个 hack
如果想让 count 一次性加3，应该如何优雅地处理潜在的异步操作，规避上述问题呢？
以下提供几种解决方案：
方法一：常见的一种做法便是将一个回调函数传入 setState 方法中。即 setState 著名的函数式用法。这样能保证即便在更新被 batched 时，也能访问到预期的 state 或 props。（后面会解释这么做的原理）
方法二：另外一个常见的做法是需要在 setState 更新之后进行的逻辑（比如上述的连续第二次 count + 1），封装到一个函数中，并作为第二个参数传给 setState。这段函数逻辑将会在更新后由 React 代理执行。即：
setState(updater, [callback])
方法三：把需要在 setState 更新之后进行的逻辑放在一个合适的生命周期 hook 函数中，比如 componentDidMount 或者 componentDidUpdate 也当然可以解决问题。也就是说 count 第一次 +1 之后，出发 componentDidUpdate 生命周期 hook，第二次 count +1 操作直接放在 componentDidUpdate 函数里面就好啦。
更多详细内容:从 setState promise 化的探讨 体会 React 团队设计思想

标签: react.js, javascript
问题：vue-cli构建的项目，eslint一直报CRLF/LF的linebreak错误
如题，vue在构建项目的时候选择了airbnb规则，同时项目构建后被windows的unix bash工具pull并且push过，这之后在windows上进行开发，就开始一直报
```
Expected linebreaks to be 'CRLF' but found 'LF'
```
这样的错误，后经查是一种强制统一方式，并且解决方法是
```
linebreak-style: ["error", "windows"]
```
强制使用windows方式，我将之添加到了项目根目录下的 .eslintrc.js 文件中的rule字段下：
```
// add your custom rules here
  'rules': {
    // don't require .vue extension when importing
    'import/extensions': ['error', 'always', {
      'js': 'never',
      'vue': 'never'
    }],
    // allow optionalDependencies
    'import/no-extraneous-dependencies': ['error', {
      'optionalDependencies': ['test/unit/index.js']
    }],
    // try to fix the line break problem
    'linebreak-style': ["error", "windows"],
    // allow debugger during development
    'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0
  }
```
结果无效，现有问题二个：'1. 是否是因为系统环境不同而造成了某种强制转换才会引发如上的错误？
2. 如何选择性的关闭eslint某个功能（linebreak检查）？

回答：#### 问题1
不同的操作系统下，甚至是不同编辑器，不同工具处理过的文件可能都会导致换行符的改变。
#### 问题2
项目根目录下有`.eslintrc.js`文件，在配置文件中修改rule配置项，如下：
```
// 统一换行符，"\n" unix(for LF) and "\r\n" for windows(CRLF)，默认unix
// off或0: 禁用规则
'linebreak-style': 'off'
```

标签: vue-cli, eslint
问题：关于javascript es6 class中static方法的使用场景
我们知道在class中定义的static方法，在使用时可以直接调用，不用实例化，我的疑惑是
1. 在定义类的方法的时候，什么方法适宜定义成static，什么方法不用？
2. 我可不可以把类中的方法都定义为static,这 样做有什么弊端没有？
还请详细介绍下class的适用场景以及static的适用场景，不胜感激！

回答：在OOP中，带方法的类（即非数据类），一般有两个作用
- 封装方法和属性（通常意义的 OOP 类）
- 封装临时变量（和来处理复杂事务的类）

不管哪个作用，方法通常都是会操作成员变量的，这种情况下，肯定只能写实例方法（因为要操作成员）
除此之外，不需要访问类属性的方法都可以写成静态的，这类方法一般都是 Helper 方法，即对输入进行处理再得到一个输出，与对象的成员无关。这类方法也可以直接写为公共函数（非方法函数）。不过在 C#、Java、TypeScript 等有权限限制的语言中，静态方法可以访问对象的私有成员，比如 `Foo` 类的 `Foo.bla(f: Foo)` 静态方法内部可以直接访问 `f.somePrivateMethod()`，当然目前 JavaScript 中不存在这种情况，以后引入私有成员之后会不会存在这种情况也还要观望
顺便说一下，多数静态类型语言中成员方法都是可以直接调用同一个类的静态方法的，但 JavaScript 由于实现机制不能，做不到。
### 回看有惊喜，2020-02-27 更新
JavaScript 的私有字段提议已经到了 stage-3 (实验) 阶段，TypeScript 3.8 和 Chrome 7.4 已经支持私有字段，那么前面提到的疑惑其实是可以实验来验证的
实验环境：
- Microsoft Edge Version 80.0.361.62 (Official build) (64-bit)
- TypeScript Playground

实验代码，TypeScript
```
class MyClass {
    static create(name: string, age: number = 10) {
        var obj = new MyClass();
        obj.#name = name;
        obj.#age = age;
    }

    #name: string;
    #age: number;

    constructor() {
        this.#name = "Default Name";
        this.#age = 0;
    }

    toString(): string {
        return `${this.#name}: ${this.#age`;
    }
}

const inst = MyClass.create("James", 10);
// inst.#name = "Hello";

console.log(inst.toString());
```
结论
- 静态方法（`static create()`) 中可以访问对象的私有成员 （`#name` 和 `#age`）
- 外部不能访问对象的私有成员(`inst.#name = "Hello"` 会报错）

标签: javascript
问题：react ant design 中如何在表头中加个Icon,悬浮icon又触发Tooltip?
如题，表头的某一列是：
```
<Table.Column title='目的地' dataIndex='destination' key='destination'></Table.Column>
```
显示效果就是‘目的地’。
我想在后面加个问号的Icon：question-circle,鼠标悬停上去的时候显示提示文字：‘这是提示’。
这里面用到了Table，Icon.Tooltip三个组件，但是不知道该怎么写出来。写法一直报错。

回答：`Table.Column` 的 `title` 传值可以传入一个 `ReactNode `。
所以，可以写成这样
```
const title = (
  <span>
    目的地
    <Tooltip title="这是提示">
      <Icon style={{ marginLeft: '0.25em' }} type="question-circle" />
    </Tooltip>
  </span>
);

<Table.Column title={title} dataIndex='destination' key='destination'></Table.Column>
```

标签: react.js, antd
问题：js promise中如何取到[[PromiseValue]] ?
```
Promise {[[PromiseStatus]]: "resolved", 
        [[PromiseValue]]: "http://dl.stream.qqmusic.qq.com/M8000046HRBd0FvKLm…C380C8F140044403EDC0124&guid=489780640&fromtag=30"
        }
```
有一个promise，现在取到的值为上述所示， 能不能直接从中取到  promisevalue的url？
该promise由 `QQMusic.getSong(1561).then(song => song.url)` 获得
这个程序是别人写的，再加上不太了解promise，所以请问下可否直接取到？

回答：```
var a = Promise.resolve('xx')
// Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "xx"}
a.then(function (result) { console.log(result) })
```

标签: promise, javascript
问题：vue的CDN有几种文件结尾，分别是什么意思？
CDN地址：
http://www.bootcdn.cn/vue/
下面几种文件结尾分别是什么意思？
```
vue.js
vue.common.js
vue.esm.js
vue.runtime.js
vue.runtime.esm.js
vue.runtime.common.js
```

回答：common和esm分别是2种现代模块化规范CommonJS和EcmaScript Module的缩写。
现在主流的webpack2采用esm，也就是es6及以上的模块化编程，说白了就是
import ... from ...
vue.runtime.js则是运行时的意思，纯粹全是javascript，适用于生产环境，需要经过预编译。
官方说法是用来创建 Vue 实例，渲染并处理 virtual DOM 等行为的代码。基本上就是除去编译器的其他一切。
vue.esm.js，预编译+运行时，也就是模板字符串和现在最常用的单文件组件.vue文件，需要经过它预编译转化成纯javascrit，然后再运行，适用于开发环境。
官方说法叫用来将模板字符串编译成为 JavaScript 渲染函数的代码。
vue.js则是直接用在<script>标签中的。
1.若是自己写个小demo测试一下
```
用vue.js即可，方便阅读源码

```
2.若你是用vue2+webpack2开发项目（vue-cli采用的方式）
```
开发环境用vue.esm.js
生产环境用vue.runtime.esm.js，比完整版小30%左右，前端性能更优

```

标签: vue.js
问题：怎么让类数组使用forEach?
```
<div>1</div>
<div>2</div>

```
```
let div = document.getElementsByTagName('div');

div.forEach = Array.prototype.forEach;
div.forEach(item=>{
    console.log(item);
});
这样是一种方法，如何使用call、apply或bind 使用forEach方法

```

回答：```
[].forEach.call(document.getElementsByTagName("div"), (item) => console.log(item))
```
```
[].forEach.apply(document.getElementsByTagName("div"), [(item) => console.log(item)])
```
```
var getDivs = [].forEach.bind(document.getElementsByTagName("div"))
getDivs(item => console.log(item))
```
```
document.querySelectorAll('div').forEach(item => console.log(item))
```

标签: javascript
问题：正则表达式，3-10位必须包含至少1个数字和1个字母，为何我这样写不对？
```
(?=[a-zA-Z]+)(?=[0-9]+)[a-zA-Z0-9]{3,10}
```
上面是我写的，但不正确，不知道原因。我理解的是第一个正向预查找出至少一个字母，和第二个正向预查找出至少一个字母。然后最后是[a-zA-Z0-9]{3,10}，这大家都懂。不知道哪里错了，是不是我对正向预查的理解不正确？

回答：`?=`不同的人叫法不一样，你称之为`预查`，我更倾向于叫`零宽断言`，也就是说`?=`只是匹配一个位置，并不匹配具体的字符，所以是`零宽`，也就是宽度是0。
所以`(?=[a-zA-Z]+)`匹配一个位置，这个位置后面`紧跟`至少一个字母，注意此时位置并没有后移;
`(?=[0-9]+)`也是匹配一个位置，这个位置后面后面`紧跟`至少一个数字；
因为`(?=[a-zA-Z]+)`和`(?=[0-9]+)`都只匹配位置，而不匹配具体的字符，这两个又直接写在了一起，也就是说`(?=[a-zA-Z]+)(?=[0-9]+)`意味着这个位置后面`紧跟`至少一个字母，`同时紧跟`至少一个数字，也就是说这个位置后面的字符既是字母又是数字，显然这样的位置不存在。
Update:
你试试这个`/^(?=[a-zA-Z]*[0-9])(?=[0-9]*[a-zA-Z])[a-zA-Z0-9]{3,10}$/`。

标签: python, c#, java, javascript
问题：JS 中 new Date 默认为1或0的问题
最近看到了一个获取天数的写法，之前一直没用过，直接上代码
```
let dayLength = new Date(2017,2,0); //28
```
有哪位大佬知道上面为什么能得到2017年2月的总天数吗？
看了 MDN 没找到答案MDN_Date

回答：虽然  `new Date(2017,2,0)` 并不是输出 28 但是它却包含 28 这个信息，确实是一个获取某月天数的好方法。
下面来说下为什么，Date 作为构造函数，有一种用法是这样的，就是您说的这种：
`new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);`
重点：
month 参数，是指月份，从 0 开始，也就是说，0 表示 1月，2表示 3月。
day 参数，是指月份中的某一天，从 1 开始，也就是说 1 就是月份中的第一天，2就是第二天，0 是不在取值范围内的
然后看一下 ES 规范：http://es5.github.io/#x15.9.1.12，这一节的第七和第八条：
7.Find a value t such that YearFromTime(t) == ym and MonthFromTime(t) == mn) and DateFromTime(t) == 1; but if this is not possible (because some argument is out of range), return NaN. 
8.Return Day(t) + dt − 1.
简单解释下就是，传入 year, month, day 来获取一个新的日期实例时，会先获取指定年、月的 1 号，例如 year=2017, month=4，会先获取 2017-5-1 这个日期，这是上面第七步完成的。
然后第八步，上面这个日期会加上 day 参数的整数值，然后减去 1。
看见了没有，要减去 1。你上面的例子：
```
new Date(2017, 2, 0)
```
先获取 `2017-3-1` 然后 加上 0 ，再减去 1，就是 `2017-2-28`
明白了吧。
综上，咱们可以这样来获取某年某月有多少天：
```
function getMonthLength(year, month) {
    return new Date(year, month, 0).getDate();
}

getMonthLength(2017, 2); //28
```

标签: javascript
问题：后台管理系统有必要允许多端登录么？
php在写后台管理系统的时候有必要开启多设备登录么？请发表观点，并说明原因吧，谢谢！

回答：允许还不允许，取决于你的需求。比如早期 QQ 就不允许多端登录，但是随着智能手机的发展，越来越多人 PC、手机同时登录QQ，也就允许多端了。
到底需要不需要，应该从你的应用的使用场景去考虑，比如是否有两地同时办公(比如办公室、家里)的场景，有没有PC、手机同时访问的需求，有没有 Web、客户端同时访问的需求……

标签: php
问题：如何在 Spring容器 service层获取当前登录用户信息？
用户信息绑定会话，怎样才可以在服务层注入？

回答：谢谢邀请回答。
如果不想在controller拿到用户信息传到service层，直接在service层也是可以拿到的。
spring mvc在处理请求的时候，会把请求对象放到RequestContextHolder持有的ThreadLocal对象中,你可以去看看DispatcherServlet类的源代码。
在service层可以按照如下代码获取：
```
//获取到当前线程绑定的请求对象
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
//已经拿到session,就可以拿到session中保存的用户信息了。
        System.out.println(request.getSession().getAttribute("userInfo"));
```

标签: spring-mvc, spring, java
问题：拼团活动 的 业务逻辑
有人做过拼团活动么，做过的讲一下业务逻辑吧。看看和我自己想的一样不。

回答：可以参照人人商城的拼团活动（网上有源码）或者是有赞的（只能看规则什么的）或者是拼多多（同样是展示，这里有0元参团的，正好可以用来查看各界面展示）的，他们三个逻辑也各不相同，但大体思路是一样的。
相关的表差不多是：
- 拼团商品表（包含商品信息，是否单独购买，开团人数，开团期限等）
- 开团信息表（关联拼团商品，团开始时间，团结束时间，总人数，当前参团人数，开团人，参与人等）
- 开团会员的购买订单表（也可在普通商品订单表基础上增加字段区分）

需要注意的基本就是：
- 超时未成团的自动退款（可能需要支付宝、微信等退款接口）
- 未成团前不能发起退款，只有成团后才能发起退款
- 未支付成功不算参团，需要注意超卖的情况

大体是这样的吧。

标签: php, javascript, python, node.js, java
问题：vue-router两种模式，到底什么情况下用hash,什么情况下用history模式呢？
vue-router两种模式，hash，history看了官方文档也不怎么明白，到底什么情况下用hash,什么情况下用history模式呢？

回答：#### None
对于 Vue 这类渐进式前端开发框架，为了构建 SPA（单页面应用），需要引入前端路由系统，这也就是 Vue-Router 存在的意义。前端路由的核心，就在于 —— 改变视图的同时不会向后端发出请求。
为了达到这一目的，浏览器当前提供了以下两种支持：
1. 
hash —— 即地址栏 URL 中的 `#` 符号（此 hash 不是密码学里的散列运算）。
比如这个 URL：`http://www.abc.com/#/hello`，hash 的值为 `#/hello`。它的特点在于：hash 虽然出现在 URL 中，但不会被包括在 HTTP 请求中，对后端完全没有影响，因此改变 hash 不会重新加载页面。
2. 
history —— 利用了 HTML5 History Interface 中新增的 `pushState()` 和 `replaceState()` 方法。（需要特定浏览器支持）
这两个方法应用于浏览器的历史记录栈，在当前已有的 `back`、`forward`、`go` 的基础之上， 它们提供了对历史记录进行修改的功能。只是当它们执行修改时，虽然改变了当前的 URL，但浏览器不会立即向后端发送请求。

因此可以说，hash 模式和 history 模式都属于浏览器自身的特性，Vue-Router 只是利用了这两个特性（通过调用浏览器提供的接口）来实现前端路由。
#### None
一般场景下，hash 和 history 都可以，除非你更在意颜值，`#` 符号夹杂在 URL 里看起来确实有些不太美丽。
> 如果不想要很丑的 hash，我们可以用路由的 history 模式，这种模式充分利用 history.pushState API 来完成
URL 跳转而无须重新加载页面。——  Vue-router 官网。
另外，根据 Mozilla Develop Network 的介绍，调用 `history.pushState()` 相比于直接修改 `hash`，存在以下优势：
- 
`pushState()` 设置的新 URL 可以是与当前 URL 同源的任意 URL；而 `hash` 只可修改 `#` 后面的部分，因此只能设置与当前 URL 同文档的 URL；
- 
`pushState()` 设置的新 URL 可以与当前 URL 一模一样，这样也会把记录添加到栈中；而 `hash` 设置的新值必须与原来不一样才会触发动作将记录添加到栈中；
- 
`pushState()` 通过 `stateObject` 参数可以添加任意类型的数据到记录中；而 `hash` 只可添加短字符串；
- 
`pushState()` 可额外设置 `title` 属性供后续使用。

当然啦，`history` 也不是样样都好。SPA 虽然在浏览器里游刃有余，但真要通过 URL 向后端发起 HTTP 请求时，两者的差异就来了。尤其在用户手动输入 URL 后回车，或者刷新（重启）浏览器的时候。
1. 
`hash` 模式下，仅 `hash` 符号之前的内容会被包含在请求中，如 `http://www.abc.com`，因此对于后端来说，即使 没有做到对路由的全覆盖，也不会返回 404 错误。
2. 
`history` 模式下，前端的 URL 必须和实际向后端发起请求的 URL 一致，如 `http://www.abc.com/book/id`。如果后端缺少对 `/book/id` 的路由处理，将返回 404 错误。Vue-Router 官网里如此描述：“不过这种模式要玩好，还需要后台配置支持……所以呢，你要在服务端增加一个覆盖所有情况的候选资源：如果 URL 匹配不到任何静态资源，则 应该返回同一个 index.html 页面，这个页面就是你 app 依赖的页面。”

#### 小节
对于一般的 Vue + Vue-Router + Webpack + XXX 形式的 Web 开发场景，用 `history` 模式即可，只需在后端（Apache 或 Nginx）进行简单的路由配置，同时搭配前端路由的 404 页面支持。

标签: javascript
问题：vscode 怎么双击选中连字符
我的css类名习惯用 - 横线连字符，可是在vscode每次双击只能选中其中一个单词，不能选中整个连字符，请问有办法解决吗？谢谢了！

回答：在设置里
```
  // 执行文字相关的导航或操作时将用作文字分隔符的字符
  "editor.wordSeparators": "`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?",
```
去掉 - 就好了。

标签: css, html, visual-studio-code
问题：JS 构造函数原型对象设为 null，为什么其实例依旧存在原型链？
```
    function Dog(){}
    Dog.prototype = null;
    var dog = new Dog();
    console.log(dog.__proto__==Object.prototype)//为什么这里dog.__proto_不是null，不是dog.__proto应该指向 Dog.prototype的么
```

回答：可以查看es5的说明：
> If Type(proto) is not Object, set the [[Prototype]] internal property of obj to the standard built-in Object prototype object as described in 15.2.4.
就是说，在通过 new 关键字来创建一个对象的时候，会查看 Dog.prototype 是不是一个对象，如果不是的话，就设置为 `Object.prototype`
如果你想让 dog 没有原型链，可以 `var dog = Object.create(null)`
`Object.create`的执行步骤可以看这里：
> Set the [[Prototype]] internal property of obj to O.
`Object.create(null)`
等价于：
```
var obj = new Object();
obj.__proto__ = null;
```

标签: javascript
问题：PHP命名空间中define和const的区别
比如在a.php用define定义一个常量，在b.php中声明一个命名空间 && 引入a.php
此时在b.php中无法再次定义同名的常量，然而用const却可以，求解，谢谢诸位
```
a.php代码：
define('ROOT','123');

b.php代码：
namespace web360;
require 'c.php';
define('ROOT','123');
```
此时会报错（常量已经定义）
而如果用const定义的话，则不会出现此问题

回答：这是因为 define 不会考虑命名空间，而 const 会。
简单的说，使用 define 定义时，不会考虑当前的命名空间，所以你两次定义的常量名称重复，会报重复定义。
而使用 const 定义时，会带上命名空间，你两次定义的常量实际是 `ROOT` 和 `web360\ROOT` 。名称不重复，不会报重复定义的错误。

标签: php, 命名空间, define, const
问题：Python中list+dict的一个小问题，求大家帮忙解答
l1 = [
{"name": "aaa","value": 1},
{"name": "aaa","value": 1},
{"name": "bbb","value": 2},
{"name": "bbb","value": 1}
]
l2 = [
{"name": "aaa", "value": 2},
{"name": "bbb", "value": 3}
]
l1--->l2?
请教一个小问题，如何将列表l1中所有dict中name相同的value加起来，生成类似于l2的列表？

回答：```
data = [
    {"name": "aaa", "value": 1},
    {"name": "aaa", "value": 1},
    {"name": "bbb", "value": 2},
    {"name": "bbb", "value": 1}
]

#第一种pandas
import pandas as pd

df = pd.DataFrame(data)
print df.groupby('name', as_index=False).sum().to_dict(orient='records')


#第二种groupby
from itertools import groupby
lst = []
for k, g in groupby(sorted(data), key=lambda x: x['name']):
    lst.append(dict(name=k, value=sum([_['value'] for _ in list(g)])))
print lst
```

标签: python
问题：对于<router-view></router-view>的用法
在APP.vue主组件中，内容上就只有<router-view></router-view>，然后在其他页面也有<router-view></router-view>，它是怎么传递的。原理是什么

回答：可以这样理解，正常写法中，一层路径(`/xxx`)对应一个`router-view`。
比如url: /a/b/c (假设a、b、c都为正常路径，不会作为参数)
- 那`/a`对应的就是App.vue中的router-view，`/a`进入`a.vue`中
- 那`/a/b`对应的就是a.vue中的router-view， `/a/b`进入`b.vue`中

以此类推。

标签: vue.js