Coder Social home page Coder Social logo

huanghongrui.github.io's People

Contributors

huanghongrui avatar

Stargazers

 avatar  avatar  avatar

Watchers

 avatar

Forkers

cybort

huanghongrui.github.io's Issues

Work手记

个人中心-首页:

所有行程伪代码思路:

  • 请求后台数据。
  • 如果没有,提示前往预定
  • 如果有,继续下一步
  • 组织数据
  • 渲染到页面

Pic获取失败404.现框.处理.Vue

问题原图

问题:获取用户图片接口..如获取失败404(本地测试).会出现该情况,框会显示出来...丑爆
想象:当出现这种情况...让图片显示为默认图片..

Vue环境:

// HTML
<img :src="userinfo.portraitUrl" v-on:error.once="whenError($event)">
// Vue.Methods:
    whenError : function(e){
        e.currentTarget.src = '../../imgs/headpro.png';
        console.log('图片错误')
    }

Done Pic

Ajax

出生:Ajax技术首次出现于2005年一篇在线文章。
功能:向server请求额外的数据而不无须卸载页面。(无须刷新页面即可从Server获取数据)
优点:带来更好的用户体验。
核心技术XMLHttpRequest对象(简称:XHR)
XHR是什么:是为向Server发送请求和解析Server响应提供了的流畅接口。
XHR用途:通过XHR对象取得新数据,然再通过DOM讲数据插入页面中。
另外:AJAX(Asynchronous JavaScript + XML)通信跟数据格式无关。获取数据不一定是XML数据。
缺点:破坏浏览器的后退与加入收藏书签功能。

Vim 日常操作收集

NerdTree | 侧边目录栏

命令: :NERDTree
快捷:map <C-n> :NERDTreeToggle<CR> > .vimrc
默认:autocmd VimEnter * NERDTree > .vimrc
左侧:let g:NERDTreeWinPos = "left" >.vimrc
命令:ctrl e > 快速打开目录

寄存器/使用系统剪贴板

sudo apt-get install gvim
sudo apt-get install vim-gnome 

继承

由于函数没有签名,无法实现接口继承。所以只支持【实现继承】

image

Git 日常操作

将远程仓库中的全部信息拉回到本地

命令: git fetch origin

获得关于远程分支的更多信息

查询:`git ls-remote`

新建一个本地分支,以 origin/ * 为镜像。

命令:git checkout -b [起个名] origin/[输入分支名]

当需要切换到其他线上分支时:(暂时没发现什么用-。-)

查询:git branch -va

Fork 操作

github的多人协作 : 讲解

生产秘钥

命令:ssh-keygen -t rsa -b 4096 -C "[email protected]"

Git小书

https://github.com/geeeeeeeeek/git-recipes

有趣实用的Docs

Chrome收藏夹...收藏的东西多了...都不知道放了什么-。-...

特意建个 Issues 来存放这些有趣或实用且目前使用不到的东西.

以便所需之时的快速搜索...


Important

Code-Guide:开发 | 编码规范

Practical

飞冰-赋能中后台建设: 适用后台系统搭建

MobX:是状态管理库中侵入性最小的之一。这使得 MobX的方法不但简单,而且可扩展性也非常好

StoryBook : 实用的,作用在于让前端工程师专注在样式,组件功能开发过程中。有关介绍文章

Prettier:这是一款用来写出高质量漂亮代码的东西

styled-components:CSS IN JS.

Interesting

Shave:用Js实现不超过规定行数并使溢出部分使用省略号显示..或许鸡肋,但因为line-clamp兼容还不好..只能寻找此库来弥补...

Npm-run-all:用于并行或顺序运行多个npm脚本的CLI工具。

Parcel:必要之时,可作为 Webpack 的替代品.. 急速简单强大-.-

React-Intl:支持150+语言...多语言需求可使用..(内涵其他功能)

cloc: 查看代码行数

WakaTime: 编程计时器

Tool

石墨 :用于可多人实时协作的云端文档与表格.

Get | Post

Get (最常用的请求类型) 用于向服务器查询某些信息。

Post(使用平率次于Get)用来向服务器发送应该被保存的数据。

区别:GET把参数包含在URL中,POST通过request body传递参数。

GET在浏览器回退时是无害的,而POST会再次提交请求。

GET产生的URL地址可以被Bookmark,而POST不可以。

GET请求会被浏览器主动cache,而POST不会,除非手动设置。

GET请求只能进行url编码,而POST支持多种编码方式。

GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。

GET请求在URL中传送的参数是有长度限制的,而POST没有。

对参数的数据类型,GET只接受ASCII字符,而POST没有限制。

GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。

GET参数通过URL传递,POST放在Request body中。

作用域链

代码在一个执行环境执行时,会创建变量对象的一个作用域链

作用域链的用途:

  • 保证有序访问 =》 所有 能对执行环境有权访问的 变量和函数。

作用域的头部,始终都是当前执行的代码所在环境的变量对象。(如果这个环境是函数,那其活动对象作为变量对象)

** 活动对象在最开始时只包含一个变量——arguments对象(不存在于全局中)**

作用域链中的下一个变量对象来自包含(外部)环境,而再下一个变量对象则来自下一个包含环境,一直延续到全局执行环境。——全局执行环境的变量对象始终都是作用域链中的最后一个对象。

CORS

  1. CORS需要浏览器和服务器同时支持。

  2. 所有浏览器都支持该功能,IE浏览器不能低于IE10。

  3. 整个CORS通信过程,都是浏览器自动完成,不需要用户参与。

  4. 对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。

  5. 浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

浏览器将CORS请求分成两类:

  • 简单请求(simple request)
  • 非简单请求(not-so-simple request)

同时满足以下两大条件,就属于简单请求。
否则 为 非简单请求。

(1) 请求方法是以下三种方法之一:
HEAD
GET
POST
(2)HTTP的头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

null & undefined

概述

nullundefined 含义相似,都有 “无” 的意思。所以如下例子将变量设为任何一个,意思效果几乎无差别。

var leo = null;
var leo = undefined;

if语句中,nullundefined 都是被自动转为 false.
在相等运算符 == 看来,它们两也是相等的.
只能说它们确实非常相似。

但是,还是要注意它们的 差别

null + 1 // 返回 1
Number(null) // 返回 0
// null 转为数字时,会转换为 0 
undefined + 1 // 返回 NaN
Number(undefined) // NaN
// 转换为 Not A Number

用法

null 表示空值

当知道某个变量 或 参数 为空值时,给予设定或传入.

undefined 表示初始化未定义

let leo;
leo // 返回 undefined 已声明变量,但无赋值。

let leoObj = new Object();
leoObj.name // undefined 对象无该属性

fun = arg =>  arg;
fun() // 返回 undefined 无传参,参数为undefined

TypeScript 踩坑记

提示需要安装 dva ...(但实际已有)
解决: 在 tsconfig.json 中加入:

删除 include

出现 N+ 错误..由webpack配置的tslint导致..
可以通过 npm run eject 显示配置config,
在生成出来的 /config > webpack.config.dev.js > 屏蔽

      {
        test: /\.(ts|tsx)$/,
        loader: require.resolve('tslint-loader'),
        enforce: 'pre',
        include: paths.appSrc,
      },

image
用于调试使用,真正开发最好开着...规范第一!


image

报错: TS2339: Property 【】 does not exist on type 【】

解决: 在class {} extends {} component 下第一行定义该属性: private timerID: any;


盒模型

盒模型:(box-sizing)

  • CSS中,盒模型描述了元素所占空间的内容。每个盒子有四个边:外边距边, 边框边, 内填充边 与 内容边。

W3C盒模型:(content-box)

  • width只包含 内容 部分

IE盒模型:(border-box)

  • width包含 内边距、内容距、边框

Some Code...

使用 IPhone-X时,底部需要做的特殊Padding样式:

constant(safe-area-inset-bottom)
env(safe-area-inset-bottom)

然而,进而遇到的问题是,当出现底部出现工具条时,会出现BUG.这时需要使用JS识别适应:

function ipXVerifyButtom () {
  var scale = window.innerWidth / window.screen.width;
  if (window.screen.height - window.innerHeight / scale < 100) {
    // 底部无工具栏的情况下
    return true;
  }

当使用时,如有工具栏那么使用样式..


Ajax

实现网页的异步加载,局部刷新网页。当在向服务器获取新数据时不需要刷新整个网页,提高用户体验。

使用Ajax的优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。

对应用Ajax最主要的缺点,它可能破坏浏览器的后退与加入收藏书签功能。

配置记录

虽说简单,但多了也是一时半会想不来的..所以做个记录..

命令行FQ

alias pc="proxychains4 -f ~/.proxychains.conf"

WebStorm

alias ws="/home/leo/Rui/webstorm/webstorm/bin/webstorm.sh"

Chrome

alias gg="/opt/google/chrome/chrome"

截图命令

shutter --select

source ~/.bashrc

查看局域IP

ifconfig | grep 10

React API

React V_16.3.0

1.即将淘汰的API.

componentWillMount
componentWillReceiveProps
componentWillUpdate

2.新增API

  1. componentDidUpdate()
    该生命周期不经常需要用到的,但可用于在恢复期间手动保存滚动位置的情况。
    与此同时这个新的生命周期功能涵盖componentWillUpdate。

  2. getDerivedStateFromProps(nextProps, prevState)
    state的更新基于props
    该静态生命周期在组件实例化以及接收新 Props 后调用。
    它可以 返回要更新的对象state,或是使用 null 指示新的 props, 让 state 不需要更新。

class Example extends React.Component {
  static getDerivedStateFromProps(nextProps, prevState) {
    // ...
  }
}
  1. getSnapshotBeforeUpdate(prevProps, prevState)
    该新的 生命周期在进行突变之前被调用(例如,在DOM被更新之前)。
    此生命周期的返回值将作为第三个参数传递给componentDidUpdate。
class Example extends React.Component {
  getSnapshotBeforeUpdate(prevProps, prevState) {
    // ...
  }
}

3. Example

  1. 初始化, 与之前不一, 弃用 componentWillMount , 直接初始化即可
// Before
class ExampleComponent extends React.Component {
  state = {};

  componentWillMount() {
    this.setState({
      currentColor: this.props.defaultColor,
      palette: 'rgb',
    });
  }
}

// After
class ExampleComponent extends React.Component {
  state = {
      currentColor: this.props.defaultColor,
      palette: 'rgb',
    }
  }
  1. 异步请求数据
    componentWillMount 对于服务器呈现(其中不使用外部数据的地方)和即将到来的异步呈现模式(其中请求可能被多次启动)是有问题的。
    常见的错误观念认为,componentWillMount可以避免第一个空的渲染状态。
    React总是render在之后立即执行componentWillMount。如果数据在时间componentWillMount触发时不可用,则render无论您何时启动抓取,第一个仍将显示加载状态。这就是为什么componentDidMount在绝大多数情况下将提取移到没有明显效果的原因。
// Before
  componentWillMount() {
    this._asyncRequest = asyncLoadData().then(
      externalData => {
        this._asyncRequest = null;
        this.setState({externalData});
      }
    );
  }

// After
  componentDidMount() {
    this._asyncRequest = asyncLoadData().then(
      externalData => {
        this._asyncRequest = null;
        this.setState({externalData});
      }
    );
  }

3.state的更新基于props
// 生命周期在组件创建时以及每次收到新道具时调用

// Before
// componentWillReceiveProps生命周期往往是误用在这方面做存在的问题。因此,该方法将被弃用。
  componentWillReceiveProps(nextProps) {
    if (this.props.currentRow !== nextProps.currentRow) {
      this.setState({
        isScrollingDown:
          nextProps.currentRow > this.props.currentRow,
      });
    }
  }
// After
  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.currentRow !== prevState.lastRow) {
      return {
        isScrollingDown:
          nextProps.currentRow > prevState.lastRow,
        lastRow: nextProps.currentRow,
      };
    }
  1. 调用外部回调
    **有时候会使用错误使用componentWillUpdate,在componentDidUpdate发生错误时,更新其他组件的状态已经“太晚了”。React可确保在用户看到更新的用户界面之前setState发生的任何调用componentDidMount和componentDidUpdate刷新。通常,最好避免像这样的级联更新,但在某些情况下它们是必需的(例如,如果在测量渲染的DOM元素之后需要定位工具提示)。

无论哪种方式,componentWillUpdate在异步模式下使用此功能都是不安全的,因为对于单个更新,外部回调可能会被多次调用。相反,componentDidUpdate应该使用生命周期,因为它保证每次更新只能调用一次**

// Before
class ExampleComponent extends React.Component {
  componentWillUpdate(nextProps, nextState) {
    if (
      this.state.someStatefulValue !==
      nextState.someStatefulValue
    ) {
      nextProps.onChange(nextState.someStatefulValue);
    }
  }
}
// After
class ExampleComponent extends React.Component {
  componentDidUpdate(prevProps, prevState) {
    if (
      this.state.someStatefulValue !==
      prevState.someStatefulValue
    ) {
      this.props.onChange(this.state.someStatefulValue);
    }
  }
}

  1. Props导致的副作用
    **像componentWillUpdate,componentWillReceiveProps可能会多次调用一次更新。
    出于这个原因,避免在此方法中引入副作用非常重要。相反,componentDidUpdate应该使用,因为它[ 保证 ]每次更新只能调用一次:
    **
// Before
class ExampleComponent extends React.Component {
  componentWillReceiveProps(nextProps) {
    if (this.props.isVisible !== nextProps.isVisible) {
      logVisibleChange(nextProps.isVisible);
    }
  }
}
// After
class ExampleComponent extends React.Component {
  componentDidUpdate(prevProps, prevState) {
    if (this.props.isVisible !== prevProps.isVisible) {
      logVisibleChange(this.props.isVisible);
    }
  }
}
  1. props更改时获取外部数据
// Before
  componentWillReceiveProps(nextProps) {
    if (nextProps.id !== this.props.id) {
      this.setState({externalData: null});
      this._loadAsyncData(nextProps.id);
    }
  }
// After
  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.id !== prevState.prevId) {
      return {
        externalData: null,
        prevId: nextProps.id,
      };
    }
    return null;
  }
  componentDidUpdate(prevProps, prevState) {
    if (this.state.externalData === null) {
      this._loadAsyncData(this.props.id);
    }
  }

  1. 在更新之前, 读取 DOM
    componentWillUpdate用于读取DOM属性。然而,对于异步渲染,“渲染”阶段生命周期(如componentWillUpdate和render)与“提交”阶段生命周期(如componentDidUpdate)之间可能会出现延迟。如果用户在这段时间内做了类似调整窗口大小的操作,则scrollHeight读取的值componentWillUpdate将会过时。
    解决这个问题的方法是使用新的“提交”阶段生命周期getSnapshotBeforeUpdate。在进行改变之前立即调用此方法(例如,在更新DOM之前)。它可以返回一个值作为参数传递给React,在其改变后立即componentDidUpdate调用它。
// Before
class ScrollingList extends React.Component {
  listRef = null;
  previousScrollHeight = null;

  componentWillUpdate(nextProps, nextState) {
    // Are we adding new items to the list?
    // Capture the current height of the list so we can adjust scroll later.
    if (this.props.list.length < nextProps.list.length) {
      this.previousScrollHeight = this.listRef.scrollHeight;
    }
  }

  componentDidUpdate(prevProps, prevState) {
    // If previousScrollHeight is set, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    if (this.previousScrollHeight !== null) {
      this.listRef.scrollTop +=
        this.listRef.scrollHeight -
        this.previousScrollHeight;
      this.previousScrollHeight = null;
    }
  }

  render() {
    return (
      <div ref={this.setListRef}>
        {/* ...contents... */}
      </div>
    );
  }

  setListRef = ref => {
    this.listRef = ref;
  };
}

// After
class ScrollingList extends React.Component {
  listRef = null;

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the current height of the list so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      return this.listRef.scrollHeight;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
      this.listRef.scrollTop +=
        this.listRef.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      <div ref={this.setListRef}>
        {/* ...contents... */}
      </div>
    );
  }

  setListRef = ref => {
    this.listRef = ref;
  };
}

Promise

Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。

Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

Promise对象有以下两个特点。

  • 对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)

  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种可能:从pending变为fulfilled和从pending变为rejected。

缺点:

  • 首先,无法取消Promise,一旦新建它就会立即执行,无法中途取消。
  • 其次,如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。
  • 第三,当处于pending状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。

**作用:**是为 Promise 实例添加状态改变时的回调函数。(then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。)

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。
因此可以采用链式写法,即then方法后面再调用另一个then方法。

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。
Promise.race方法同样是将多个Promise实例,包装成一个新的Promise实例。

用法:

Promise对象是一个构造函数,用来生成Promise实例。

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve方法和reject方法。

如果异步操作成功,则用resolve方法将Promise对象的状态变为“成功”(即从pending变为resolved);

如果异步操作失败,则用reject方法将状态变为“失败”(即从pending变为rejected)。

promise实例生成以后,可以用then方法分别指定resolve方法和reject方法的回调函数。

GitHub API

获取请求限速(Link)

curl -i https://api.github.com/users/octocat

获取授权(Link)

https://github.com/login/oauth/authorize?client_id=myclient_id&scope=user:email

获取issues

https://api.github.com/repos/HuangHongRui/Leos/issues

MYSQL

MySQL -Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)

It work for me ..

/usr/sbin/mysqld --defaults-file=/etc/mysql/my.cnf --basedir=/usr --datadir=/var/lib/mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock

Article

Ruirui_Blog

This's Important For Me..

简单记录过程..

  1. create-react-app my-app --scripts-version=react-scripts-ts 创建一个React项目
    image

  2. 弹出Webpack/ Tslint 配置: npm run eject

  3. 因为使用 Sass 所以需要在 config/webpack.config.dev.js 文件里添加些配置..
    image

  4. 添上路由. React-Router

  5. npm i --save lodash && npm install rxjs && npm install antd --save

NodeJs_Balala

正式系统学习...

先来个入门Example:

const http = require('http');
const server =http.createServer();
server.listen(8888)

server.on('request', (req, res) => {
  let response;
  const url = req.url;
  console.log(url)
  if (url === '/hello_world') {
    response = 'Hey, How Are You !'
  } else {
    response = ' Sorry, I\'Dont Know What Are You Say '
  }

  res.statusCode = 200;
  res.end(response);
})

Keng

【解决】[did you register the component correctly? For recursive components, make sure to provide the "name" option.]
image

原因: 因为注册的组件放置于 new Vue 实例之后导致,只需将组件挪到其上方,即可解决

参考地址https://cn.vuejs.org/v2/guide/components.html
关键字:注意确保在初始化根实例之前注册组件

组件

一个可以接收一个children的组件..
children 包括

  1. 当点击发送验证码时,按钮不能选中.. (且,按钮中倒数60S,时间到了,按钮释放,又可点击)
  2. 等待读取状态时,有一个提示 loading 后面的.... 将从1到10个点循环切换...直至读取成功..
  3. 每60S刷新页面.

Some tips to up

HTTP

1.有哪些常见的HTTP method?请说出区别?

GET 是最常用的向服务端发送请求资源

HEAD 与GET一样单服务器在响应中值返回首部,不返回实体的主体部分

POST起初是用来向服务器输入数据的。实际上,通常会用它来支持HTML的表单。表单中填好的数据通常会被送给服务器,然后由服务器将其发送到要去的地方。

说说TCP传输的三次握手四次挥手策略

为了准确无误地把数据送达目标处,TCP协议采用了三次握手策略。用TCP协议把数据包送出去后,TCP不会对传送 后的情况置之不理,它一定会向对方确认是否成功送达。握手过程中使用了TCP的标志:SYN和ACK。

发送端首先发送一个带SYN标志的数据包给对方。接收端收到后,回传一个带有SYN/ACK标志的数据包以示传达确认信息。
最后,发送端再回传一个带ACK标志的数据包,代表“握手”结束。
若在握手过程中某个阶段莫名中断,TCP协议会再次以相同的顺序发送相同的数据包。

2.从浏览器地址栏输入url到显示页面的步骤(以HTTP为例)

浏览器输入url,浏览器查看缓存。

1.如果缓存不存在,且资源允许缓存就向服务器请求资源。

2.如果缓存存在,且在有效期限内,则直接使用该资源。

3.如果缓存存在且已过有效期则向服务器请求资源。

说明有限期限的字段:

HTTP1.0提供Expires,值为一个绝对时间表示缓存新鲜日期
HTTP1.1增加了Cache-Control: max-age=,值为以秒为单位的最大新鲜时间
浏览器解析URL

浏览器组装一个HTTP(GET)请求报文

浏览器获取主机ip地址

浏览器缓存
本机缓存
hosts文件
路由器缓存
ISP DNS缓存
DNS递归查询
打开一个socket与目标IP地址,端口建立TCP链接,三次握手如下:

TCP/IP 核心**,即保证数据可靠传输,又要提高传输效率。

1.客户端发送一个TCP的SYN=1,Seq=X的包到服务器端口

2.服务器发回SYN=1, ACK=X+1, Seq=Y的响应包

3.客户端发送ACK=Y+1, Seq=Z
TCP链接建立后发送HTTP请求

服务器接受请求并解析,服务器检查HTTP请求头是否包含缓存验证信息如果验证缓存新鲜,返回304等对应状态码

处理程序读取完整请求并准备HTTP响应,服务器将响应报文通过TCP连接发送回浏览器

浏览器接收HTTP响应,然后根据情况选择关闭TCP连接或者保留重用,关闭TCP连接的四次握手如下:

1.主动方发送Fin=1, Ack=Z, Seq= X报文

2.被动方发送ACK=X+1, Seq=Z报文

3.被动方发送Fin=1, ACK=X, Seq=Y报文

4.主动方发送ACK=Y, Seq=X报文
浏览器检查响应状态吗:是否为1XX,3XX, 4XX, 5XX,这些情况处理与2XX不同,如果资源可缓存,进行缓存。

对响应进行解码(例如gzip压缩),根据资源类型决定如何处理(假设资源为HTML文档).

解析HTML文档,构件DOM树,下载资源,构造CSSOM树=>renderTREE,执行js脚本,这些操作没有严格的先后顺序,以下分别解释

js解析如下:

1.浏览器创建Document对象并解析HTML,将解析到的元素和文本节点添加到文档中,此时document.readystate为loading

2.HTML解析器遇到没有async和defer的script时,将他们添加到文档中,然后执行行内或外部脚本。这些脚本会同步执行,并且在脚本下载和执行时解析器会暂停。这样就可以用document.write()把文本插入到输入流中。同步脚本经常简单定义函数和注册事件处理程序,他们可以遍历和操作script和他们之前的文档内容

3.当解析器遇到设置了async属性的script时,开始下载脚本并继续解析文档。脚本会在它下载完成后尽快执行,但是解析器不会停下来等它下载。异步脚本禁止使用document.write(),它们可以访问自己script和之前的文档元素

4.当文档完成解析,document.readState变interactive
所有defer脚本会按照在文档出现的顺序执行,延迟脚本能访问完整文档树,禁止使用document.write()
浏览器在Document对象上触发DOMContentLoaded事件
此时文档完全解析完成,浏览器可能还在等待如图片等内容加载,等这些内容完成载入并且所有异步脚本完成载入和执行,document.readState变为complete,window触发load事件

显示页面(HTML解析过程中会逐步显示页面)
XML和JSON的区别?

(1).数据体积方面。

JSON相对于XML来讲,数据的体积小,传递的速度更快些。

(2).数据交互方面。

JSON与JavaScript的交互更加方便,更容易解析处理,更好的数据交互。

(3).数据描述方面。

JSON对数据的描述性比XML较差。

(4).传输速度方面。

JSON的速度要远远快于XML

如何进行网站性能优化

content方面

减少HTTP请求:合并文件、CSS精灵、inline Image
避免重定向:多余的中间访问
使Ajax可缓存
非必须组件延迟加载
未来所需组件预加载
减少DOM元素数量
将资源放到不同的域下:浏览器同时从一个域下载资源的数目有限,增加域可以提高并行下载量

Server方面

使用CDN
避免空src的img标签

css方面

将样式表放到页面顶部
不使用CSS表达式
不使用@import

Javascript方面

将脚本放到页面底部
减少DOM访问

图片方面
优化图片:根据实际颜色需要选择色深、压缩

不要在HTML中拉伸图片

Cookie方面

减小cookie大小

HTTP状态码及其含义

1XX:信息状态码

2XX:成功状态码

200 OK:请求成功,请求所希望的响应头或数据体 将随此响应返回
201 Created:
202 Accepted:
203 Non-Authoritative Information:
204 No Content:
205 Reset Content:
206 Partial Content:
3XX:重定向

300 Multiple Choices:
301 Moved Permanently:
302 Found:
303 See Other:
304 Not Modified:
305 Use Proxy:
306 (unused):
307 Temporary Redirect:
4XX:客户端错误

400 Bad Request:
401 Unauthorized:
402 Payment Required:
403 Forbidden:
404 Not Found:
405 Method Not Allowed:
406 Not Acceptable:
407 Proxy Authentication Required:
408 Request Timeout:
409 Conflict:
410 Gone:
411 Length Required:
412 Precondition Failed:
413 Request Entity Too Large:
414 Request-URI Too Long:
415 Unsupported Media Type:
416 Requested Range Not Satisfiable:
417 Expectation Failed:
5XX: 服务器错误

500 Internal Server Error:
501 Not Implemented:
502 Bad Gateway:
503 Service Unavailable:
504 Gateway Timeout:
505 HTTP Version Not Supported:
什么是Etag?

资源过期则向服务器发送Etag,
根据Etag,判断文件内容自上一次请求之后,有没有发生变化;(只有get请求会被缓存,post请求不会)

栈和队列的区别?

栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。

队列先进先出,栈先进后出。

栈只允许在表尾一端进行插入和删除,而队列只允许在表尾一端进行插入,在表头一端进行删除
栈和堆的区别?

栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。

堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。

堆(数据结构):堆可以被看成是一棵树,如:堆排序;

栈(数据结构):一种先进后出的数据结构。
快速 排序的**并实现一个快排?

快速排序”的**很简单,整个排序过程只需要三步:
  (1)在数据集之中,找一个基准点

  (2)建立两个数组,分别存储左边和右边的数组(比基准小的放在左边,大的放在右边)

  (3)利用递归进行下次比较

<script type="text/javascript"> function quickSort(arr){ if(arr.length<=1){ return arr;//如果数组只有一个数,就直接返回; } var num = Math.floor(arr.length/2);//找到中间数的索引值,如果是浮点数,则向下取整 var numValue = arr.splice(num,1);//找到中间数的值 var left = []; var right = []; for(var i=0;i

HTML

严格模式与混杂模式 —— 如何触发这两种模式,区分它们有何意义。

当浏览器厂商开始创建与标准兼容的浏览器时,他们希望确保向后兼容性。为了实现这一点,他们创建了两种呈现模式:标准模式和混杂模式
在标准模式中,浏览器以其支持的最高标准呈现页面,;
在混杂模式中,页面以一种比较宽松的向后兼容的方式显示。混杂模式通常模拟老式浏览器的行为以防止老站点无法工作。

DOCTYPE不存在或形式不正确会导致HTML和XHTML文档以混杂模式呈现

html5既然没有DTD,也就没有严格模式与宽松模式的区别,html5有相对宽松的语法,实现时,已经尽可能大的实现了向后兼容。

盒模型 —— 外边距、内边距和边框之间的关系,及IE8以下版本的浏览器中的盒模型

标准下,盒模型只包括content,ie下content+padding+border

块级元素与行内元素 —— 怎么用CSS控制它们、以及如何合理的使用它们

block可设置长宽,在文档流中独占一行从上往下排列。
行内元素不可设置长宽,内容撑开。margin上下无效,padding上下有效但不占空间,其他有效。

浮动元素 ——怎么使用它们、它们有什么问题以及怎么解决这些问题

用于导航条,图片文字围绕效果,或者其他需要浮动的元素,
子元素浮动不会占用正常文本流的位置,所以当子元素全部浮动会导致父元素高度塌陷。

HTML与XHTML ——二者有什么区别,你觉得应该使用哪一个并说出理由。

请解释一下什么是语义化的HTML。语义化HTML的优点

根据内容的结构化(内容语义化),选择合适的标签(代码语义化)便于开发者阅读和写出更优雅的代码的同时让浏览器的爬虫和机器很好地解析。

所有的标记都必须要有一个相应的结束标记

所有标签的元素和属性的名字都必须使用小写

所有的XML标记都必须合理嵌套

所有的属性必须用引号""括起来

把所有<和&特殊符号用编码表示

给所有属性赋一个值

不要在注释内容中使“--”

图片必须有说明文字

行内元素有哪些?块级元素有哪些? 空(void)元素有那些? 首先:CSS规范规定,每个元素都有display属性,确定该元素的类型,每个元素都有默认的display值,如div的display默认值为“block”,则为“块级”元素;span默认display属性值为“inline”,是“行内”元素。

行内元素有:a b span img input select strong(强调的语气)

块级元素有:div ul ol li dl dt dd h1 h2 h3 h4…p

空元素:

常见的:


鲜为人知的是:
介绍一下你对浏览器内核的理解?

主要分成两部分:渲染引擎(layout engineer或Rendering Engine)和JS引擎。

渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入CSS等),以及计算网页的显示方式.

JS引擎则:解析和执行javascript来实现网页的动态效果。

常见的浏览器内核有哪些?

Trident内核:IE,MaxThon,TT,The World,360,搜狗浏览器等。[又称MSHTML]
Gecko内核:Netscape6及以上版本,FF,MozillaSuite/SeaMonkey等
Blink内核:Opera7及以上。 [Opera内核原为:Presto,现为:Blink;]
Webkit内核:Safari,Chrome等。 [ Chrome的:Blink(WebKit的分支)]
html5有哪些新特性、移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?

HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。 绘画 canvas; 用于媒介回放的 video 和 audio 元素; 本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失; sessionStorage 的数据在浏览器关闭后自动删除; 语意化更好的内容元素,比如 article、footer、header、nav、section; 表单控件,calendar、date、time、email、url、search;

新的技术webworker, websocket, Geolocation;

移除的元素: 纯表现的元素:basefont,big,center,font, s,strike,tt,u; 对可用性产生负面影响的元素:frame,frameset,noframes;

如何区分HTML5: DOCTYPE声明\新增的结构元素\功能元素

简述一下你对HTML语义化的理解?

html语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析; 即使在没有样式CSS情况下也以一种文档格式显示,并且是容易阅读的; 搜索引擎的爬虫也依赖于HTML标记来确定上下文和各个关键字的权重,利于SEO; 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。

HTML5的离线储存怎么使用,工作原理能不能解释一下?

在用户没有与因特网连接时,可以正常访问站点或应用,在用户与因特网连接时,更新用户机器上的缓存文件。 原理:HTML5的离线存储是基于一个新建的.appcache文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示。

请描述一下 cookies,sessionStorage 和 localStorage 的区别?

cookie是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。 cookie数据始终在同源的http请求中携带(即使不需要),记会在浏览器和服务器间来回传递。 sessionStorage和localStorage不会自动把数据发给服务器,仅在本地保存。

存储大小: cookie数据大小不能超过4k。 sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大。

iframe有那些缺点?

iframe会阻塞主页面的Onload事件;
搜索引擎的检索程序无法解读这种页面,不利于SEO;
iframe和主页面共享连接池,而浏览器对相同域的连接有限制,所以会影响页面的并行加载。
使用iframe之前需要考虑这两个缺点。如果需要使用iframe,最好是通过javascript 动态给iframe添加src属性值,这样可以绕开以上两个问题。
Label的作用是什么?是怎么用的?

label标签来定义表单控制间的关系,当用户选择该标签时,浏览器会自动将焦点转到和标签相关的表单控件上。

title与h1的区别、b与strong的区别、i与em的区别?

title属性没有明确意义只表示是个标题,H1则表示层次明确的标题,对页面信息的抓取也有很大的影响; strong是标明重点内容,有语气加强的含义,使用阅读设备阅读网络时:会重读,而是展示强调内容。 i内容展示为斜体,em表示强调的文本; Physical Style Elements -- 自然样式标签 b, i, u, s, pre Semantic Style Elements -- 语义样式标签 strong, em, ins, del, code

CSS部分

CSS优化、提高性能的方法有哪些?

关键选择器(key selector)。选择器的最后面的部分为关键选择器(即用来匹配目标元素的部分);
如果规则拥有 ID 选择器作为其关键选择器,则不要为规则增加标签。过滤掉无关的规则(这样样式系统就不会浪费时间去匹配它们了);
提取项目的通用公有样式,增强可复用性,按模块编写组件;增强项目的协同开发性、可维护性和可扩展性;
使用预处理工具或构建工具(gulp对css进行语法检查、自动补前缀、打包压缩、自动优雅降级);

CSS优先级算法如何计算?

优先级就近原则,同权重情况下样式定义最近者为准;
载入样式以最后载入的定位为准;
优先级为: !important > id > class > tag 比 内联优先级高

CSS3新增伪类有那些?

举例: p:first-of-type 选择属于其父元素的首个

元素的每个

元素。 p:last-of-type 选择属于其父元素的最后

元素的每个

元素。 p:only-of-type 选择属于其父元素唯一的

元素的每个

元素。 p:only-child 选择属于其父元素的唯一子元素的每个

元素。 p:nth-child(2) 选择属于其父元素的第二个子元素的每个

元素。

:after 在元素之前添加内容,也可以用来做清除浮动。 :before 在元素之后添加内容 :enabled :disabled 控制表单控件的禁用状态。 :checked 单选框或复选框被选中。

CSS3有哪些新特性?

新增各种CSS选择器 (: not(.input):所有 class 不是“input”的节点) 圆角 (border-radius:8px) 多列布局 (multi-column layout) 阴影和反射 (Shadow\Reflect) 文字特效 (text-shadow、) 文字渲染 (Text-decoration) 线性渐变 (gradient) 旋转 (transform) 增加了旋转,缩放,定位,倾斜,动画,多背景 transform:\scale(0.85,0.90)\ translate(0px,-30px)\ skew(-9deg,0deg)\Animation:

CSS选择器有哪些

基础选择器
组合选择器
属性选择器
伪类选择器
伪元素选择器
css sprite是什么,有什么优缺点

概念:将多个小图片拼接到一个图片中。通过background-position和元素尺寸调节需要显示的背景图案。

优点:
减少HTTP请求数,极大地提高页面加载速度
增加图片信息重复度,提高压缩比,减少图片大小
更换风格方便,只需在一张或几张图片上修改颜色或样式即可实现

缺点:
图片合并麻烦
维护麻烦,修改一个图片可能需要从新布局整个图片,样式

display: none;与visibility: hidden;的区别

都能让元素从视图消失,但是visibility任占用位置。

display:none,为非继承属性;visibility为继承属性

3.修改常规流中元素的display通常会造成文档重排。修改visibility属性只会造成本元素的重绘。

4.读屏器不会读取display: none;元素内容;visibility: hidden会读取元素内容

css hack原理及常用hack

原理:利用不同浏览器对CSS的支持和解析结果不一样编写针对特定浏览器样式。
常见的hack有

1)属性hack。

2)选择器hack。

3)IE条件注释

IE条件注释:适用于[IE5, IE9]常见格式如下

选择器hack:不同浏览器对选择器的支持不一样

属性hack:不同浏览器解析bug或方法

specified value,computed value,used value计算方法

specified value: 计算方法如下:

如果样式表设置了一个值,使用这个值
如果没有设置值,这个属性是继承属性,从父元素继承
如果没设置,并且不是继承属性,使用css规范指定的初始值
computed value 将相对值属性转换为绝对值属性

used value:属性计算后的最终值,对于大多数属性可以通过window.getComputedStyle获得,尺寸值单位为像素。以下属性依赖于布局,

link与@import的区别

link是html标签中引入样式,@import是css中引入样式

link最大限度支持并行下载,@import过多嵌套导致串行下载,出现FOUC

link的rel属性提供可选样式表

浏览器对link支持早于@import,可以使用@import对老浏览器隐藏样式

@import必须在样式规则之前,可以在css文件中引用其他文件

总体来说:link优于@import

display: block;和display: inline;的区别

block元素特点:

处于常规流中时,如果width没有设置,会自动填充满父容器

在没有设置高度的情况下会扩展高度以包含常规流中的子元素

处于常规流中时布局时在前后元素位置之间(独占一个水平空间)

忽略vertical-align

inline元素特点

width/height属性对非替换行内元素无效,宽度由元素内容决定

浮动或绝对定位时会转换为block

margin无用,padding有用但不占用垂直方向位置

CSS有哪些继承属性

  • font
  • word-break
  • letter-spacing
  • text-align
  • text-rendering
  • word-spacing
  • white-space
  • text-indent
  • text-transform
  • text-shadow
  • line-height
  • color
  • visibility
  • cursor
    清浮动的方法

容器元素闭合标签前添加额外元素并设置clear: both
父元素触发块级格式化上下文(见块级可视化上下文部分)
设置容器元素伪元素进行清理推荐的清理浮动方法(最优解)
浮动元素如何居中?

因为浮动元素宽度是由内容撑开,先让浮动元素position:relative;右移动50%;然后让其子元素左移50%;

什么是FOUC?如何避免

Flash Of Unstyled Content:浏览器使用默认样式显示文档,用户样式加载渲染之后再从新显示文档,造成页面闪烁。解决方法:把样式表放到文档的head

如何创建块级格式化上下文(block formatting context),BFC有什么用

创建规则:

  1. 根元素
  2. 浮动元素(float不是none)
  3. 绝对定位元素(position取值为absolute或fixed)
  4. display取值为inline-block,table-cell, table-caption,flex, inline-flex之一的元素
  5. overflow不是visible的元素
    作用:

1.内部的Box会在垂直方向,一个接一个地放置。
2.Box垂直方向的距离由margin决定。属于同一个BFC的两个相邻Box的margin会发生重叠
3.BFC的区域不会与float box重叠。
4.BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素。反之也如此。
5.计算BFC的高度时,浮动元素也参与计算
外边距折叠(collapsing margins)

毗邻的两个或多个margin会合并成一个margin,叫做外边距折叠。规则如下:

两个或多个毗邻的普通流中的块元素垂直方向上的margin会折叠
浮动元素/inline-block元素/绝对定位元素的margin不会和垂直方向上的其他元素的margin折叠
创建了块级格式化上下文的元素,不会和它的子元素发生margin折叠
元素自身的margin-bottom和margin-top相邻时也会折叠
如何确定包含块?

确定包含块的过程完全依赖于这个包含块的 position 属性:

如果 position 属性是 static 或 relative 的话,包含块就是由它的最近的祖先块元素(比如说inline-block, block 或 list-item元素)或格式化上下文(比如说 a table container, flex container, grid container, or the block container itself)的内容区的边缘组成的。
如果 position 属性是 absolute 的话,包含块就是由它的最近的 position 的值不是 static (fixed, absolute, relative, or sticky)的祖先元素的内边距区的边缘组成的。
如果 position 属性是 fixed 的话,包含块就是由 viewport (in the case of continuous media) or the page area (in the case of paged media) 组成的。
js部分

XSS原理及防范

Xss(cross-site scripting)攻击指的是攻击者往Web页面里插入恶意 html标签或者javascript代码。比如:攻击者在论坛中放一个

看似安全的链接,骗取用户点击后,窃取cookie中的用户私密信息;或者攻击者在论坛中加一个恶意表单,

当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为的信任站点。

首先代码里对用户输入的地方和变量都需要仔细检查长度和对”<”,”>”,”;”,”’”等字符做过滤;其次任何内容写到页面之前都必须加以encode,避免不小心把html tag 弄出来。这一个层面做好,至少可以堵住超过一半的XSS 攻击。

CSRF有什么区别吗?

跨站请求伪造。其原理是攻击者构造网站后台某个功能接口的请求地址,诱导用户去点击或者用特殊方法让该请求地址自动加载。用户在登录状态下这个请求被服务端接收后会被误以为是用户合法的操作。对于 GET 形式的接口地址可轻易被攻击,对于 POST 形式的接口地址也不是百分百安全,攻击者可诱导用户进入带 Form 表单可用POST方式提交参数的页面。

于是采用了anti-csrf-token的方案。 具体方案如下:

服务端在收到路由请求时,生成一个随机数,在渲染请求页面时把随机数埋入页面(一般埋入 form 表单内,)
服务端设置setCookie,把该随机数作为cookie或者session种入用户浏览器
当用户发送 GET 或者 POST 请求时带上_csrf_token参数(对于 Form 表单直接提交即可,因为会自动把当前表单内所有的 input 提交给后台,包括_csrf_token)
后台在接受到请求后解析请求的cookie获取_csrf_token的值,然后和用户请求提交的_csrf_token做个比较,如果相等表示请求是合法的。

为什么HTTPS安全

因为网络请求需要中间有很多的服务器路由器的转发。中间的节点都可能篡改信息,而如果使用HTTPS,密钥在你和终点站才有。https之所以比http安全,是因为他利用ssl/tls协议传输。它包含证书,卸载,流量转发,负载均衡,页面适配,浏览器适配,refer传递等。保障了传输过程的安全性

Javascript垃圾回收方法

标记清除(mark and sweep)

这是JavaScript最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。

垃圾回收器会在运行的时候给存储在内存
引用计数(reference counting)

在低版本IE中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个 变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加1,如果该变量的值变成了另外一个,则这个值得引用次数减1,当这个值的引用次数变为0的时 候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为0的值占用的空间。
谈谈性能优化问题

代码层面:避免使用css表达式,避免使用高级选择器,通配选择器。

少用全局变量,
缓存DOM节点查找的结果,
避免使用CSS Expression
避免全局查询
多个变量声明合并
避免图片和iFrame等的空Src。空Src会重新加载当前页面,影响速度和效率
缓存利用:缓存Ajax,使用CDN,使用外部js和css文件以便缓存,添加Expires头,服务端配置Etag,减少DNS查找等

请求数量:合并样式和脚本,使用css图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载。

请求带宽:压缩文件,开启GZIP,

DOM元素e的e.getAttribute(propName)和e.propName有什么区别和联系?

e.getAttribute(),是标准DOM操作文档元素属性的方法,具有通用性可在任意文档上使用,返回元素在源文件中设置的属性。e.propName通常是在HTML文档中访问特定元素的特性。
offsetWidth/offsetHeight,clientWidth/clientHeight与scrollWidth/scrollHeight的区别

offsetWidth/offsetHeight返回值包含content + padding + border,效果与e.getBoundingClientRect()相同
clientWidth/clientHeight返回值只包含content + padding,不包含滚动条
scrollWidth/scrollHeight返回值包含content + padding + 溢出内容的尺寸
创建ajax过程

(1)创建XMLHttpRequest对象,也就是创建一个异步调用对象.

(2)创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.

(3)设置响应HTTP请求状态变化的函数.

(4)发送HTTP请求.

(5)获取异步调用返回的数据.

(6)使用JavaScript和DOM实现局部刷新.
XMLHttpRequest通用属性和方法

readyState:表示请求状态的整数,取值:

UNSENT(0):对象已创建
OPENED(1):open()成功调用,在这个状态下,可以为xhr设置请求头,或者使用send()发送请求
HEADERS_RECEIVED(2):所有重定向已经自动完成访问,并且最终响应的HTTP头已经收到
LOADING(3):响应体正在接收
DONE(4):数据传输完成或者传输产生错误
onreadystatechange:readyState改变时调用的函数

status:服务器返回的HTTP状态码(如,200, 404)

statusText:服务器返回的HTTP状态信息(如,OK,No Content)

responseText:作为字符串形式的来自服务器的完整响应

responseXML: Document对象,表示服务器的响应解析成的XML文档

abort():取消异步HTTP请求

getAllResponseHeaders(): 返回一个字符串,包含响应中服务器发送的全部HTTP报头。每个报头都是一个用冒号分隔开的名/值对,并且使用一个回车/换行来分隔报头行

send(body):对服务器请求进行初始化。参数body包含请求的主体部分,对于POST请求为键值对字符串;对于GET请求,为null

setRequestHeader(name, value):设置HTTP报头

focus/blur与focusin/focusout的区别与联系

focus/blur不冒泡,focusin/focusout冒泡

可获得焦点的元素

window
链接被点击或键盘操作
表单空间被点击或键盘操作
设置tabindex属性的元素被点击或键盘操作
mouseover/mouseout与mouseenter/mouseleave的区别与联系

  • mouseover/mouseout是冒泡事件;mouseenter/mouseleave不冒泡。需要为多个元素监听鼠标移入/出事件时,推荐mouseover/mouseout托管,提高性能

  • mouseover/mouseout是标准事件,所有浏览器都支持;mouseenter/mouseleave是IE5.5引入的特有事件后来被DOM3标准采纳,现代标准浏览器也支持
    sessionStorage,localStorage,cookie区别

都会在浏览器端保存,有大小限制,同源限制

cookie会在请求时发送到服务器,作为会话标识,服务器可修改cookie;web storage不会发送到服务器,cookie有path概念,子路径可以访问父路径cookie,父路径不能访问子路径cookie

有效期:cookie在设置的有效期内有效,默认为浏览器关闭;sessionStorage在窗口关闭前有效,localStorage长期有效,直到用户删除

共享:sessionStorage不能共享,localStorage在同源文档之间共享,cookie在同源且符合path规则的文档之间共享

localStorage的修改会促发其他文档窗口的update事件

浏览器不能保存超过300个cookie,单个服务器不能超过20个,每个cookie不能超过4k。web storage大小支持能达到5M

javascript跨域通信

同源:两个文档同源需满足

  1. 协议相同
  2. 域名相同
  3. 端口相同
    javascript有哪几种数据类型

六种基本数据类型

1.undefined
2.null
3.string
4.boolean
5.number
6.symbol(ES6)

一种引用类型

Object
什么闭包,闭包有什么用

闭包

「函数」和「函数内部能访问到的变量」(也叫环境)的总和,就是一个闭包

作用

管理私有变量和私有方法,将对变量(状态)的变化封装在安全的环境中
将代码封装成一个闭包形式,等待时机成熟的时候再使用,比如实现柯里化和反柯里化
需要注意的,由于闭包内的部分资源无法自动释放,容易造成内存泄露
闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。
javascript有哪几种方法定义函数

函数声明表达式
function操作符
Function 构造函数
ES6:arrow function
客户端存储localStorage和sessionStorage

localStorage有效期为永久,sessionStorage有效期为顶层窗口关闭前
同源文档可以读取并修改localStorage数据,sessionStorage只允许同一个窗口下的文档访问,如通过iframe引入的同源文档。
Storage对象通常被当做普通javascript对象使用:通过设置属性来存取字符串值,也可以通过setItem(key, value)设置,getItem(key)读取,removeItem(key)删除,clear()删除所有数据,length表示已存储的数据项数目,key(index)返回对应索引的key
cookie及其操作

cookie是web浏览器存储的少量数据,最早设计为服务器端使用,作为HTTP协议的扩展实现。cookie数据会自动在浏览器和服务器之间传输。
通过读写cookie检测是否支持
cookie属性有名,值,max-age,path, domain,secure;
cookie默认有效期为浏览器会话,一旦用户关闭浏览器,数据就丢失,通过设置max-age=seconds属性告诉浏览器cookie有效期
cookie作用域通过文档源和文档路径来确定,通过path和domain进行配置,web页面同目录或子目录文档都可访问
通过cookie保存数据的方法为:为document.cookie设置一个符合目标的字符串如下
读取document.cookie获得'; '分隔的字符串,key=value,解析得到结果
javascript有哪些方法定义对象

对象字面量: var obj = {};
构造函数: var obj = new Object();
Object.create(): var obj = Object.create(Object.prototype);
编写javascript深度克隆函数deepClone

function deepClone(obj) {
var _toString = Object.prototype.toString;

// null, undefined, non-object, function
if (!obj || typeof obj !== 'object') {
    return obj;
}

// DOM Node
if (obj.nodeType && 'cloneNode' in obj) {
    return obj.cloneNode(true);
}

// Date
if (_toString.call(obj) === '[object Date]') {
    return new Date(obj.getTime());
}

// RegExp
if (_toString.call(obj) === '[object RegExp]') {
    var flags = [];
    if (obj.global) { flags.push('g'); }
    if (obj.multiline) { flags.push('m'); }
    if (obj.ignoreCase) { flags.push('i'); }

    return new RegExp(obj.source, flags.join(''));
}

var result = Array.isArray(obj) ? [] :
    obj.constructor ? new obj.constructor() : {};

for (var key in obj ) {
    result[key] = deepClone(obj[key]);
}

return result;

}

function A() {
this.a = a;
}

var a = {
name: 'qiu',
birth: new Date(),
pattern: /qiu/gim,
container: document.body,
hobbys: ['book', new Date(), /aaa/gim, 111]
};

var c = new A();
var b = deepClone(c);
console.log(c.a === b.a);
console.log(c, b);
完成一个函数,接受数组作为参数,数组元素为整数或者数组,数组元素包含整数或数组,函数返回扁平化后的数组

如:[1, [2, [ [3, 4], 5], 6]] => [1, 2, 3, 4, 5, 6]

var data = [1, [2, [ [3, 4], 5], 6]];

function flat(data, result) {
    var i, d, len;
    for (i = 0, len = data.length; i < len; ++i) {
        d = data[i];
        if (typeof d === 'number') {
            result.push(d);
        } else {
            flat(d, result);
        }
    }
}

var result = [];
flat(data, result);

console.log(result);

如何判断一个对象是否为数组

function isArray(arg) {
if (typeof arg === 'object') {
return Object.prototype.toString.call(arg) === '[object Array]';
}
return false;
}
事件监听器兼容

参数个数不相同,这个最直观,addEventListener有三个参数,attachEvent只有两个,attachEvent添加的事件处理程序只能发生在冒泡阶段,addEventListener第三个参数可以决定添加的事件处理程序是在捕获阶段还是冒泡阶段处理(我们一般为了浏览器兼容性都设置为冒泡阶段)

第一个参数意义不同,addEventListener第一个参数是事件类型(比如click,load),而attachEvent第一个参数指明的是事件处理函数名称(onclick,onload)

事件处理程序的作用域不相同,addEventListener的作用域是元素本身,this是指的触发元素,而attachEvent事件处理程序会在全局变量内运行,this是window,所以刚才例子才会返回undefined,而不是元素id

为一个事件添加多个事件处理程序时,执行顺序不同,addEventListener添加会按照添加顺序执行,而attachEvent添加多个事件处理程序时顺序无规律(添加的方法少的时候大多是按添加顺序的反顺序执行的,但是添加的多了就无规律了),所以添加多个的时候,不依赖执行顺序的还好,若是依赖于函数执行顺序,最好自己处理,不要指望浏览器

function addEvent(node, type, handler) {
if (!node) return false;
if (node.addEventListener) {
node.addEventListener(type, handler, false);
return true;
}
else if (node.attachEvent) {
node['e' + type + handler] = handler;
node[type + handler] = function() {
node'e' + type + handler;
};
node.attachEvent('on' + type, node[type + handler]);
return true;
}
return false;
}
function removeEvent(node, type, handler) {
if (!node) return false;
if (node.removeEventListener) {
node.removeEventListener(type, handler, false);
return true;
}
else if (node.detachEvent) {
node.detachEvent('on' + type, node[type + handler]);
node[type + handler] = null;
}
return false;
}
如何判断一个对象是否为函数

function isFunction(arg) {
if (arg) {
if (typeof (/./) !== 'function') {
return typeof arg === 'function';
} else {
return Object.prototype.toString.call(arg) === '[object Function]';
}
} // end if
return false;
}
编写一个函数接受url中query string为参数,返回解析后的Object,query string使用application/x-www-form-urlencoded编码

function parseQuery(query) {
var result = {};

// 如果不是字符串返回空对象
if (typeof query !== 'string') {
    return result;
}

// 去掉字符串开头可能带的?
if (query.charAt(0) === '?') {
    query = query.substring(1);
}

var pairs = query.split('&');
var pair;
var key, value;
var i, len;

for (i = 0, len = pairs.length; i < len; ++i) {
    pair = pairs[i].split('=');
    // application/x-www-form-urlencoded编码会将' '转换为+
    key = decodeURIComponent(pair[0]).replace(/\+/g, ' ');
    value = decodeURIComponent(pair[1]).replace(/\+/g, ' ');

    // 如果是新key,直接添加
    if (!(key in result)) {
        result[key] = value;
    }
    // 如果key已经出现一次以上,直接向数组添加value
    else if (isArray(result[key])) {
        result[key].push(value);
    }
    // key第二次出现,将结果改为数组
    else {
        var arr = [result[key]];
        arr.push(value);
        result[key] = arr;
    } // end if-else
} // end for

return result;

}

function isArray(arg) {
if (arg && typeof arg === 'object') {
return Object.prototype.toString.call(arg) === '[object Array]';
}
return false;
}
console.log(parseQuery('sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8'))
完成函数getViewportSize返回指定窗口的视口尺寸

function getViewportSize(w) {
w = w || window;

// IE9及标准浏览器中可使用此标准方法
if ('innerHeight' in w) {
    return {
        width: w.innerWidth,
        height: w.innerHeight
    };
}

var d = w.document;
// IE 8及以下浏览器在标准模式下
if (document.compatMode === 'CSS1Compat') {
    return {
        width: d.documentElement.clientWidth,
        height: d.documentElement.clientHeight
    };
}

// IE8及以下浏览器在怪癖模式下
return {
    width: d.body.clientWidth,
    height: d.body.clientHeight
};

}
完成函数getScrollOffset返回窗口滚动条偏移量

function getScrollOffset(w) {
w = w || window;
// 如果是标准浏览器
if (w.pageXOffset != null) {
return {
x: w.pageXOffset,
y: w.pageYOffset
};
}

// 老版本IE,根据兼容性不同访问不同元素
var d = w.document;
if (d.compatMode === 'CSS1Compat') {
    return {
        x: d.documentElement.scrollLeft,
        y: d.documentElement.scrollTop
    }
}

return {
    x: d.body.scrollLeft,
    y: d.body.scrollTop
};

}
用ES6实现
const obj={a:1,b:2,c:3};

foo(obj,["a","c"]);

//输出 {a:1,c:3}

const foo=(obj,arr)=>{

var res=arr.reduce((res,cur)=>{
    res[cur]=obj[cur]
    return res
},{})
console.log(res)
return res

}
const obj={a:1,b:2,c:3};
foo(obj,["a","c"]);
判断两个字符串是否匹配

function isMatch(str1, str2) {
var str1arr=[...str1].sort()
var str2arr=[...str2].sort()
return str1arr.every((ele,i)=>{
return str2arr[i]==ele
})
}

jquery插件写法

(function( $ ){
$.fn.myPlugin = function() {

    // 没有必要再作 $(this) ,因为"this"已经是 jQuery 对象了
    // $(this) 与 $($('#element')) 是相同的
       
    this.fadeIn('normal', function(){
        // 在这里 this 关键字指向 DOM 元素
    });		    		    
};  		

})( jQuery );

$('#element').myPlugin();
说说你对闭包的理解

闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。
在js中,函数与该函数的上下文即闭包,只有函数才会产生作用域的概念

概念

文档对象模型 (DOM) 是 HTML 和 XML 文档的编程接口。
element.insertAdjacentElement(position, element);
insertAdjacentElement

DOM结构 —— 两个节点之间可能存在哪些关系以及如何在节点之间任意移动。

兄弟与父子
element.insertAdjanceElement()
element.insertAdjanceHTML()
指定的文本解析为HTML或XML,并将结果节点插入到DOM树中的指定位置。它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素。这避免了额外的序列化步骤,使其比直接innerHTML操作更快。

DOM操作 ——如何添加、移除、移动、复制、创建和查找节点等。

node.appendChild()
node.removeChild()

var newnode=node.cloneNode(true); //true:深克隆(子节点克隆)
createElement()

事件 —— 如何使用事件,以及IE和标准DOM事件模型之间存在的差别

如果要对许多元素绑定事件最好,采用事件委托在其父元素上绑定。
Api不同 IE下是attachEvent(),标准上面是addEventLister()
IE指支持事件冒泡

XMLHttpRequest —— 这是什么、怎样完整地执行一次GET请求、怎样检测错误。

XMLHttpRequest是js内置发送网络请求的,

//GET
var request=new XMLHttpRequest();
request.onreadystatechange=function(){
if(this.readyState===4){ //完成进度
if(this.status>=200&&this.status<400){
//success
var data=JSON.parse(this.responseText)
}else{
console.log(this.status)
}
this.onerror(function(error){
console.log(error)
})
}
}
request.send();
request = null;

//post
var request = new XMLHttpRequest();
request.open('POST', '/my/url', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.send(data);
常见布局

固定宽度

弹性布局

响应式布局

一栏布局
一栏布局(通栏)
要点 max-width:1000px;
水平居中 margin-left:auto;margin-right:auto;

双栏布局
一列固定宽度,另外一列自适应宽度
浮动加margin

三列布局
两侧两列固定宽度,中间列自适应宽度

float:left,float:right;margin:-wdith (main要在中间)

html5有哪些新特性、移除了那些元素?如何处理HTML5新标签的浏览器兼容问题?如何区分 HTML 和 HTML5?

HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加。

拖拽释放(Drag and drop) API

语义化更好的内容标签(header,nav,footer,aside,article,section)

音频、视频API(audio,video)

画布(Canvas) API

地理(Geolocation) API

本地离线存储 localStorage 长期存储数据,浏览器关闭后数据不丢失;

sessionStorage 的数据在浏览器关闭后自动删除

表单控件,calendar、date、time、email、url、search

新的技术webworker, websocket, Geolocation

移除的元素

纯表现的元素:basefont,big,center,font, s,strike,tt,u;

对可用性产生负面影响的元素:frame,frameset,noframes;

支持HTML5新标签:

IE8/IE7/IE6支持通过document.createElement方法产生的标签,

可以利用这一特性让这些浏览器支持HTML5新标签,

当然最好的方式是直接使用成熟的框架、使用最多的是html5shim框架
cookie, session, localStrorage, sessionStorage 区别, 具体怎么用代码去操作?

Cookie 是浏览器访问服务器后,服务器传给浏览器的一段数据。

浏览器需要保存这段数据,不得轻易删除。

此后每次浏览器访问该服务器,都必须带上这段数据。

Cookie 一般有两个作用。

第一个作用是识别用户身份。

第二个作用是记录历史。

session

当一个用户打开淘宝登录后,刷新浏览器仍然展示登录状态。服务器如何分辨这次发起请求的用户是刚才登录过的用户呢?

这里就使用了session保存状态。用户在输入用户名密码提交给服务端,服务端验证通过后会创建一个session用于记录用户的相关信息,这个 session 可保存在服务器内存中,也可保存在数据库中

创建session后,会把关联的session_id 通过setCookie 添加到http响应头部中。
浏览器在加载页面时发现响应头部有 set-cookie字段,就把这个cookie 种到浏览器指定域名下。
当下次刷新页面时,发送的请求会带上这条cookie, 服务端在接收到后根据这个session_id来识别用户。
cookie 是存储在浏览器里的一小段「数据」,而session是一种让服务器能识别某个用户的「机制」,session 在实现的过程中需要使用cookie。 二者不是同一维度的东西。

数组去重

方法一:
var arr1=[1,2,3,2,1,2];
function repeat1(arr){
for(var i=0,arr2=[];i<arr.length;i++){
if(arr2.indexOf(arr[i])==-1){
arr2.push(arr[i]);
}
}//(遍历结束)
return arr2;
}

方法二:hash
function repeat2(arr){
//遍历arr中每个元素,同时声明hash
for(var i=0,hash={};i<arr.length;i++){
//hash中是否包含当前元素值的建
//如果不包含,就hash添加一个新元素,以当前元素值为key,value默认为1
if(hash[arr[i]]===undefined){
hash[arr[i]]=1;
}
}

return Objext.keys(hash);

}

方法三:
function repeat3(arr){
return Array.from(new Set(arr))
}
console.log(repeat3(arr1));

方法4:

function repeat4(arr){
const set=new Map();
return arr.fliter((e)=>!set.has(e)&&set.add(e,1)
)
}
统计字符串中每种字符出现的次数,出现次数最多的是? 出现?次

var str="helloworld";
方法一:用hash
for(var i=0,hash={};i<str.length;i++){
if(hash[str[i]]){
hash[str[i]]++
}else{
hash[str[i]]=1;
}
}
console.dir(hash);
方法二:用正则
var arr=str.split("")
.sort()
.join("")
.match(/([a-z])\1*/g)
.sort(function(a,b){
return b.length-a.length; })
console.log("出现最多的是: "+arr[0][0]
+"共"+arr[0].length+"次");
var hash={};
arr.forEach(function(val){
hash[val[0]]=val.length;
});
console.dir(hash);
数组降维

for(var r=0,arr2=[];r<arr.length;r++){
arr2=arr2.concat(arr[r]);
}
console.dir(arr2);
var arr2=[].concat.apply([],arr);
console.dir(arr2);
判断一个对象是不是数组类型,有五种方法:

(1) typeof 无法判断 只能判断原始类型的值和函数
(2)isPrototypeOf 判断父及对象 可检查整个原型链 //可能继承自数组
console.log(Array.prototype.isPrototypeOf([])?"是数组":"不是数组");
console.log(Array.prototype.isPrototypeOf({})?"是数组":"不是数组");
console.log(Array.prototype.isPrototypeOf(function(){})?"是数组":"不是数组");�
(3)constructor 检查指定对象的构造函数 可检查整个原型链 //可能继承自数组
var father={};
var son={};
father.proto=Array.prototype;
son.proto=father;
console.log(son.contructor==Array?"是数组":"不是数组")
console.log({}.contructor==Array?"是数组":"不是数组");
console.log(function(){}.contructor==Array?"是数组":"不是数组");�
(4)instanceof 检查一个对象是否是制定构造函数的实例 可检查整个原型链 //可能继承自数组
var father={};
var son={};
father.proto=Array.prototype;
son.proto=father;
console.log(son instanceof Array?"是数组":"不是数组");
console.log({} instanceof Array?"是数组":"不是数组");
console.log(function(){} instanceof Array?"是数组":"不是数组");
(5)强行用要检查的对象,调用原始的toString方法 不检查整个原型链
//[object class]: class-Array Date Object
//只能检查最初就是数组创建的对象。
console.log(Object.prototype.toString.call([])=="[object Array]"?"是数组":"不是数组");
console.log(Object.prototype.toString.call({}));
console.log(Object.prototype.toString.call(function(){}));
console.log(Object.prototype.toString.call(/\d/));
var father={};
var son={};
father.proto=Array.prototype;
son.proto=father;
console.log(Object.prototype.toString.call(son)=="[object Array]"?"是数组":"不是数组");//不是
//结论: 对象一旦创建,class属性就无法修改
//修改继承关系,也无法修改class属性
(6) Array.isArray(obj) 不检查整个原型链
console.log(Array.isArray([]));
console.log(Array.isArray({}));
//如果浏览器不支持isArray
if(Array.prototype.isArray===undefined){//if(!Array.isArray)
//给?添加isArray方法
Array.prototype.isArray=function(arg){
//强行调用原始toString方法,和"[object Array]"比较
return Object.prototype.toString.call(arg)
=="[object Array]"?"是数组":"不是数组";
}
}
自定义Object.create()——手写

Object.create=function(father,props){
/*使用setPrototypeOf方法
var o={};//1. 创建空对象
Object.setPrototypeOf(o,father);//2. 继承father
*/
/*不使用setPrototypeOf方法
function Constructor(){}
Constructor.prototype=father;
var o=new Constructor();
*/
Object.defineProperties(o,props);//3. 定义新属性
return o;
}
如果浏览器不支持every属性,every的实现原理

Object.clone=function(obj){//深克隆
if(typeof(obj)=="object"){//如果obj是对象
var o=//有必要区分数组和普通对象
Object.prototype.toString.call(obj)=="[object Array]"?[]:{};
for(var key in obj){//遍历obj的自有属性
//如果key是obj的自有属性
if(obj.hasOwnProperty(key)){
o[key]=arguments.callee(obj[key]);//arguments.callee调的是当前的Object.clone函数
}
}
return o;
}else{//如果obj是原始类型的值,就直接返回副本
return obj;
}
}
如果浏览器不支持every属性,every的实现原理

if(Array.prototype.every===undefined){
Array.prototype.every=function(fun){
//遍历当前数组中每个元素
for(var i=0;i<this.length;i++){
if(this[i]!==undefined){
//调用fun,依次传入当前元素值,位置i,当前数组作为参数 ,将返回值,保存在变量r中
var r=fun(this[i],i,this);
if(r==false){//如果r为false
return false;//返回false
}
}
}//(遍历结束)
return true;//返回true
}
}
如果浏览器不支持some属性,some的实现原理

if(Array.prototype.some===undefined){
Array.prototype.some=function(fun){
for(var i=0;i<this.length;i++){
if(this[i]!==unefined){
var r=fun(this[i],i,this);
if(r==true){ return true; }
}
}
return false;
}
}
浏览器不支持map属性,map的实现原理

if(Array.prototype.map===undefined){
Array.prototype.map=function(fun){
//创建空数组: newArr
var newArr=[];
//遍历当前数组中每个元素
for(var i=0;i<this.length;i++){
//如果当前元素不是undefined
if(this[i]!==undefined){//判断稀疏数组
//调用fun传入当前元素值,位置i,当前数组,将结果保存在r中
//将newArr的i位置赋值为r
var r=fun(this[i],i,this);
newArr[i]=r;
}
}//(遍历结束)
return newArr;//返回newArr
}
}
如果浏览器不支持reduce属性,reduce的实现原理

if(Array.prototype.reduce===undefined){
Array.prototype.reduce=function(fun,base){
base===undefined&&(base=0);
for(var i=0;i<this.length;i++){
if(this[i]!==undefined){
base=fun(base,this[i],i,this);
}
}
return base;
}
}
IE缓存问题

在IE浏览器下,如果请求的方法是GET,并且请求的URL不变,那么这个请求的结果就会被缓存。解决这个问题的办法可以通过实时改变请求的URL,只要URL改变,就不会被缓存,可以通过在URL末尾添加上随机的时间戳参数('t'= + new Date().getTime())
localStorage

localStorage HTML5本地存储web storage特性的API之一,用于将大量数据(最大5M)保存在浏览器中,保存后数据永远存在不会失效过期,除非用 js手动清除。

不参与网络传输。
一般用于性能优化,可以保存图片、js、css、html 模板、大量数据。
var, let, const区别

块级作用域

不存在变量提升

暂时性死区 (只要块级作用域内存在let命令,它所声明的变量就“绑定”(binding)这个区域,不再受外部的影响。)

var tmp = 123;

if (true) {
tmp = 'abc'; // ReferenceError
let tmp;
}
总之,在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”(temporal dead zone,简称 TDZ)。

不允许重复声明
const声明一个只读的常量。一旦声明,常量的值就不能改变。(内存地址)

正确自我介绍模板:

面试官你好,我叫xx,我毕业于华中科技大学,以前工作主要是页面重构及组件开发,主要技术使用jq和jq插件或者原生js,
工作中擅长提升网页性能.关心用户的体验,讲究代码风格,html,css js基础扎实.平时喜欢写技术博客,经常活跃在github社区,熟悉如何与后端人员沟通。
前端新技术方面,了解ES6语法,webpack等前端工程化构建工具,掌握react vue 等前端mvvm框架,并有三个在线项目,
第一个项目是用vue vue-router vuex做的在线简历编辑器,路由切换保持信息,同步刷新消息。
第二个项目是用react react-router leancloud做的计划表,主要用的HTML5 CSS3的新特性以及leancloud存储功能。
第三个项目也是用react antd-mobile react-router 豆瓣图书V2Api做的豆瓣图书分类查询。
同时我可以接受加班.平时经常会学习新技术.对技术难题有钻研精神,最近在学redux,看redux源码。

问:你学前端多久了?
答:
比如可以这样,就当聊天一样
我最早接触前端是 xxx的时候,那时候前端刚刚 xxx,我做了 xxx,后来工作做移动端开发有很多内容涉及到前端,做了 xxx,后来干脆直接转行做前端
问:你会不会 java?
答:
很早之前接触一点 java,都忘了,目前主要还是专注做前端,如果后续公司有需要,往后端转也没有问题
问:你会不会小程序/html5/微信开发?答:小程序/h5/微信开发 本质上都是前端的一个小分支,内容90%以上都差不多,如果是做小程序需要可以在1周以内正式介入开发。

技巧:

1.同样的技术水平下, 自信能增加30%的工资
2.不用觉得自己过于自信,我们99%的同学都太过谦虚,自己觉得过度自信实际上也就稍微达标
3.即使我知道你的能力就这样,我(面试官)也喜欢自信有干劲的人

一些开放性题目

自我介绍:除了基本个人信息以外,面试官更想听的是你与众不同的地方和你的优势。

项目介绍

如何看待前端开发?

平时是如何学习前端开发的?

未来三到五年的规划是怎样的?

谈谈你对重构的理解

网站重构:在不改变外部行为的前提下,简化结构、添加可读性,而在网站前端保持一致的行为。也就是说是在不改变UI的情况下,对网站进行优化。
(答优化)

说说严格模式的限制

变量必须声明后再使用
函数的参数不能有同名属性,否则报错

不能使用with语句

不能对只读属性赋值,否则报错

不能使用前缀0表示八进制数,否则报错

不能删除不可删除的属性,否则报错

不能删除变量delete prop,会报错,只能删除属性delete global[prop]

eval不会在它的外层作用域引入变量

eval和arguments不能被重新赋值

arguments不会自动反映函数参数的变化

不能使用arguments.callee

不能使用arguments.caller

禁止this指向全局对象

不能使用fn.caller和fn.arguments获取函数调用的堆栈

增加了保留字(比如protected、static和interface)

设立”严格模式”的目的,主要有以下几个:

消除Javascript语法的一些不合理、不严谨之处,减少一些怪异行为;

消除代码运行的一些不安全之处,保证代码运行的安全;

提高编译器效率,增加运行速度;

为未来新版本的Javascript做好铺垫。

框架

什么是 MVVM , 和 MVC 是什么区别, 原理是什么?

  • 视图(View):用户界面。
  • 控制器(Controller):业务逻辑
  • 模型(Model):数据保存

View 传送指令到 Controller
Controller 完成业务逻辑后,要求 Model 改变状态
Model 将新的数据发送到 View,用户得到反馈

Vue

它采用双向绑定(data-binding):View的变动,自动反映在 ViewModel,反之亦然。Angular 和 Ember 都采用这种模式。

各部分之间的通信,都是双向的。
View 与 Model 不发生联系,都通过 Presenter 传递。
View 非常薄,不部署任何业务逻辑,称为"被动视图"(Passive View),即没有任何主动性,而 Presenter非常厚,所有逻辑都部署在那里。
父子组件怎么通信的?

props down event up

兄弟组件怎么通信的?

event bus vuex

生命周期有哪些, 怎么用?

beforecreate : 可以在这加个loading事件,在加载实例时触发
created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
beforeMount (为虚拟dom)
mounted : 挂载元素,获取到DOM节点
updated : 如果对数据统一处理,在这里写上相应函数
beforeDestroy : 可以做一个确认停止事件的确认框
nextTick : 更新数据后立即操作dom
React

jsx是什么?

本质上来讲,JSX 只是为 React.createElement(component, props, ...children) 方法提供的语法糖。

<MyButton color="blue" shadowSize={2}>
    Click Me
</MyButton>

编译为:

React.createElement(
MyButton,
{color: 'blue', shadowSize: 2},
'Click Me'
)

特性

点表示法:方便地从一个模块中导出许多 React 组件
属性: 你可以传递任何 {} 包裹的 JavaScript 表达式作为一个属性值
字符串常量 {'aaaa'}=='aaaaa'
默认为 True
Ref与props

在典型的 React 数据流中, 属性(props)是父组件与子代交互的唯一方式。要修改子组件,你需要通用新的 props 重新渲染它。
何时使用 Refs

处理焦点、文本选择或媒体控制。
触发强制动画。
集成第三方 DOM 库
React 支持给任意组件添加特殊属性。ref 属性接受一个回调函数,它在组件被加载或卸载时会立即执行。

当给 HTML 元素添加 ref 属性时,ref 回调接收了底层的 DOM 元素作为参数。例如,下面的代码使用 ref 回调来存储 DOM 节点的引用。

当 ref 属性用于使用 class 声明的自定义组件时,ref 的回调接收的是已经加载的 React 实例

redux的流程

调用store.dispatch(action)提交action。
redux store调用传入的reducer函数。把当前的state和action传进去。
根 reducer 应该把多个子 reducer 输出合并成一个单一的 state 树。
Redux store 保存了根 reducer 返回的完整 state 树
Provider组件是让所有的组件可以访问到store。不用手动去传。也不用手动去监听。

connect函数作用是从 Redux state 树中读取部分数据,并通过 props 来把这些数据提供给要渲染的组件。也传递dispatch(action)函数到props。

生产环境与开发环境

开发环境(development)和生产环境(production)的构建目标差异很大。在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)或热模块替换(hot module replacement)能力的 source map 和 localhost server。
而在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,以及更优化的资源,以改善加载时间。由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。

谈谈你对webpack的看法

WebPack 是一个模块打包工具,你可以使用WebPack管理你的模块依赖,并编绎输出模块们所需的静态文件。
它能够很好地管理、打包Web开发中所用到的HTML、JavaScript、CSS以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack有对应的模块加载器。webpack模块打包器会分析模块间的依赖关系,最后 生成了优化且合并后的静态资源。
webpack的两大特色:

  1. code splitting(可以自动完成)

  2. loader 可以处理各种类型的静态文件,并且支持串联操作
    你觉得jQuery源码有哪些写的好的地方

jQuery源码封装在一个匿名函数的自执行环境中,有助于防止变量的全局污染.

然后通过传入window对象参数,可以使window对象作为局部变量使用,好处是当jquery中访问window对象的时候,就不用将作用域链退回到顶层作用域了,从而可以更快的访问window对象。同样,传入undefined参数,可以缩短查找undefined时的作用域链。

(function( window, undefined ) {

     //用一个函数域包起来,就是所谓的沙箱

     //在这里边var定义的变量,属于这个函数域内的局部变量,避免污染全局

     //把当前沙箱需要的外部变量通过函数参数引入进来

     //只要保证参数对内提供的接口的一致性,你还可以随意替换传进来的这个参数

    window.jQuery = window.$ = jQuery;

})( window );

jquery将一些原型属性和方法封装在了jquery.prototype中,为了缩短名称,又赋值给了jquery.fn,这是很形象的写法。

有一些数组或对象的方法经常能使用到,jQuery将其保存为局部变量以提高访问速度。

jquery实现的链式调用可以节约代码,所返回的都是同一个对象,可以提高代码效率。
ES6的了解

新增模板字符串(为JavaScript提供了简单的字符串插值功能)、
箭头函数(操作符左边为输入的参数,而右边则是进行的操作以及返回的值Inputs=>outputs。)、
for-of(用来遍历数据—例如数组中的值。)
arguments对象可被不定参数和默认参数完美代替。
ES6将promise对象纳入规范,提供了原生的Promise对象,。
增加了let和const命令,用来声明变量。增加了块级作用域。let命令实际上就增加了块级作用域。
ES6规定,var命令和function命令声明的全局变量,属于全局对象的属性;let命令、const命令、class命令声明的全局变量,不属于全局象的属性。。还有就是引入module模块的概念
Generator async await
Router 的作用就是让每个 URL 都有一段代码来负责响应。

Controller 监听 Model 变化,Model 一变,Controller 就会去更新 View。
Controller 监听用户交互,用户点了提交或修改按钮,Controller 就要去更新 Model。
mvvm

监听是同步的,改动太频繁,频繁改动cpu太多,js->dom,
一开始没设置则不会被监听,创造一个api数据添加进去(get和set)
优化

优化发现改动不变就不改,
虚拟dom

jsx

JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
react diff

首先比较根节点,当根元素有不同类型时,React将卸载旧树并重新构建新树。

当比较两个相同类型的React DOM元素时,React则会观察二者的属性,保持相同的底层DOM节点,并仅更新变化的属性

原型链

  1. 原型对象也是普通的对象,是对象一个自带隐式的 proto 属性,原型也有可能有自己的原型,如果一个原型对象的原型不为 null 的话,我们就称之为原型链

  2. 原型链是由一些用来继承和共享属性的对象组成的(有限的)对象链

外边距合并 || 外边距塌陷

块的顶部外边距和底部外边距有时被组合(折叠)为单个外边距,其大小是组合到其中的最大外边距。

出现的3种情况:

  1. 毗邻的两个兄弟元素之间的外边距会塌陷(除非后者兄弟姐妹需要清除过去的浮动

  2. 块级父元素与其第一个/最后一个子元素
    【块级父元素中,不存在上边框、上内边距、内联元素、 清除浮动 这四条属性(也可以说,当上边框宽度及上内边距距离为0时),那么这个块级元素和其第一个子元素的上边距就可以说”挨到了一起“。此时这个块级父元素和其第一个子元素就会发生上外边距合并现象,换句话说,此时这个父元素对外展现出来的外边距将直接变成这个父元素和其第一个子元素的margin-top的较大者。】

  3. 空块元素
    如果一个空的块级元素,其 border、padding、inline content、height、min-height 都不存在。那么此时它的上下边距中间将没有任何阻隔,此时它的上下外边距将会合并。

设计模式

  1. 工厂模式
    该模式抽象了创建具体对象的过程。
    考虑到在Js中无法创建类,程序猿发明该种函数,用来封装以特定接口创建对象的细节。
    解决: 多个相似对象的问题。
    缺点: 没有解决对象识别(对象类型)的问题
function createObj(name, age, job){
    let rui = new Object();
    rui.name = name;
    rui.age = age;
    rui.job = job;
    rui.sayName = function(){
        return this.name
    };
    return rui;
}
var rui1 = createObj('rui1', 24, 'it')
var rui2 = createObj('rui2', 24, 'it')

Key Issus..

zh_CN.ts/Customer
export type IntlKeys = keyof typeof zh_CN | **string**;
export type IntlData = { [p in IntlKeys]: string };

接入变量 类型是否 为string ..妥当?

JSON

JSON(JavaScript Object Notation)轻量级的数据交换语言,以文字为基础,且易于让人阅读。
一种数据格式
出生:2001年
属于Js一个严格子集
与XML相比,不必创建DOM对象。
3种值为: 简单值 | 对象 | 数组
不支持: 变量 | 对象实例 | 函数
要求属性必须加双引号“ ”,分隔号使用 逗号代替。

JavaScript提供方法:
JSON.stringify 将对象转换为JSON。(目标,函数/数组过滤器,缩进参数)
JSON.parse 将JSON转换回对象。(目标,还原过滤器/如日期还原)

toJSON()方法
有时,JSON.stringify 不能满足某对象进行自定义序列化的需求,可给对象定义该方法,返回其自身的JSON数据格式。

如吧一个对象传入JSON.stringify()中,序列化该对象的顺序过程:

  1. 查看是否有toJSON方法,有的话,那么调用并返回有效值,没有就返回对象本身。
  2. 如果第二个参数(过滤器)存在,那调用它,返回结果为第一步的返回值。
  3. 对第2步的返回值进行相应序列化。
  4. 如果提供第三个参数(缩进) 那么执行格式化。

方法: JSON.stringify(student) 接收对象并将其转换为字符串。
由此产生的JSON字符串是一个叫做JSON编码或序列化或字符串化或编组的对象。再已经准备好把它发送到线上,或者放进数据存储中。

样板:

{
    "num" : 123,
    "ary" : [1,2,3,'a','b','c'],
    "obj" : { 
        "a" : 1, 
        "b" : "gaga"
    },

Webstorm_工具控的成长之路

设置【Log】快捷

Setting > LiveTemplates > ADD > console.log('☞☞☞ 9527 $class$ $line$', $END$);
Edit-Variables > ADD > class fileNameWithoutExtension() And line lineNumber() > ChangeDefault >> DONE

console.log('☞☞☞ 9527 $class$ $line$', $END$);
class fileNameWithoutExtension()
line lineNumber()

// 实时模板.

import * as React from 'react';

export default class $Component extends React.PureComponent<${Component}Types, any> {
  constructor(props: ${Component}Types) {
    super(props);
    this.state = {};
  }
  render() {
    return (
      <div>$Component Works!</div>
    );
  }
}

interface ${Component}Types {

}

javascript规范中总共有8中错误类型构造函数

错误构造函数

  • Error -- 错误对象
  • SyntaxError --解析过程语法错误
  • TypeError -- 不属于有效类型
  • ReferenceError -- 无效引用
  • RangeError -- 数值超出有效范围
  • URIError -- 解析URI编码出错
  • EvalError -- 调用eval函数错误
  • InternalError -- Javascript引擎内部错误的异常抛出, "递归太多"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.