-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontent.json
1 lines (1 loc) · 133 KB
/
content.json
1
{"meta":{"title":"TedQin","subtitle":null,"description":"Output is the best input","author":"Ted Qin","url":"http://yoursite.com"},"pages":[{"title":"All categories","date":"2019-07-28T10:39:03.000Z","updated":"2019-07-28T17:41:00.655Z","comments":true,"path":"categories/index.html","permalink":"http://yoursite.com/categories/index.html","excerpt":"","text":""},{"title":"All tags","date":"2019-07-25T07:40:02.000Z","updated":"2019-07-25T14:41:55.720Z","comments":true,"path":"tags/index.html","permalink":"http://yoursite.com/tags/index.html","excerpt":"","text":""}],"posts":[{"title":"什么时候需要保存this?","slug":"什么时候需要保存this","date":"2019-10-17T06:25:05.000Z","updated":"2019-10-17T06:29:42.963Z","comments":true,"path":"2019/10/17/什么时候需要保存this/","link":"","permalink":"http://yoursite.com/2019/10/17/什么时候需要保存this/","excerpt":"","text":"https://www.imooc.com/wenda/detail/312105 javascript中this什么时候可以直接调用?什么时候要把它赋值给一个变量后才能调用? 1) 避免多层this var o = { f1: function() { console.log(this); var f2 = function() { console.log(this); }(); } } o.f1() 上面代码包含两层this,结果运行后,第一层指向该对象,第二层指向全局对象。一个解决方法是在第二层改用一个指向外层this的变量。 var o = { f1: function() { console.log(this); var that = this; var f2 = function() { console.log(that); }(); } } o.f1() 上面代码定义了变量that,固定指向外层的this,然后在内层使用that,就不会发生this指向的改变。 2) 避免数组处理方法中的this 数组的map和foreach方法,允许提供一个函数作为参数。这个函数内部不应该使用this。 var o = { v: 'hello', p: [ 'a1', 'a2' ], f: function f() { this.p.forEach(function (item) { console.log(this.v+' '+item); }); }} o.f() 上面代码中,foreach方法的参数函数中的this,其实是指向window对象,因此取不到o.v的值。 解决这个问题的一种方法,是使用中间变量。 var o = { v: 'hello', p: [ 'a1', 'a2' ], f: function f() { var that = this; this.p.forEach(function (item) { console.log(that.v+' '+item); }); }} o.f() 另一种方法是将this当作foreach方法的第二个参数,固定它的运行环境。 var o = { v: 'hello', p: [ 'a1', 'a2' ], f: function f() { this.p.forEach(function (item) { console.log(this.v+' '+item); }, this); }} o.f() 3) 避免回调中的this var o = new Object();o.f = function (){ console.log(this === o);}o.f() 上面代码表示,如果调用o对象的f方法,其中的this就是指向o对象。 但是,如果将f方法指定给某个按钮的click事件,this的指向就变了。 $('#button').on('click', o.f);","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"}]},{"title":"vue的一些知识整理","slug":"vue的一些知识整理","date":"2019-10-10T15:56:43.000Z","updated":"2019-10-12T10:01:39.095Z","comments":true,"path":"2019/10/10/vue的一些知识整理/","link":"","permalink":"http://yoursite.com/2019/10/10/vue的一些知识整理/","excerpt":"","text":"父子组件传值 父组件向子组件传值 //html //1.父组件通过v-bind给子组件传值 <todo-item v-bind:content="data1"></todo-item> //script //定义全局组件 Vue.component("TodoItem", { //2.子组件通过props接收 props: ['content'] //也可以用对象形式进行参数校验 //props: {content: String}//只允许接受string template: "<li>{{content}}</li>" }) var app = new Vue({ ... data: { data1: "ted" } }) 子组件向父组件传值 //html //2.父组件使用子组件时,通过v-on监听触发的事件 //一旦子组件delete触发,就会触发父组件handleItemDelete这个方法 <todo-item v-on:delete="handleItemDelete"> </todo-item> //script var TodoItem = { data: { data1: 'ted' }, template: "<li v-on:click='handleButtonClick'>点我删除</li>", methods: { handleButtonClick: function() { //1.子组件通过$emit向外触发delete事件,并传出data1 this.$emit("delete", data1) } } } var app = new Vue({ ... methods: { //3.父组件使用子组件的值 handleItemDelete: function(data1) { alert("data1") } } }) 非父子组件传值 观察者模式 <!-- 非父子组件传值 --> <!-- 通过观察者模式实现,两个子组件之间传值,点击其中一个组件,另一个组件的值变成这个被点击组件的值--> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="./vue.js"></script> </head> <body> <div id="root"> <child :content="content1"></child> <child :content="content2"></child> </div> <script> //1. 在Vue的prototype上定义一个bus Vue.prototype.bus = new Vue() Vue.component('child', { props: { content: String }, template: '<div v-on:click="handleClick">{{content}}</div>', methods: { handleClick: function() { //使用bus向外触发事件 this.bus.$emit('change', this.content) } }, //利用钩子函数,监听change事件 mounted: function() { var this_ = this this.bus.$on('change', function(msg) { this_.content = msg }) } }) var vm = new Vue({ el: "#root", data: { content1: "tedqin", content2: "teddymoon" } }) </script> </body> </html> vuex 全局组件和局部组件 全局组件:用Vue.component()方法定义,其他组件可以直接使用 //html //父组件通过v-bind给子组件传值 <todo-item v-bind:content="data1"></todo-item> //script //定义全局组件 Vue.component("TodoItem", { //子组件通过props接收 props: ['content'] template: "<li>{{content}}</li>" }) var app = new Vue({ ... data: { data1: "ted" } }) 局部组件:像普通对象一样定义,其他组件引用的时候需要注册 //html //父组件通过v-bind给子组件传值 <todo-item v-bind:content="data1"></todo-item> //script //定义局部组件 var TodoItem = { props: ['content'] template: "<li>{{content}}</li>" } var app = new Vue({ ... //把局部逐渐注册到到需要引用它的组件的vue实例中 components: { TodoItem: TodoItem } data: { data1: "ted" } }) v-bind,v-model,v-for和v-on v-bind:用于给标签/组件绑定属性,实现动态管理标签的属性 //html <a v-bind:href="url">网络测试</a> //v-bind绑定href //script var app = new Vue({ ... data { url: "http://www.baidu.com" } }) //html //父组件通过v-bind给子组件传值 <todo-item v-bind:content="data1"></todo-item> //script Vue.component("TodoItem", { //子组件通过props接收 props: ['content'] template: "<li>{{content}}</li>" }) var app = new Vue({ ... data: { data1: "ted" } }) v-model:实现数据和视图层的双向绑定,只能定义在input,select,textarea上,绑定之后随着input输入的变化,对应绑定的内容也变化,反之也变化 //html <input type="text" v-model="inputValue" /> //script var app = new Vue({ ... data: { inputValue: '' } }) v-for:循环data //循环数组 //html <li v-for="item of list">{{item.text}}</li> <li v-for="(item, index) of list">{{item.text}}---{{index}}</li> <li v-for="(item, index) of list" :key="item.id">{{item.text}}---{{index}}</li> <!--用index的时候最好再用key唯一标识--> //script var app = new Vue({ ... data: { list: [{ id: "1", text: "ted" }, { id: "2", text: "xxy" }] } }) //循环对象 //html <li v-for="(item, key, index) of list">{{item}}--{{key}}--{{index}}</li> <!--输出"ted--name--0 23--age--1"--> //script var app = new Vue({ ... data: { list: { name: "ted", age: "23" } } }) v-on:绑定事件 //html <button v-on:click="handleButtonClick">提交</button> //script var app = new Vue({ ... methods: { handleButtonClick: function() { alert("click!") } } }) v-text和v-html的区别 v-text: 等同于插值表达式双括号,绑定当前元素的innerText,会原封不动的输出纯文本 v-html: 绑定当前元素的innerText,会以html规则编译文本内容后输出 //html <div v-text="name"></div> <!--输出<h1>ted</h1>--> <div v-html="name"></div> <!--输出h1大小的ted--> //script var vm = new Vue({ el:"#app", data: { name:"<h1>ted</h1>" } }) 计算属性 computed和逻辑有关的计算都放在computed中,不方便直接在模版中计算 例子: get属性 <div id="example"> <p>Original message: "{{ message }}"</p> <p>Computed reversed message: "{{ reversedMessage }}"</p> </div> var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 计算属性的 getter reversedMessage: function () { // `this` 指向 vm 实例 return this.message.split('').reverse().join('') } } }) set属性 computed: { fullName: { // getter get: function () { return this.firstName + ' ' + this.lastName }, // setter set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } 上面代码中,get作用是通过监听firstName和lastName的改变,获取fullName的值;set的所用是传入需要改变的fullName,并根据参数更新firstName和lastName的值 和method的不同: 计算属性中的值依赖data中相关联的值 computed存在缓存机制:每次重新渲染时,对于method,每次都会重新计算;对于计算属性,仅当data中依赖的值改变时,计算属性的值才改变, 侦听器 watch和computed相似,同样是监听data中的值,当data发生改变时,执行相应的操作也具有缓存效果 和computed的不同: computed是定义并计算一个新的值,这个值依赖data中的某些值 watch是监听data中已经存在的变量,并在data发生改变的时候做相应的操作 computed比watch更加简洁 样式绑定 class绑定::class=等价于: v-bind:class= ,将class绑定在一个标签上,可以控制class的显示与否 class的对象绑定 :class="{activated: isActivated}" <style> .activated {color: red} </style> <div @click="handleDivClick> :class="{activated: isActivated}"></div> var vm = new Vue({ el: "#app", data: { isActicated: false }, method: { handleDivClick: function() { this.isActivated = true } } }) class的数组绑定 :class="[activated]" ``` <style> .activated {color: red} </style> <div @click="handleDivClick> :class="{activated: isActivated}"></div> var vm = new Vue({ el: "#app", data: { activated: "" }, method: { handleDivClick: function() { this.activated = "activated" } } }) ``` 内联样式绑定 style的对象绑定 <div :style="styleObj" v-on:click="handleDivClick"></div> var vm = new Vue({ el: "#app", data: { styleObj: { color: red } }, methods: { handleDivClick: function() { this.styleObj.color = red } } }) style的数组绑定 只需要把<div :style="styleObj"换成<div :style=[styleObj, {fontSize: '20px'}] 条件渲染 v-if: 隐藏的元素不会被渲染到页面上,还可以用v-else v-show: 隐藏的元素已经被渲染到页面上,只是用了display:none来隐藏 <div v-if="show">{{name}}</div> <div v-else="show">Bye</div> <div v-if="show===a">a</div> <div v-else-if="show===b">b</div> <div v-else>bye</div> <div v-show="show">{{name}}</div> var vm = new Vue({ el: "#app", data: { name: 'ted', show: false }, }) vue中的set方法arr=[1,2,3,4,5] data={ name: "ted", age: "23" } 改变页面中的渲染出来的对象或数组,不能直接用arr[3]=5这样直接改,只能修改数组/对象的引用,即this.arr=[1,2,5,4,5]全部修改 也可以用Vue.set()方法修改,set方法也可以添加新的数据 //改数组 Vue.set(this.arr, 0, 11) //[11,2,3,4,5] //改对象 Vue.set(this.data, "name", "teddy") //{name:"teddy", age: "23"} slot插槽:父组件向子组件传递dom结构: 直接在子组件中定义,然后在template中引入 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="./vue.js"></script> </head> <body> <div id="app"> <child> <h1>tedqin</h1> </child> </div> <script> Vue.component('child', { template: `<div> <p>hello</p> <slot></slot> </div> ` }) var vm = new Vue({ el: "#app" }) </script> </body> </html> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="./vue.js"></script> </head> <body> <div id="app"> <child> <header slot="header"></header> <footer slot="footer"></footer> </child> </div> <script> Vue.component('child', { template: `<div> <slot name="header"></slot> <p>hello</p> <slot name="footer"></slot> </div> ` }) var vm = new Vue({ el: "#app" }) </script> </body> </html> 动态组件<component :is="type"></component> // Vue.component('type1', { template: '<div>type1</div>' }) Vue.component('type2', { template: '<div>type2</div>' }) // data:{ type: 'type1' } // methods: { handleBtnClick: function(){ this.type = (this.type==="type1" ? 'type2' : 'type1') } } 根据is属性绑定的data数据中的type动态切换组件 v-once将第一次展示在页面中的资源保存在内存中,下次直接从内存中取资源,可以优化性能,提高静态页面展示效率 ##vue的路由 src/main.js 入口文件,定义了一个根实例 import Vue from 'vue' import App from './App' import router from './router' new Vue({ el: "app", //app挂载点在./index.html上 router, //使用router,在路由配置文件index.js中配置路由 components: { App }, //使用子组件App template: '<App/>' //渲染App这个局部组件 }) src/App.js App局部组件,也就是main.js渲染的页面,也就是主页面 <template> <div id="app> <router-view> //显示当前路由地址所对应的路由内容 </div> </template> <script> export default { name: 'App' } <sctipt> <style> #app { ... } <style> src/router/index.js 路由配置项 `import Vue from ‘vue’import Router from ‘vue-router’import Home from ‘@/pages/home/Home’import Home from ‘@/pages/list/List’ Vue.use(Router) export default new Router({ routes: [ { path: '/', //1.当用户访问根路径的时候 name: 'Home', components: Home // 2.访问home这个单文件组件 }, { //增加其他页面的配置项 path: '/list', name: 'List', components: List } ] }) ``` @/pages/home/Home.vue 主页,单文件组件 <template> <div>home</div> </template> <script> export default { name: 'Home' } </script> <style> </style> @/pages/list/List.vue list页面,单文件组件 <template> <div>list</div> </template> <script> export default { name: 'List' } </script> <style> </style> vue是单页面应用,用替换a标签<router-link to="/list">点击跳转</router-link>","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"}],"tags":[{"name":"vue","slug":"vue","permalink":"http://yoursite.com/tags/vue/"}]},{"title":"html5知识整理","slug":"html5知识整理","date":"2019-09-30T02:53:19.000Z","updated":"2019-09-30T03:25:41.606Z","comments":true,"path":"2019/09/30/html5知识整理/","link":"","permalink":"http://yoursite.com/2019/09/30/html5知识整理/","excerpt":"","text":"h5变化 表单增强属性 日期、时间、搜索 表单验证 (required必填,minmax输入范围,正则) placeholder 表单空的时候显示什么内容 自动聚焦 新增语义 header/footer section/article 区域 (块级) nav 导航(快级) aside(快级) em/strong 强调 新API 离线 (applicationCache ) 音视频 (audio, vidio) 图形 (canvas) 实时通信(websoket) 本地存储(localStorage, indexDB) 设备能力(地图定位,手机摇一摇) Doctype 作用?标准模式与兼容模式各有什么区别?<!DOCTYPE html>声明位于HTML文档中的第一行,不是一个HTML标签,它的作用:告知web浏览界面应该使用哪个html版本。 标准模式:<!DOCTYPE html> h5及以后的版本,以该浏览器支持的最高标准运行 兼容模式:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> h5以前的版本,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。需引用DTD(文档类型说明),因为html 4.0.1是基于SGML(Standard Generalized Markup Language,标准通用标记语言)。DTD指定了标记语言的规则,确保了浏览器能正确的渲染内容。 行内元素有哪些?块级元素有哪些? 空(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 空元素: 常见: br hr img input link meta 不常见: area base col command embed keygen param source track wbr 不同浏览器(版本)、HTML4(5)、CSS2 等实际略有差异 参考: http://stackoverflow.com/questions/6867254/browsers-default-css-for-html-elements 哪些元素可以自闭合? 表单元素 input img br, hr meta, link HTML和DOM的关系 HTML只是一个字符串 DOM由HTML解析而来 JS可以维护DOM form 作用 直接提交表单 使用submit / reset按钮 便于浏览器保存表单 第三方库可以整体取值 第三方库可以进行表单验证 简述一下你对 HTML 语义化的理解? 用正确的标签做正确的事情。 html 语义化让页面的内容结构化,结构更清晰,便于对浏览器、搜索引擎解析; 即使在没有样式 CSS 情况下也以一种文档格式显示,并且是容易阅读的; 搜索引擎的爬虫也依赖于 HTML 标记来确定上下文和各个关键字的权重,利于 SEO; 使阅读源代码的人对网站更容易将网站分块,便于阅读维护理解。 介绍一下你对浏览器内核的理解?主要分成两部分:渲染引擎(layout engineer 或 Rendering Engine)和 JS 引擎。 渲染引擎:负责取得网页的内容(HTML、XML、图像等等)、整理讯息(例如加入 CSS 等),以及计算网页的显示方式,然后渲染到用户的屏幕上。 JS 引擎则:解析和执行 javascript 来实现逻辑和控制 DOM 进行交互。 最开始渲染引擎和 JS 引擎并没有区分的很明确,后来 JS 引擎越来越独立,内核就倾向于只指渲染引擎。 html 中 title 属性和 alt 属性的区别?<img src="#" alt="alt信息" /> 当图片不输出信息的时候,会显示 alt 信息 鼠标放上去没有信息,当图片正常读取,不会出现 alt 信息。 <img src="#" alt="alt信息" title="title信息" /> 当图片不输出信息的时候,会显示 alt 信息 鼠标放上去会出现 title 信息; 当图片正常输出的时候,不会出现 alt 信息,鼠标放上去会出现 title 信息。 除了纯装饰图片外都必须设置有意义的值,搜索引擎会分析。 另外还有一些关于 title 属性的知识: title 属性可以用在除了 base,basefont,head,html,meta,param,script 和 title 之外的所有标签。 title 属性的功能是提示。额外的说明信息和非本质的信息请使用 title 属性。title 属性值可以比 alt 属性值设置的更长。 title 属性有一个很好的用途,即为链接添加描述性文字,特别是当连接本身并不是十分清楚的表达了链接的目的。 为什么我们要弃用table标签?table的缺点在于服务器把代码加载到本地服务器的过程中,本来是加载一行执行一行,但是table标签是里面的东西全都下载完之后才会显示出来,那么如果图片很多的话就会导致网页一直加载不出来,除非所有的图片和内容都加载完。如果要等到所有的图片全都加载完之后才显示出来的话那也太慢了,所以table标签现在我们基本放弃使用了。 head子元素大概分为三类,分别是: 描述网页基本信息的 指向渲染网页需要其他文件链接的 各大厂商根据自己需要定制的 网页基本信息一个网页,首先得有个标题,就跟人有名字一样。除此之外,还可以根据实际需要补充一些基本信息。 文档标题(浏览器标签中显示的文本):<title>深入了解 head 元素</title> 编码格式: 如果你的页面出现乱码,那一般就是编码格式不对 视窗设置: 搜索引擎优化相关内容: IE浏览器版本渲染设置: 其他文件链接 CSS 文件: JavaScript 文件:<script src=“script.js"></script> 但是为了让页面的样子更早的让用户看到,一般把JS文件放到body的底部 厂商定制同样分享页面到QQ的聊天窗口,有些页面直接就是一个链接,但是有些页面有标题,图片,还有文字介绍。为什么区别这么明显呢?其实就是看有没有设置下面这三个内容 <meta itemprop="name" content="这是分享的标题"/><meta itemprop="image" content="http://imgcache.qq.com/qqshow/ac/v4/global/logo.png" /><meta name="description" itemprop="description" content="这是要分享的内容" /> 移动端项目需要注意的4个问题meta中设置viewport阻止用户手滑放大或缩小页面,需要在 index.html中添加meta元素,设置viewport。 <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"> CSS样式统一问题我们需要重置页面样式,因为在不同的手机浏览器上,默认的css样式不是统一的。 解决方法:使用reset.css重置所有元素的默认样式 一像素边框问题有的手机分辨率比较高,是2倍屏或3倍屏,手机上的浏览器就会把CSS中的1像素值展示为2个或3个物理宽度 解决方法: 添加一个border.css库,将利用scroll缩放的原理将边框重置。当我们需要使用一像素边框时只需要在标签上添加对应类名,如设置底部一像素边框就在标签上加入”border-bottom”的class名 300毫秒点击延迟问题在移动端开发中,某些机型上使用click事件会延迟300ms才执行,这样影响了用户体验。 解决方法: 引入fastclick.js。 嵌套 块级一般不能嵌套块级(但div可以嵌套p) a可以包含div html问题 doctype的意义是什么 让浏览器以标准模式渲染 让浏览器知道元素的合法性 html xhtml h5的关系 html属于sgml xhtml属于xml,是html进行xml严格化的结果 h5是一个独立的规范,比hxtml宽松 H5有什么变化 新的语义化元素section article header footer aside 表单增强 新的API em和i有什么区别 都是斜体,em是语义化标签,i是纯样式 语义化的意义 维护的开发者容易理解 机器容易理解结构 有助于seo 哪些标签可以自闭和(不能嵌套其他标签) input img br(换行) hr(水平线) meta link","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"}],"tags":[{"name":"html5","slug":"html5","permalink":"http://yoursite.com/tags/html5/"}]},{"title":"es6中的async&await异步调用方法","slug":"es6中的async-await异步调用方法","date":"2019-09-25T09:13:18.000Z","updated":"2019-09-25T14:46:38.249Z","comments":true,"path":"2019/09/25/es6中的async-await异步调用方法/","link":"","permalink":"http://yoursite.com/2019/09/25/es6中的async-await异步调用方法/","excerpt":"","text":"基本用法async函数 async定义的函数返回一个Promise对象,可以使用then方法添加回调函数。 async function timeout() { return 'hello world' } console.log(timeout()); console.log('虽然在后面,但是我先执行'); 它和promise一样,有异步回掉功能 async function timeout() { return 'hello world' } timeout().then(result => { console.log(result); }) console.log('虽然在后面,但是我先执行'); async原理:如果async成功返回一个promise对象,实际会调用Promise.resolve()返回,否则会调用Promise.reject() async function timeout(flag) { if (flag) { return 'hello world' } else { throw 'my god, failure' } } console.log(timeout(true)) // 调用Promise.resolve() 返回promise 对象。 console.log(timeout(false)); // 调用Promise.reject() 返回promise 对象。 await当函数执行时,一旦遇到await(后面定义的也是一个promise对象)就会先返回,等异步操作完成,再执行后面的语句。 await只能出现在async函数内部,等待async函数返回或执行promise, // 2s 之后返回双倍的值 function doubleAfter2seconds(num) { return new Promise((resolve, reject) => { setTimeout(() => { resolve(2 * num) }, 2000); } ) } async function testResult() { let result = await doubleAfter2seconds(30); console.log(result); } testResult(); //2s后输出60 代码执行过程: 调用testResult()函数,遇到await,开始等待(后面的promise执行完毕) 执行await后的doubleAfter2seconds(30),返回promise开始执行,2s后执行完毕,值为60并返回 await拿到60,赋值给result,等待结束,代码继续运行,执行console 这里如果计算多个值,可以像写同步代码那样,避免回掉地狱 async function testResult() { let first = await doubleAfter2seconds(30); let second = await doubleAfter2seconds(50); let third = await doubleAfter2seconds(30); console.log(first + second + third); } demo 获取股票报价的函数(可以用.then处理async函数) async function getStockPriceByName(name) { const symbol = await getStockSymbol(name); const stockPrice = await getStockPrice(symbol); return stockPrice; } getStockPriceByName('goog').then(function (result) { console.log(result); }); 在api中,把结果return 出去 export async function getRetailUnitPrice () { const reqBody = await get('/race/spot/racespot/enter/dayahead') return reqBody } 注意点 async函数返回的promise对象,必须等到内部所有await命令后面的对象执行完,才会执行then 当async返回一个常量,返回Promise.resolve(常量)自动构建promise返回值 当async函数没有返回值的时候,返回Promise.resolve(undefiend)自动构建promise返回值 async function getTitle(url) { let response = await fetch(url); let html = await response.text(); return html.match(/<title>([\\s\\S]+)<\\/title>/i)[1]; } getTitle('https://tc39.github.io/ecma262/').then(console.log) // "ECMAScript 2017 Language Specification" 与promise相比优点:处理.then链,不必把回掉嵌套在.then中,只要await即可 function sing() { return new Promise(function(resolve, reject) { setTimeout(function() { resolve(`来一首好听的歌吧~~~`); }, 1000); }); } async function demo() { try { const v = await say(); const s = await sing(); console.log(v); // 输出:hello, joel。今年我 26 岁 console.log(s) // 来一首好听的歌吧~~~ } catch (e) { console.log(e) } } demo(); 如果使用原来的Promise 就是把回调放在then()中。","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"}]},{"title":"浅谈Javascript的垃圾回收机制与内存泄漏问题","slug":"浅谈Javascript的垃圾回收机制与内存泄漏问题","date":"2019-09-25T02:37:12.000Z","updated":"2019-09-25T03:50:46.938Z","comments":true,"path":"2019/09/25/浅谈Javascript的垃圾回收机制与内存泄漏问题/","link":"","permalink":"http://yoursite.com/2019/09/25/浅谈Javascript的垃圾回收机制与内存泄漏问题/","excerpt":"","text":"javascript的垃圾回收机制Javascript浏览器具有自动垃圾回收机制最常用的方式是标记清除(mark-and-sweep) 当申明一个变量时,就将这个变量标记为“进入环境”。从逻辑上来讲,永远都不能释放进入环境的变量。当变量离开环境时,标记为“离开环境” js定期进行垃圾回收(非实时),销毁带“离开环境”标记的变量,回收内存 function test(){ var a = 10 ; // 被标记 ,进入环境 var b = 20 ; // 被标记 ,进入环境 } test(); // 执行完毕 之后 a、b又被标离开环境,被回收 内存泄漏内存泄漏是指一块被分配的内存即不能使用也不能回收 浏览器会使用自动垃圾回收机制,但是也会产生一些内存泄漏问题 1. 意外的全局变量function foo(arg) { bar = "this is a hidden global variable"; } bar没被申明,会变成一个全局变量,在页面关闭之前不会被释放 2. 被遗忘的计时器或callback函数var someResource = getData(); setInterval(function() { var node = document.getElementById('Node'); if(node) { // 处理 node 和 someResource node.innerHTML = JSON.stringify(someResource)); } }, 1000); 这里如果node元素从dom中移除,该定时器还是会存在;同时因为回掉函数中用了someResource,定时器外面的someResource也不会被释放 3. 闭包function bindEvent(){ var obj=document.createElement('xxx') obj.onclick=function(){ // Even if it is a empty function } } 闭包可以维持函数内的局部变量,使得闭包内返回的函数可以调用返回外的局部变量,使其得不到释放,所以会形成内存泄漏 // 将事件处理函数定义在外面 function bindEvent() { var obj = document.createElement('xxx') obj.onclick = onclickHandler } // 或者在定义事件处理函数的外部函数中,删除对dom的引用 function bindEvent() { var obj = document.createElement('xxx') obj.onclick = function() { // Even if it is a empty function } obj = null } 解决方法:将事件处理函数定义在外部,或者在定义事件处理函数的外部函数中,删除对dom的引用。 4. 没有清理的dom元素引用var elements = { button: document.getElementById('button'), image: document.getElementById('image'), text: document.getElementById('text') }; function removeButton() { document.body.removeChild(document.getElementById('button')); // 此时,仍旧存在一个全局的 #button 的引用 // elements 字典。button 元素仍旧在内存中,不能被 GC 回收。 } 虽然我们用removeChild移除了button,但是还在elements对象里保存着#button的引用,换言之,DOM元素还在内存里面。 避免内存泄漏的方法 减少不必要的全局变量,或者生命周期较长的对象,及时对无用的数据进行垃圾回收 注意程序逻辑,避免“死循环”之类的 避免创建过多的对象 总而言之需要遵循一条原则:不用了的东西要及时归还 内存泄漏查看方法chrome中 打开开发者工具,选择 performance 面板 勾选 Memory和screenshots 点击左上角的录制按钮。 在页面上进行各种操作,模拟用户的使用情况。 一段时间后,点击对话框的 stop 按钮,面板上就会显示这段时间的内存占用情况。 如果内存占用基本平稳,接近水平,就说明不存在内存泄漏。 反之,就是内存泄漏了。","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"}]},{"title":"vue源码研读","slug":"vue源码研读","date":"2019-09-24T09:59:08.000Z","updated":"2019-09-24T10:50:13.112Z","comments":true,"path":"2019/09/24/vue源码研读/","link":"","permalink":"http://yoursite.com/2019/09/24/vue源码研读/","excerpt":"","text":"不定时更新 computed原理Vue的响应式系统当把一个普通的js对象传给Vue实例的data时,Vue将遍历这个对象的所有属性,并使用Object.defineProperty把这些属性全部转换为getter/setter 目的:在data被访问和修改的时候通知变化 组成: observe:遍历data中的属性,使用Object.defineProperty把它们转化为getter/setter,这一步被称为数据劫持 dep:每个属性都拥有自己的消息订阅器dep,用于存放所有订阅了该属性的观察者对象 watcher:观察者对象,通过dep实现对响应属性的监听,当监听到改变时,触发自己的回掉函数 computed监听的原理步骤 数据劫持:组件初始化,computed和data建立各自的响应系统,observe遍历data的属性,并使用Object.defineProperty把它们转化为getter/setter computed初始化:注册一个watcher观察者对象,实例化一个dep消息订阅器 computed调用: 触发getter 调用watcher.depend()向自身的dep中添加所监听data属性的watcher 当data中某个被监听的数据发生变化时,出发setter,遍历dep,调用watcher.update()完成更新 双向绑定原理model=>view:使用基本的事件监听即可实现 view=>model:原理的computed相似,也是通过数据劫持+观察者模式来实现 步骤: 数据劫持:使用Object.defineProperty()给data添加getter和setter属性, 创建一个消息订阅器类dep,存放订阅者,订阅者是收集的发生变化的数据 创建一个观察者类watcher,在初始化时把自己添加进dep,观察者是view需要修改的节点","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"},{"name":"vue","slug":"前端/javascript/vue","permalink":"http://yoursite.com/categories/前端/javascript/vue/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"},{"name":"vue","slug":"vue","permalink":"http://yoursite.com/tags/vue/"}]},{"title":"浅谈原型、执行上下文和作用域","slug":"浅谈原型、执行上下文和作用域","date":"2019-09-23T17:28:59.000Z","updated":"2019-09-23T17:29:07.289Z","comments":true,"path":"2019/09/24/浅谈原型、执行上下文和作用域/","link":"","permalink":"http://yoursite.com/2019/09/24/浅谈原型、执行上下文和作用域/","excerpt":"","text":"原型构造函数一个普通函数,内部使用了this变量 实例对构造函数使用new运算符,就能生成实例对象,并且this会绑定在实例上 原型链一个实例对象,自身不存在的属性可以通过它的隐式原型proto向指向的原型对象找,若没有,则同理顺着该原型对象的proto到该原型对象的原型对象上找 原型(原型对象)原型对象是每个函数的prototype属性指向的一个对象,可以理解为一个仓库,可以在上面定义其他属性,它自带一个constructor,指向回它的构造函数 每创建一个函数,该函数就会自带一个prototype属性(显式原型),该属性是一个指针,指向该函数的原型对象。 若这个函数是构造函数,则由它构建的实例会自带一个proto属性(隐式原型),该属性是一个指针,指向原型对象 原型对象上有一个属性constructor,该属性也是一个指针,指向其关联的构造函数 如果Person的原型Person.prototype对象变成了某一个类的实例Person{},这个实例又会指向一个新的原型对象Object.prototype 执行上下文针对对象或者函数,可以理解为this的值 分类: 全局上下文:window为全局上下文 函数(局部)上下文 特点: 动态的,函数调用的时候时创建,函数调用结束时释放 作用域一块地盘,一个代码段所在的区域。 分类: 全局作用域 函数作用域 块级作用域 作用:隔离变量,不同作用域下同名的变量名不会产生冲突 特点: 静态的,只要定义好了就一直存在,不会改变 作用域链由多个具有从属关系的作用域形成的链,查找变量时沿着作用域链查找 自由变量:当前作用域没有定义的变量,可以顺着作用域链到父级作用域中去找","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"}]},{"title":"Javascript的几种继承方法","slug":"Javascript的几种继承方法","date":"2019-09-23T14:36:54.000Z","updated":"2019-09-23T15:12:43.741Z","comments":true,"path":"2019/09/23/Javascript的几种继承方法/","link":"","permalink":"http://yoursite.com/2019/09/23/Javascript的几种继承方法/","excerpt":"","text":"整理一下目前javascript的几种继承方式 1. 利用构造函数和call/apply缺点:子类无法继承父类原型上的属性function Parent() { this.name = 'parentName' } function Child() { Parent.call(this) this.age = 10 } 2. 利用原型链缺点:如果改变一个实例的属性,其他的实例也会被改变,原因是公用一个原型function Parent() { this.name = 'parentName' } function Child() { this.age = 10 } Child.prototype = new Parent() 3. 组合继承function Parent() { this.name = 'parentName' } function Child() { Parent.call(this) this.age = 10 } Child.prototype = new Parent() 4. es6 class继承class Point { constructor(x, y) { this.x = x; this.y = y; } } class ColorPoint extends Point { constructor(x, y, color) { super(x, y); this.color = color; } } let cp = new ColorPoint(25, 8, 'green');","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"}]},{"title":"深浅拷贝","slug":"深浅拷贝","date":"2019-09-22T16:27:23.000Z","updated":"2019-09-23T15:13:20.631Z","comments":true,"path":"2019/09/23/深浅拷贝/","link":"","permalink":"http://yoursite.com/2019/09/23/深浅拷贝/","excerpt":"","text":"简单的概念: 浅拷贝:将原对象/数组的引用赋值给新对象,新对象/数组只是一个引用 改变新对象的时候,同时改变原对象 深拷贝:创建一个新的对象/数组,将原对象/数组的各项属性的值拷贝过来 改变新对象的时候,不改变原对象 只对第一层做拷贝:浅拷贝对数组(基本类型数组) 直接遍历 let arr = [1,2,3,4] let newArray=[] 遍历{ newArray.push(item) } slice() let newArray = arr.slice() concat() let newArray = arr.concat() 对对象 直接遍历 Object.assign() var obj = {name: 'ted', age:23} var copyObj = Object.assign({}, obj) 扩展运算符…(数组同样适用) let copyObj = {...obj} 深拷贝:拷贝所有层级 JSON.parse(JSON.stringify(XXXX)) let arr = [ {number1: 1}, {number2: 2}, {number3: 3} ] let copyArr = JSON.parse(JSON.stringify(arr)) 递归 function myCopy(obj) { let copyObj = obj.constructor === Array ? [] : {} for (let i in obj) { if (typeof obj[i] === 'object') { copyObj[i] = myCopy(obj[i]) } else { copyObj[i] = obj[i] } } }","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"}]},{"title":"牛客网JavascriptV8输入格式","slug":"牛客网JavascriptV8输入格式","date":"2019-08-03T15:38:20.000Z","updated":"2019-08-03T22:42:28.094Z","comments":true,"path":"2019/08/03/牛客网JavascriptV8输入格式/","link":"","permalink":"http://yoursite.com/2019/08/03/牛客网JavascriptV8输入格式/","excerpt":"","text":"相比Leetcode,牛客和赛码网等网站对于Javascript真的太不友好了,光是输入就可以折腾半天。整理了一下牛客网上Javascript V8的输入 输入一行,空格隔开 1 2 while (line = readline()) { var lines = line.split(' ') var a = parseInt(lines[0]) var b = parseInt(lines[1]) } console.log(a, b) 多行,每行输入一个 2 1 2 var lines = [] while (line = readline()) { lines.push(parseInt(line)) } console.log(lines) 多行,第一行为参数,后面行为数组 //第一行为参数m和n,接下里为数组 2 3 //m, n 1 2 3 4 11 22 33 44 var lines = readline().split(' ') var n = parseInt(lines[0]) var m = parseInt(lines[1]) var Arr1 = readline().split(' ') var Arr2 = readline().split(' ') console.log(n,m,Arr1,Arr2)","categories":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/categories/javascript/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"},{"name":"基础","slug":"基础","permalink":"http://yoursite.com/tags/基础/"}]},{"title":"vue2.0仿去哪儿网移动端Webapp遇到的问题","slug":"vue2.0仿去哪儿网移动端Webapp遇到的问题","date":"2019-07-31T15:20:07.000Z","updated":"2019-08-01T02:52:01.197Z","comments":true,"path":"2019/07/31/vue2.0仿去哪儿网移动端Webapp遇到的问题/","link":"","permalink":"http://yoursite.com/2019/07/31/vue2.0仿去哪儿网移动端Webapp遇到的问题/","excerpt":"","text":"vue2.0仿去哪儿网移动端Webapp遇到的问题github地址:https://github.com/tedqin/Traveldemo:https://tedqin.github.io/Travel/ 使用vue2.0对去哪儿网的移动端web页面的复现,做个总结。 为什么使用单页面应用多页面应用 每次页面跳转,后端返回一个新的html 优点:首屏时间快、seo效果好(搜索引擎可以识别跳转的多个链接) 缺点:页面切换慢(每次跳转需发送http请求) 单页面应用 js感知路由变化,动态清除页面内容并将新页面渲染 优点:页面切换快 缺点:首屏时间慢,seo差 移动web端配置 使用rem单位 防止手指放大缩小页面,修改index.js <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> 组件开发合理拆分组件,提高开发效率。父组件通过import方式导入子组件,并且 export default { name: 'xxx', components: {注册子组件名} 插槽使用场景:当组件的内容希望父组件去定制 stylusstyle库,增加开发效率。其中,.a >>> .b具有穿透scoped限制的效果 防抖为了防止图片加载的过程中,页面抖动(图片未加载完毕的时候,文字会在上方,加载完毕后会抖动) .wrapper width: 100% height: 0 overflow: hidden padding-bottom: 26.7% //图片的宽高比 vuex进行非父子组件数据传递一般使用vuex中有几个关键:单向数据的改变过程state存放公用数据,组件改数据必须调用actions,做一些异步处理或者批量的同步操作。然后actions调用mutations,只有通过改变mutations的值才能改变state 在state中设置默认值 attr = 'aaa' 在组件中通过dispatch向actions派发数据(如果没有异步请求,可以直接使用commit,跳过这步) this.$store.dispatch('actionsName', data) 在actions中通过commit向mutations发送数据 actionnName(tcx, data) { tcx.commit('mutationsName', data) } 然后在mutations中修改state中的值 mutationsName(state, data) { state.attr = data } 高级使用 引入mapState, mapMutations import [mapState, mapMutations] from 'vuex 把mapState添加到计算属性(compute)中,把mapMutations添加到方法(methods)中 computed: { ...mapState({ currentCity: 'city }) }, methods: { ...mapMutations( ['changeCity'] ) } axios发送ajax请求 使用生命周期函数mounted函数获取ajax数据,此时vue实例被挂载,但dom还没有渲染,可以节省性能 请求url:axios.get('xxx/xxx.json') axios返回的是promise对象,可以使用then methods: { getCityInfo () { axios.get('/Travel/static/mock/city.json') .then(this.handleGetCityInfoSucc) }, handleGetCityInfoSucc (res) { res = res.data if (res.ret && res.data) { const data = res.data this.cities = data.cities this.hotCities = data.hotCities } ... 对以上代码的解释: 在mounted钩子函数里面定义一个A方法,只要页面加载完毕就执行A方法 A方法用于获取后端的数据,它是一个promise函数,只要获取到了函数就then一个B函数 B函数可以接收一个res参数,这个参数就是返回的结果 ajax请求一般放在最外层的组件,这样只需要一次请求就可以获取所有页面的内容 ajax获取动态数据 在路由里的地址后面写:id,表示把对应的id参数存在了id变量中 在获取ajax请求的地址上,可以写axios.get('xxx/xxx.json?id=' + this.$route.params.id) 也可以写axios.get('xxx/xxx.json', {params: {id: this.$route.params.id}}) router-link vue中的内置路由组件 <router-link to='/city'></router-link> 使用前先在router/index.js中配置路由 可以通过配置tag属性改成别的标签 单行内容超出范围当单行文字内容超出显示范围,而显示......时,可以 overflow: hidden white-space: nowrap text-overflow: ellipsis betterscroll页面滚动插件 函数节流当鼠标在字母表上来回移动的时候,touchMove执行的频率是非常高的,通过函数节流限制下执行的频率:增加延时器 localstorage自动缓存,刷新页面的时候已经选择的城市不发生改变 相当于cookie,但是用法要简单很多 用法: localStorage.arrt = va;ue 最好使用try catch包裹,因为在部分浏览器会报错 keepalive优化问题:缓存页面数据,防止切换页面会发生多次ajax请求 <keep-alive> <router-view/> </keep-alive> 它的意思是,路由内容每被加载一次,就把路由中的内容放到内存之中,下一次再进这个路由的时候,不需要再次渲染这个组件去重新执行钩子函数,只需要你从内存把以前的内容拿出来显示到页面上就可以 组件中name属性 在递归组件时使用 keepalive取消缓存在exclude=’组件name’中使用 vue devtool调试工具中显示项目结构的名字 组件异步加载正常情况下,单页应用会在进入首页时加载所有组件可以删除import特定的组件,然后通过component: () => import('@/pages/home/Home)按需加载 全局事件解绑 window是全局事件,无论那个页面都会监听这个事件,会影响到其他页面,所以要解绑 在有keep-alive时会出现两个新的钩子函数: activated 在页面被显示时执行 deactivated 在页面即将被隐藏或页面被替换的时候执行 简写 @表示src目录 es6中,键值对相同写一个就可以 组件一览 home Header 头部 Icon 原型图标区域 Recommend 推荐 Swiper 图片轮播 Weekend 周末推荐 city Header 头部 Alphabet 右侧城市首字母下拉列表 List 城市列表 Search 搜索 detail Header 头部 Banner 主页面 List 图片详情页的轮播 部署到GitHub pages参考 https://medium.com/@Roli_Dori/deploy-vue-cli-3-project-to-github-pages-ebeda0705fbd webpack后期更新","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"},{"name":"vue","slug":"前端/javascript/vue","permalink":"http://yoursite.com/categories/前端/javascript/vue/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"},{"name":"vue","slug":"vue","permalink":"http://yoursite.com/tags/vue/"}]},{"title":"javascript整理","slug":"javascript整理","date":"2019-07-15T13:23:22.000Z","updated":"2019-10-17T05:44:13.427Z","comments":true,"path":"2019/07/15/javascript整理/","link":"","permalink":"http://yoursite.com/2019/07/15/javascript整理/","excerpt":"","text":"闲来无事,把之前的笔记整理一下。 基础知识变量类型 值类型:a和b相等,改a,b不变 (直接赋值值) undefined string number boolean 引用类型:a和b相等,改a,b变 (赋值地址) object function 强制类型转换 字符串拼接 var a=10; var b=100 + '10'//string == 100=='100'; 0==''; null==undefined //true if if(b=100)//转换为true 逻辑运算符(&,||) 10&&0;''||'abc'; !window.abc//都转换为true或false 问题 typeof能得到哪些类型 number, string, object, boolean, function, undefiend, symbol (null是object) symbol: 可以生成永不重复的值,可以用一个字符串标记 何时使用===,何时使用== ===:内容相等数据类型也相同的严格模式;==:内容相等数据类型可以不相等 使用==的唯一情况:’’if(obj.a==null){}’’ 原型 原型链 构造函数 function Foo(name,age) {this.name=name; this.age=age return this} var f = new Foo('ted',20) var a ={}是var a =new Object()的语法糖//数组,函数同理 函数名大写字母开头 原型规则和示例 所有的引用类型(数组对象函数)都具有对象特性,即可自由扩展属性(null除外) 所有的引用类型都有一个__proto__属性,属性值是一个普通对象 所有的函数都有一个prototype属性,属性值也是一个普通的对象 __proto__对象指向它的构造函数的prototype对象(完全等于) 当试图得到一个引用类型的某个属性时,如果这个变量本身没有这个属性,那么会去它的__proto__,即它的构造函数的prototype中找 例子:不遍历原型上的属性:if(f.hasOwnProperty(item)) 原型链 一个对象,对象自身不存在的属性到它的隐式原型找,它的隐式原型不存的的话,再到它的隐式原型的隐式原型中找 Object.prototype指向null,防止死循环 instanceof instanceof判断一个函数是否是一个变量的构造函数 var f = new Foo('ted') f instanceof Foo//true 判断逻辑:f的__proto__一层层往上,能否对应到Foo.prototype 问题 如何准确判断一个变量是数组 var arr = [] arr instanceof Array//true 写一个原型链继承的例子 function Animal(){this.eat = function(){console.log('eat')}} function Dog(){this.bark(){console.log('bark')}} Dog.prototype=new Animal() var haski=new Dog() //这个比较low function Elem(id){this.elem=document.getElementById(id)} Elem.prototype.html=function(val) { var elem=this.elem if(val){ elem.innerHTML=val return this } else{ return elem.innerHTML}}</pre> Elem.prototype.on=function(type,fn){ var elem=this.elem elem.addEventListener(type,fn) </pre> var div1 = new Elem('div1') 描述new一个对象的过程 创建一个新对象 this指向这个新对象 执行构造函数的代码,即对this赋值 返回this 作用域 闭包 执行上下文 代码执行的环境 一段<script>:全局上下文 变量定义->函数申明 一个函数:函数上下文 变量定义->函数申明->this->arguments this this要在执行时才能确认值,定义时无法确认 call可以改变this的值:a.fn.call({name:B}) 1.作为构造函数执行:指向定义的对象 function Foo(name) {this.name = name}var f = new Foo(‘ted’) 2.作为对象属性执行:指向该对象 var obj = {name: ‘A’, printName: function () {console.log(this.name)}}obj.printName() 3.作为普通函数执行: 指向window function fn() {console.log(this)}} 4.call apply bind function fn1(name, age) {alert(name); console.log(this)}fn1(‘ted’,20)//普通函数的this,指向windowfn1.call({x:100},’ted’,20)//通过call函数改变this,指向{x:100}这个对象fn1.apply({x:200}, [‘ted’, 20])//apply和call不同在于参数用数组传递 //bind:适用于函数表达式 var fn2 = function (name, age) { alert(name); console.log(this)} .bind({y:300}) fn2('ted',20)//通过bind函数改变this,this也指向{y:300}这个对象 作用域 JS没有块级作用域 在函数中定义和赋值的变量可以在函数外使用 ES6中加入块级作用域:for(let i = 0; i< 10; i++){}console.log(i)//报错,let定义的变量有块级作用域,在for中定义的不能在for之外访问 JS有函数和全局作用域 定义在函数中的变量,只能在函数中修改 自由变量:当前作用域没有定义的变量,可以在父级作用域中去找 作用域链 当前作用域可访问父级作用域 一个元素的父级作用域是在它定义的时候的作用域,而非执行 闭包 函数作为返回值 函数作为参数传递 闭包中返回的函数,若有自由变量,则向(函数定义时)父作用域寻找 问题 说一下对变量提升的理解 在各个执行上下文中,变量定义+函数声明都会提前 说明this几种不同的使用场景 作为构造函数:指向定义的对象 作为对象属性:指向该对象 作为普通函数:指向window call apply bind: 指向改变的对象 创建10个<a>标签,点击的时候弹出来对应的序号 * 如何理解作用域 自由变量 作用域链,自由变量的查找 闭包的两个场景 闭包 实际开发中闭包的应用 封装变量,收敛权限 let isFirstLoad = function () { let _list = [] return function (el) { if (_list.indexOf(el) >= 0) { return false } else { _list.push(el) return true } } } let firstLoad = isFirstLoad() isFirstLoad(10) //true isFirstLoad(10) //false isFirstLoad(20) //true 异步和单线程 什么是异步(对比同步) 同步会阻塞,异步不会,遇到setTimeout会先执行后面的代码 何时使用:有可能发生等待的情况-等待的过程不能阻塞程序运行 前端使用异步的场景 定时任务:setTimeout,setInverral 网络请求:ajax请求,动态加载 (时间不固定) 事件绑定:如点击事件,在不点击的时候不能阻塞程序运行 异步和单线程 单线程:代码一个个排队执行,不能同时干两件事 js是单线程,所以在遇到阻塞的情况,要用异步,现将不需要等待的代码执行完,再执行异步代码 问题 同步和异步的区别是什么?分别举一个同步和异步的例子 同步会阻塞代码,异步不会,alert是同步,setTimeout是异步 一个关于setTimeout的笔试题 前端使用异步的场景有哪些? 定时任务-网络请求-时间绑定 补充 日期 Date.now() //获取时间戳 //2019/09/17/23:41:44 let dt = new Date() dt.getTime() //获取时间戳 dt.getFullYear() //2019 dt.getMonth() //8 (0-11) dt.getDate() //17 (0-31) dt.getHours() //23 (0-23) dt.getMinutes() //41 (0-59) dt.getSeconds() //44 (0-59) Math 获取随机数Math.random() 数组api forEach 遍历所有元素 every 判断所有元素是否都符合条件 some 判断是否有至少一个元素符合条件 sort 排序 map 对元素重新组装,生成新数组 filter 过滤符合条件的元素 对象api for in 题目 获取2019-07-25格式的日期 let formatDate = function (dt) { if (!dt) { dt = new Date() } let year = dt.getFullYear() let month = dt.getMonth() + 1 let date = dt.getDate() if (month < 10) { month = '0' + month } if (date < 10) { date = '0' + date } return year + '-' + month + '-' + date } let dt = new Date() console.log(formatDate(dt)) 获取随机数,要求是长度一致的字符串格式 //获取长度一致的随机数 let formatRandom = function () { let random = Math.random() random = random + '0000000000' return random.slice(0, 10) } console.log(formatRandom()) JS API JS语法标准(基础知识):ECMA 262标准 JS-WEB-API(浏览器):W3C标准 DOM操作 BOM操作:浏览器操作 获取当前地址 获取屏幕尺寸 事件绑定 AJAX请求(包括http协议) 存储 没有规定任何JS基础相关的东西 全面考虑,JS内置的全局函数和对象(浏览器打造) Object,Array,Boolean等 window document 所有未定义的全局变量,如navigator.userAgent DOM操作 DOM本质 浏览器拿到html代码后,把html结构化成浏览器可识别以及js可识别的东西,就是dom dom本质是js的对象 DOM节点操作 获取dom节点 //获取DOM节点 //get let id1 = document.getElementById('id1') //id let divs = document.getElementByTagName('div') //元素集合 let div0 = document.getElementByTagName('div')[0] //元素 let classes = document.getElementsByClassName('class1') //class集合 let class0 = document.getElementsByClassName('class1')[0] //class //query let id1 = document.querySelector('#id1') //id let divs = document.querySelectorAll('div') //元素集合 let div0 = document.querySelector('div') //元素,选择第一个div let div0 = document.querySelector('div')[0] //元素,选择第一个div let classes = document.querySelectorAll('.class0') //class集合 let class0 = document.querySelector('class0') //class,选择第一个class let class0 = document.querySelector('class0')[0] //class,选择第一个class property js对象中的属性 //获取attribute let p0 = document.quertSelectorAll('p')[0] console.log(p0.style.width) //获取样式 p0.style.width = '200px' //修改样式 console.log(p0.className) //获取class p0.className = 'p0' //修改class console.log(p0.nodeName) //p console.log(p0.nodeType) //1 attribute HTML文档中 标签的属性 //获取attribute let p0 = document.querySelectorAll('p')[0] p0.getAttribute('attr1') //获取p0上的attr1属性的值 p0.getAttribute('attr1', 'abc') //修改属性 p0.getAttribute('style') //获取style,元素上必须有style才行 p0.getAttribute('style', 'font-size:30px') DOM结构操作 新增节点 document.createElement(node) //添加新节点 let div1 = document.getElementById('div1') let p1 = documemt.createElement('p') div1.appendChild(div1) //移动现有节点 let p2 = document.getElementById('p2') div1.appendChild(p2) 获取父节点 childNode.parentElement let div1 = getElementById(div1) let parent = div1.parentElement 获取子节点 .parentNode.childNodes let div1 = getElementById(div1) let parent = div1.parentElement .childNodes返回所有节点包括文本和注释节点 .children只返回元素节点 删除节点 parentNode.removeChild(childNode) let div1 = getElementById(div1) let child = div1.childNodes //删除第一个子元素 div1.removeChild(child[0]) 问题 DOM是哪一种基本数据结构 数 DOM操作的常用API有哪些 获取DOM节点,以及节点的property和attr 获取父节点,子节点 新增,删除,移动节点 DOM节点的attr和property有何局别 property是js属性的修改和获取 attr是对html标签的修改和获取 BOM操作 navigator浏览器 判断浏览器类型 userAgent var ua = navigator.userAgentvar isChrome = ua.indexOf(‘Chrome’)console.log(isChrome) screen屏幕 console.log(screen.width) console.log(screen.height) location地址栏信息 拆解url location.href //url location.protocal //协议 http https location.host //域名 location.pathname //路径 /learn/199 location.search //url ? 后面的字符串 location.search //url # 后的hash history历史 前进后退 history.back history.forward 问题 如何检测目标浏览器的类型 let ua = navigator.userAgent let isChrome = ua.indexOf('Chrome') console.log(isChrome) 拆解url的各部分 location.href //url location.protocal //协议 http https location.host //域名 location.pathname //路径 /learn/199 location.search //url ? 后面的字符串 location.search //url # 后的hash Ajax XMLHttpRequest let xhr = new XMLHttpRequest() xhr.open("GET", "/api", "false") xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { alert(xhr.responseText) } } } xhr.send(null) 状态码说明 readyState == 4 ajax状态码 0-(未初始化)还没有调用send()方法 1-(载入)已调用send()方法,正在发送请求 2-(载入完成)send()方法执行完成,已经接收到全部响应内容 3-(交互)正在解析响应内容 4-(完成)响应内容解析完成,可以在客户端调用了 statue == 200 http标准状态码 2xx - 表示成功处理请求。如200 3xx - 需要重定向,浏览器直接跳转 4xx - 客户端请求错误,如404 5xx - 服务端错误 跨域 什么是跨域 浏览器有同源策略,不允许ajax访问其他接口,如http://www.a.com:80不能访问http://www.b.com 跨域条件:协议(http)、域名(www.a.com)、端口(:80)有一个不同就算跨域 可以跨域的三个标签 <img src=xxx> 用于打点统计,统计网站可能是其他域 <link href=xxx> 可以使用CDN,CDN也是其他域 <script src=xxx> 可以使用CDN,CDN也是其他域 可以用于JSONP JSONP 前端 <!-- jsonp跨域 --> <script> function callbackFunc (data) { alert(data) } </script> <script src="http://www.baidu.com/api/data.js"></script> 前端定义一个callback函数,得到信息。再用script标签获取一个跨域的信息,这个信息会调用callback({x:100, y:200}) 服务器端设置http header 后端 //后端通过设置httpheader跨域 response.setHeader("Access-Control-Allow-Origin", "http://a.com, http://b.com"); response.setHeader("Access-Control-Allow-Headers", "X-Requested-With"); response.setHeader("Access-Control-Allow-Methods", "PUT, POST,GET, OPTIONS, DELETE"); //允许接收跨域的cookie response.setHeader("Access-Control-Allow-Credentials", "true"); 问题 手动编写一个ajax,不依赖第三方库 前面有 跨域的几种实现方式 JSONP 服务器端设置http header 事件绑定 通用事件绑定 //通用事件绑定函数 function bindEvent (elem, type, fn) { elem.addEventListener(type, fn) } let a1 = document.getElementById('a1') bindEvent(a1, 'click', function (e) { e.preventDefault() alert('clicked') }) 事件冒泡 若底层和父层节点有相同绑定事件,底层业务节点的事件(如点击)会先执行,然后会一层层网上执行,先执行底层的事件,然后上一层的事件,然后… 点击激活弹出激活,点击取消弹出取消(e.stopPropatation():阻止冒泡) 代理 事件冒泡的应用 点击a标签的元素,会弹出相应文字 ` <!DOCTYPE html> propogation a1 a2 a3 a4 let div1 = document.getElementById(“div1”) div1.addEventListener(“click”, function(e) { alert(e.target.innerHTML) }) ``` (这里target可以定位到当前点击的元素) 问题 编写一个通用的事件监听函数 描述事件冒泡流程 dom树形结构 冒泡 阻止冒泡 应用:代理 对于一个无限下拉加载图片的页面,如何给每个图片绑定事件 使用代理:代码简洁,对浏览器压力小 存储 cookie 属于http的东西,本身用于客户端和服务端通信 但是它有本地存储的功能,于是被“借用” 使用document.cookie=...获取和修改即可 限制: 存储量太小,只有4kb 所有http请求都带着,会影响获取资源的效率 API简单,需要封装才能用document.coockie sessionStorage和localStorage H5专门为存储而设计,最大容量5M API简单易用,key+value localStorage.setItem(key,value) localStorage.getItem(key) 问题 描述一下cookie(h5之前),sessionStorage和localStorage的区别 cookie和后两者的区别 容量 是否会携带到ajax请求中 API易用性 后两者的区别 localStorage不会主动删除,sessionStorage随着每次会话结束会清除,95%的场景存储到localStorage中 开发环境IDE(写代码的效率) webstorm sublime vscode atom git 版本管理,多人协作 常用命令 git add . git checkout xxx git commit -m ‘xxx’ //提交到本地仓库 git push origin master git pull origin master git branch git checkout -b xxx git merge xxx js模块化 不适用模块化的情况 如果a.js, b.js, c.js, c依赖b,b依赖a,引用的时候必须要按顺序,如果顺序错就会报错 引用的文件的变量必须是全局变量,容易被污染 使用模块化 a.js 传递出别人所需要的功能函数,b和a需要哪个函数引用哪个函数 引用的时候直接引用最表层的js文件即可 AMD 异步模块定义规范 require.js 全局define函数 全局require函数 依赖的js会自动、异步加载 ` //util.js define(function() { return { func: function () { return 1 } } }) //a-utils.js define([‘./utils.js’], function(util) { return { func2: function () { return util.func() } } }) ``` * html用:``<script src="/require.js" data-main="./main.js"></script> `` * 好处:异步加载,不使用(依赖)就不加载 CommonJs nodejs模块化规划,现在被大量用于前端 前端开发依赖的插件和库,都可以用npm中获取 构建工具的高度自动化,使得使用npm的成本非常低 CommonJS不会异步加载js,而是同步一次性加载出来 //util.js module.exports = { func: function () { return 1 } } //a-util.js let util = require('./util.js') module.exports = { func2: function () { return utils() } } AMD和CommonJS的使用场景 需要异步加载,用AMD 使用了npm之后建议使用CommonJs 打包工具 webpack 启动一个服务,先全局安装,npm install http-server =g,然后在要访问的页面根目录启动服务 http-server 8080 npm init 初始化,完成后多处package.json文件 npm install webpack --save -dev 安装webpack 配置webpack 创建webpack.config.js var path = require('path') var webpack = require('require') module.exports = { context: path.resolve(__dirname, './src'), extry: { app: './app.js' }. output: { path: path.resolve(__dirname, './dist') filename: 'bundle.js' } } 创建src app.js等文件 在package.json scripts里加入”start”: “webpack”,就可以在命令行执行start进行打包输出 webpack进行代码压缩: 在config的exports中追加plugins: [new webpack.optimize.UglifyJsPlugin()] webpack的主要作用: 代码合并:合并commonjs的语法规范,否则前端无法识别 代码压缩:保证代码上线 上线回滚的流程 上线的基本流程 将测试完成的代码提交到git版本库的master分支 将当前服务器的代码全部打包并记录版本号,备份 将master分支的代码提交覆盖到线上服务器,生成新版本号 回滚的基本流程 将当前服务器的代码全部打包并记录版本号,备份 将备份的上一个版本号解压,覆盖到线上服务器,并生成新的版本号 linux基本命令 mkdir ls ll 列表形式的ls pwd cd cd .. rm -rf 文件夹名 //删除当前目录下所有文件 vi a.js //创建并进入a.js i //insert : //最下行 w //写 q //退出 cp a1 a2 //创建a2,把a1复制到a2 mv a1 f1 //把a1移动到f1文件夹 cat a1 //查看当前文件 grep ‘2’ a.js //查找a.js中的2 运行环境页面加载过程 加载资源的形式 输入url(或跳转页面)加载html 加载html中的静态资源 如<script><img> 加载一个资源的过程 浏览器根据DNS服务器得到域名的IP地址 向这个IP的机器发送http请求 服务器收到、处理并返回http请求(图片,html js代码,) 浏览器得到返回的请求并渲染 浏览器渲染页面的过程 根据HTNL结构生成DOM树 根据CSS生成CSSOM(结构化处理) 将DOM和CSSOM整合成RenderTree(渲染树,每个节点都规定了样式) 根据RenderTree开始渲染和展示 遇到<script>时,会执行并阻塞渲染 题目 从输入url到得到html的详细过程 根据DNS得到域名IP-向该IP发送请求-服务器收到处理返回请求-浏览器得到返回内容 window.onload和DOMCotentLoaded的区别 onload:页面全部资源加载完,包括图片视频等才会执行 CotentLoaded:DOM渲染完即可执行,图片还没有加载完 为什么把css文件放在head中? 因为渲染默认是顺序的,保证在渲染body时候浏览器已经知道对应的样式了 为什么把js放在body最下面? 不会阻塞之前body中html的渲染 保证script能拿到所有的html节点标签 性能优化 基本2点 多使用内存、缓存或者其他方法 -开源 减少CPU计算、减少网络 -节流 加载资源优化 静态资源的压缩合并 合并:将多个js文件合并成一个js 压缩:压缩体积 静态资源缓存 通过连接名称,名称不变的话,浏览器会加载之前同名的缓存 使用CDN让资源加载更快 不同区域的网络优化,上海转到上海的节点等等 使用SSR后端渲染,数据直接输出到HTML中(不同ajax请求数据) 页面渲染优化 CSS放前面,JS放后面 懒加载(图片懒加载,下拉加载更多/先用一张模糊的图片代替原图,要用的时候再加载) 什么时候用什么时候加载 减少DOM查询,对DOM查询做缓存 减少DOM操作,多个操作尽量合并在一个执行 先创建一个片段frag=document.createDocumentFragment() 事件节流 间隔一段时间执行一次 如键盘输入,在ns内执行一次事件, 不停的输入,也会在一段时间后输出一次 //时间戳版 function throttle(fn, delay) { let previous = 0 return function (args) { let _args = args let _this = this let now = Date.now() if (now-previous > wait) { fn.call(_this, _args) previous = now } } } 事件防抖 超过一段时间不输入,执行一次 防止输入一个就输出一个这样的抖动情况,设置一个延迟,超过这个延迟不执行输入的情况下,才会执行输出。也就是输入一堆,停5ms不输入以后,才会输出 function debounce (fn, delay) { let timeout return function (args) { let _this = this let _args = args clearTimeout(timeout) timout = setTimeout(function (_args, _this) { fn.call(_this, _args) }, delay) } } //使用防抖 function print (content) { console.log(content) } let input = document.getElementById('text') let debounceInput = debounce(print, 100) input.addEventListener('keyup', function () { debounceAjax(e.target.innerHTML) }) 尽早执行操作(DOMCotentLoaded) 安全性 XSS跨站请求攻击 新浪博客写一篇文章,同时偷偷插入一段攻击代码<script> 攻击代码中,获取查看者的cookie,发送到自己的服务器 XSS预防 前端替换关键字,例如替换<为&lt;>为&gt 后端替换 XSRF跨站请求伪造 你已登录一个购物网站,正在浏览商品 付费接口是xxx.com/pay?id=100但是没有任何验证 你收到一封钓鱼邮件,隐藏着<img src='xxx.com/pay?id=100'> 查看邮件的时候,就悄悄付费了 XSRF预防 增加验证流程,如输入指纹、密码、短信验证码 问题 前端安全问题的场景有哪些 面试技巧 简历 简介明了,重点突出项目经历和解决方案 把个人博客放在简历中,并且定期维护更新博客 把个人的开源项目放在简历中,并维护开源项目 不能造假,要保证能力和经历上的造假 谈谈你的缺点 说一下最近正在学的东西,比如我对vue不是很了解,正在学vue.js 面试题 window.onload和DOMCotentLoaded的区别 onload事件触发:页面上所有dom,样式表,脚本,图片,flash都已经加载完;DOMCotentLoaded:仅dom加载完 如何理解JSON 是一个JS对象,有两个API: JSON.stringify(obj)//将js的对象转换成json字符串 JSON.parse('{"a":5}')//json字符串转js对象 是一个数据格式 js有哪些内置函数 Object Array Boolean Number String Function(以上为构造函数) Date RegExp Error new一个vue对象发生了什么? 执行this._init()方法,初始化对象: 合并配置options 初始化生命周期 初始化事件中心 初始化渲染 初始化data,props,computed,watcher等 初始化完成,检查如果有el属性,就调用vm.$mount方法挂载 promise一种异步解决方案,类似一个容器,包括未来会执行的任务 .then()参数1为resolve的内容,参数2(可以不要)为reject的内容 .catch()用于resolve有错误的情况,一般用在.then的最后 .finally()用于不管promise最后状态如何都执行的操作 .all()用于将多个promise包装成一个const p = Promise.all([p1, p2, p3]); 必须等三个都resolve,p才resolve,而有一个reject p就reject 场景:几个任务时间不一样,需要等全部完成才执行下一个任务 .race()Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。const p = Promise.race([p1, p2, p3]) 只要有一个resolve了,就算完成 场景:把异步操作和定时器绑定,如果定时到了异步操作还没完成就报错 .resolve()将对象转换为promise对象,状态为resolvelet jsPromise = Promise.resolve(para) param: promise对象,直接返回不做修改 thenable对象:有then: function(resolve, reject){resolve()}的对象,直接封装,立即执行then 普通对象:直接封装,状态为resolve .reject()将对象转换为promise对象,状态为reject .try()模拟try代码块","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"}]},{"title":"DCGAN进行图像修复","slug":"DCGAN进行图像修复","date":"2019-07-10T04:12:51.000Z","updated":"2019-09-19T09:33:02.161Z","comments":true,"path":"2019/07/10/DCGAN进行图像修复/","link":"","permalink":"http://yoursite.com/2019/07/10/DCGAN进行图像修复/","excerpt":"","text":"本文已置于https://github.com/tedqin/GAN-ImageRepairing 总体设计 和典型的使用神经网络来实现目的方法一样,简单来讲,基于DCGAN的图像修复首先需要先训练出一组优秀的生成器和判别器,然后利用这一组训练好的模型进行图像修复。首先第一步需要进行图像预处理,这是因为DCGAN的模型结构决定了图像的尺寸大小是64”×” 64”×” 3,进行图像预处理之后,由于神经网络需要矩阵形式的输入,所以修复流程的首要步骤就是将图像分解为样本点,这个步骤可以由判别器的卷积实现,然后生成器和判别器进行博弈,得到训练好的模型,由生成器快速生成伪造的图像,然后建立适当的损失函数和惩罚因子来寻找修复图像所需要的最佳伪造图像。由此,总的系统流程主要可以分为三步: 图像预处理。 训练DCGAN模型。 找到补全原图像所需要的最佳伪造图像,进行图像修复。 图像预处理Openface预处理Openface是一个基于深度神经网络的开源人脸识别系统。 用OpenCV或者dlib中预训练好的模型检测人脸 将人脸迁移到神经网络。利用dlib的实时姿态估计与OpenCV的仿射线变换来使人脸的眼睛和嘴唇出现在每个图像上的相同位置。 使用深度神经网络将面部表示(或嵌入)在128维单位超球面上。这种嵌入方法可以通用于任何人脸表示上面。与其他的一些人脸表征方法不同,这种人脸嵌入方法具有很好的性质,两个嵌入人脸间的距离较大就意味着这两幅面孔可能不是来自于同一个人。 运用Openface来消除除了人脸外的其他的因素,比如背景、发型等等,然后移动图像,使得数据集中的每个人的人脸区域居于整张图片的中央。 构建掩膜为了能够评估修复结果,需要知道被损坏图像之前的样子。我采用给未损坏图像一个二进制掩膜来作为损坏区域,这样就可以在修复掩膜之后,对比修复前的图像进行修复效果评估。 训练 训练过程中,定义了一个采样器,在每一个epoch训练完成以后,用采样器对生成器进行采样并且保存样例图像 在20个epoch训练完成以后,生成的图像效果已经比较好,此时生成器和判别器的损失函数变化如图 修复部分结果如下:","categories":[{"name":"machine learning","slug":"machine-learning","permalink":"http://yoursite.com/categories/machine-learning/"},{"name":"gan","slug":"machine-learning/gan","permalink":"http://yoursite.com/categories/machine-learning/gan/"}],"tags":[{"name":"python","slug":"python","permalink":"http://yoursite.com/tags/python/"},{"name":"machine learning","slug":"machine-learning","permalink":"http://yoursite.com/tags/machine-learning/"}]},{"title":"知识整理CSS","slug":"知识整理css","date":"2019-06-01T08:19:02.000Z","updated":"2019-10-16T16:59:19.064Z","comments":true,"path":"2019/06/01/知识整理css/","link":"","permalink":"http://yoursite.com/2019/06/01/知识整理css/","excerpt":"","text":"CSS选择器标签:p{}class: .class{}id:#id {}同一标签,多个类:p.class1{} .class2{集体选择器:p,.class1,#id1 {}后代选择器(选择子孙代):p em a {}子代选择器(只能选择子代):div > p相邻选择:div + p通配符选择:*否定选择:not(.link) {}属性选择器:[title] {}伪类选择::link {}链接伪类 ``:link``:未访问的链接 ``:visited``:已访问的链接 ``:hover``:鼠标悬停状态 ``:active``:鼠标点击到松开的阶段 (hover和active可用于任何标签)伪元素选择:::before {} 权重 !important 优先级最高,但也会被权重高的important所覆盖 行内样式总会覆盖外部样式表的任何样式(除了!important) 如果两个相同权重的选择器作用在同一元素上:以后面出现的选择器为最后规则,以与元素距离近的选择器为最后规则 一句话总结: !important > 行内样式 > ID选择器 > (类选择器 | 属性选择器 | 伪类选择器 ) > 元素选择器 | 伪元素选择弃 > * css3 属性选择器 选择器 描述 [attribute] 用于选取带有指定属性的元素。 [attribute=value] 用于选取带有指定属性和值的元素。 [attribute~=value] 用于选取属性值中包含指定词汇的元素。 `[attribute =value]` 用于选取带有以指定值开头的属性值的元素,该值必须是整个单词。 [attribute^=value] 匹配属性值以指定值开头的每个元素。 [attribute$=value] 匹配属性值以指定值结尾的每个元素。 [attribute*=value] 匹配属性值中包含指定值的每个元素。 伪类和伪元素区别伪类值一种状态,用于选择DOM树之外的信息,或是不能用简单选择器进行表示的信息。前者包含那些匹配指定状态的元素,比如:visited,:active;伪类将特殊的效果添加到特定选择器上。它是已有元素上添加类别的,不会产生新的元素。例如: a:hover {color: #FF00FF} p:first-child {color: red} 伪元素是DOM树没有定义的虚拟元素,是一个真实存在的元素,他可以有样式有内容伪元素在内容元素的前后插入额外的元素或样式,但是这些元素实际上并不在文档中生成。它们只在外部显示可见例如: p::before {content:"第一章:";} p::after {content:"Hot!";} p::first-line {background:red;} p::first-letter {font-size:30px;} 换句话说伪类和伪元素的区别就是伪类的操作对象是文档树中已有的元素,而伪元素则创建了一个文档树以外的元素。 浏览器解析CSS.wrapper div > p CSS中,浏览器查找元素是通过选择权从后往前找的, 这样做的目的是加快CSS解析速度,从后往前,排除法 盒子模型盒模型有两种, W3C标准盒子模型、IE 怪异盒子模型; 盒模型是由: 内容(content)、内边距(padding)、边框(border)、外边距(margin) 组成的。 标准模型的宽高是指的content区宽高; IE盒模型的宽高是指的content+padding+border的宽高。 盒子模型类型 box-sizing: border-box | content-box border-box:width的值为width=width content-box:width的值为width=border+padding+content height:长度/百分比/auto width: border边框 边框粗细border-(top/l/r/bottom)-width: thin/medium/thick/长度值 边框颜色 border-color: 样式border-style: none/solid实线/dotted点状 简写: 粗细-样式-颜色 padding内边距 主要用来设置空隙 盒子与边框的距离 padding粗细padding-(top/l/r/bottom): thin/medium/thick/长度值 padding粗细简写:全/上下 左右/上 左右 下/上 右 下 左 margin外边距 边框与外界的距离 可以为负值 设置为auto:实现水平方向居中 bfcW3C对BFC定义: 浮动元素和绝对定位元素,非块级盒子的块级容器(例如 inline-blocks, table-cells, 和 table-captions),以及overflow值不为“visiable”的块级盒子,都会为他们的内容创建新的BFC(块级格式上下文)。 BFC(Block formatting context)直译为”块级格式化上下文”。它是一个独立的渲染区域,只有Block-level box参与, 它规定了内部的Block-level Box如何布局,并且与这个区域外部毫不相干。 BFC作用: 利用BFC避免外边距折叠 清除内部浮动 (撑开高度) 原理: 触发父div的BFC属性,使下面的子div都处在父div的同一个BFC区域之内 避免文字环绕 分属于不同的BFC时,可以阻止margin重叠 多列布局中使用BFC 如何生成BFC:(脱离文档流,满足下列的任意一个或多个条件即可) 根元素,即HTML元素(最大的一个BFC) float的值不为none position的值为absolute或fixed overflow的值不为visible(默认值。内容不会被修剪,会呈现在元素框之外) display的值为inline-block、table-cell、table-caption 非布局样式文字粗细:font-weight: normal/bold文字斜度:font-style: normal/italic/oblique文字粗细:font-weight: 600字重(粗体)font-weight斜体 font-style下划线 text-decoration指针 cursor 滚动 visible 滚动条隐藏, 文字超出显示 hidden 滚动条隐藏, 文字超出不显示 scroll 滚动条一直显示,无论文字是否够多 auto 滚动条自动隐藏 文本对齐方式文本水平对齐方式:text-align: left/right/center/justify左对齐/右对齐/居中对齐/两端对齐 只对块级元素有效 行高首行缩进:text-indent: 2em行高:line-height: 120em 最好用em防止字体过大导致显示不全注意:图片是按照inline元素做的排版,会涉及字体对齐,默认按照baseline对齐,和底线有空隙。 为了删除这个空隙,可以直接vertical-align: bottom或者display: block 行高的构成行高是由 line-box 组成的line-box 是由一行里的 inline-box 组成的inline-box中最高的那个,或字体最大的拿个决定行高 你对 line-height 是如何理解的? line-height 指一行字的高度,包含了字间距,实际上是下一行基线到上一行基线距离 如果一个标签没有定义 height 属性,那么其最终表现的高度是由 line-height 决定的 一个容器没有设置高度,那么撑开容器高度的是 line-height 而不是容器内的文字内容 把 line-height 值设置为 height 一样大小的值可以实现单行文字的垂直居中 line-height 和 height 都能撑开一个高度,height 会触发 haslayout(一个低版本IE的东西),而 line-height 不会 line-height 三种赋值方式有何区别?(带单位、纯数字、百分比) 带单位:px 是固定值,而 em 会参考父元素 font-size 值计算自身的行高 纯数字:会把比例传递给后代。例如,父级行高为 1.5,子元素字体为 18px,则子元素行高为 1.5 * 18 = 27px 百分比:将计算后的值传递给后代 浮动 可以让行内元素形成块级元素 元素”浮动” 脱离文档流 不脱离文本流 位置尽量靠上,并靠左或右 脱离文档流,只能左右 float:left/right/none 对自己的影响 形成”块”(BFC) 这个块会负责自己的布局,宽高由自己决定。比如 span 中用 float 这个span就形成了一个BFC,就可以设置宽高了 浮动后出现的问题: 浮动溢出(高度塌陷) 解决:清除浮动 clear:none/left/right/both 1.给父元素添加overflow:hidden 使父元素变成一个bfc,同时需要父元素指定宽度 2.css3 clearfix :after 使用伪元素 .clearfloat:after{ display:block; clear:both; content:""; visibility:hidden; height:0} .clearfloat{zoom:1} 3.结尾添加一个空行 <div class="parent"> <div class="left">Left</div> <div class="right">Right</div> <div class="clearfloat"></div> </div> <style> .left {float:left} .clearfloat{clear:both} </style> inline-block的间隙两个并列的inline-block中间会有一条裂缝,这个的原因是两个标签之间有空格,浏览器把这些空格当成文字中空格,所以这两个块中间多少有间隙。 解决办法: 删除两个标签间的空格,但是这样html排版不好 容器元素font-size: 0 然后再在里面再重新设置字体大小 元素内容的垂直方式只对行内元素有效vertical-align: sub/supper/文字向上向下对齐 单行文本溢出显示省略号 overflow: hidden; text-overflow: ellipsis; white-space: no-wrap; 多行文本溢出显示省略号 overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; display属性将元素显示为内联元素: inline将元素显示为块级元素: block将元素显示为内联元素具有快级属性可以设置宽高: inline-blockinherit 规定应该从父元素继承 display 属性的值none 此元素将显示为块级元素,此元素前后会带有换行符。list-item 象块类型元素一样显示,并添加样式列表标记。table 此元素会作为块级表格来显示 ps:宽高设为100%,表示和父元素相同 display: none; 与 visibility: hidden; 的区别结构: display:none 会让元素完全从渲染树中消失,渲染的时候不占据任何空间, 不能点击 visibility: hidden 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,不能点击 opacity: 0 不会让元素从渲染树消失,渲染元素继续占据空间,只是内容不可见,可以点击 继承 display: none和opacity: 0 非继承属性,子孙节点消失由于元素从渲染树消失造成,通过修改子孙节点属性无法显示。 visibility: hidden 继承属性,子孙节点消失由于继承了hidden,通过设置visibility: visible;可以让子孙节点显式。 性能 display:none 修改元素会造成文档回流。读屏器不会读取display: none元素内容,性能消耗较大 visibility:hidden 修改元素只会造成本元素的重绘,性能消耗较少。读屏器读取visibility: hidden元素内容 opacity: 0 修改元素会造成重绘,性能消耗较少 相同点: 它们都能让元素不可见、他们都依然可以被 JS 所获取到 CSS预处理器 嵌套 反映层级和约束 变量和计算 减少冗余代码 entend和mixin 代码片段重用 mixin是直接把CSS代码每个地方重复写一份 extend是使用逗号分割的选择器来为多个不同的地方使用同一段CSS 循环 适用于复杂有规律的样式 import CSS模块化 常见三种css预处理器:sass less stylus CSS单位 px 绝对单位。传统上一个像素对应于计算机屏幕上的一个点,而对于高清屏则对应更多。 % 父元素宽度的比例。 如果对 html 元素设置 font-size 为百分比值,则是以浏览器默认的字体大小16px为参照计算的(所有浏览器的默认字体大小都为 16px),如62.5%即等于10px(62.5% * 16px = 10px)。 em 相对单位。 不同的属性有不同的参照值。 对于字体大小属性(font-size)来说,em 的计算方式是相对于父元素的字体大小 border, width, height, padding, margin, line-height)在这些属性中,使用em单位的计算方式是参照该元素的 font-size,1em 等于该元素设置的字体大小。同理如果该元素没有设置,则一直向父级元素查找,直到找到,如果都没有设置大小,则使用浏览器默认的字体大小。 rem 是相对于根元素 html 的 font-size 来计算的,所以其参照物是固定的。 好处:rem 只需要修改 html 的 font-size 值即可达到全部的修改,即所谓的牵一发而动全身。 vw, vh, vmin, vmax 相对单位,是基于视窗大小(浏览器用来显示内容的区域大小)来计算的。 vw:基于视窗的宽度计算,1vw 等于视窗宽度的百分之一 vh:基于视窗的高度计算,1vh 等于视窗高度的百分之一 vmin:基于vw和vh中的最小值来计算,1vmin 等于最小值的百分之一 vmax:基于vw和vh中的最大值来计算,1vmax 等于最大值的百分之一 CSS 优化、提高性能的方法有哪些? 多个 css 合并,尽量减少 HTTP 请求 css 雪碧图 抽象提取公共样式,减少代码量 选择器优化嵌套,尽量避免层级过深 (用‘>’替换‘ ’) 属性值为 0 时,不加单位 压缩CSS代码 避免使用 CSS 表达式 它们要计算成千上万次并且可能会对你页面的性能产生影响。 position 定位模型 static:常规流 忽略跑偏移量(忽略 top, bottom, left, right - z-index 声明) inherit 规定从父元素继承 position 属性的值 relative: 相对相对于其正常位置进行定位。设置偏移量 top/bottom/left/right:10px 常规流的位置会留下,不会影响其他元素;也就是如果因为它的移动空出来了区域,其他的元素不会填充 absolute:绝对定位 相对于值不为 static 的第一个父元素进行定位。 常规流的位置会被占据,会影响其他元素;也就是如果因为它的移动空出来了区域,其他的元素会填充 如果设置上下左右偏移量为0,margin:autoauto,子元素就会相对于父元素居中 常用: 父元素设置为relative,子元素设置为absolute,子元素就可以设置相对于父元素的偏移量 fixed:相对定位 相对于浏览器窗口进行定位。不会随着视图滚动而滚动,其余和absolute一样 后三者可以设置z-index DOM层级顺序与z-indexDOM层级顺序,大概来说就是DOM节点在z轴方向(垂直于屏幕向外的方向)的显示优先级。为了调整DOM层级顺序,我们想到的往往就是用CSS的z-index属性来控制。dom层级顺序规则: 顺序规则 在不设置position属性(或设置成static)的情况下,文档流后面的DOM节点会覆盖前面的DOM节点。 定位规则 定位节点(position属性设置为relative,absolute或fixed的节点)会覆盖非定位节点(不设置position属性或position属性设为static的节点) 参与规则 z-index属性仅对定位节点生效。(使用position的节点) 有三个DOM节点,其定位为static。但是A的z-index最大,但是依旧是在最底部,C的z-index最小,而在最顶部,因此可知z-index并未生效,此时为顺序规则在生效。 默认值规则 z-index设为0和没有设置z-index的节点在同一层级内没有高低之分。在IE6和7种,z-index的默认值为0,其他浏览器中默认值为auto。 从父规则 两个节点A和B都是定位节点,如果节点A的z-index值比节点B的大,那么节点A的子元素都会覆盖在节点B以及节点B的子节点上。 link 与 @import 的区别 link 属于 XHTML 标签,除了加载 CSS 外,还能用于定义 RSS, 定义 rel 连接属性等作用;而@import 是 CSS 提供的,只能用于加载 CSS; 页面被加载的时,link 会同时被加载,而@import 引用的 CSS 会等到页面被加载完再加载; import 是 CSS2.1 提出的,只在 IE5 以上才能被识别,而 link 是 XHTML 标签,无兼容问题; link 支持使用 js 控制 DOM 去改变样式,而@import 不支持; 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 CSS3新特性 新增的选择器: 元素选择器 子元素选择器:father > son1 {} 相邻兄弟元素选择器:father > son1 + son2 {} 通用兄弟选择器: father > son1 ~ son5 {} 群组选择器: father > son1, father > son2, father > son3 {} 属性选择器 a[href] {} 伪类选择器 动态伪类(之前有): 锚点伪类 a:link{} a:visited{} 用户行为伪类 :hover :active :focus UI元素状态伪类 input:enabled {} :disabled :checked 结构类选择器 first/last子类选择器section:fi<div class="a2">123 </div><div class="a2">123 </div><div class="a2">123 </div><div class="a2">123 </div>rst-child {} 父元素的第N个子元素ul>li:nth-child(3){} 选择多个: nth-child(n){} 弹性盒模型 display: flex; 边框与圆角 圆角 border-radius:10px/10rem/10% 盒阴影 box-shadow:水平偏移 垂直偏移 模糊 扩展 颜色 边界图片 border-image:source 文本 文本阴影 text-shadow:h v blur color 自动换行 word-break 文本属性 字体 @font-face @font-face {font-familt:<name> src:<source> [<format>]} transform 转换 旋转transform:rotate(<angle>) 平移trandform:translate(x,y) trandform:translateX(200px) trandform:translateY(200px) 缩放:水平 垂直 都有 trandform:scaleX(.5) 扭曲: 三种 skewX(<angle>)`` 3D transform rotateX translate3d(x,y,z) scale3d(x,y,z) scaleZ(z) 动画 transition 补间动画 两个状态 keyframe 关键帧动画 有很多状态 逐帧动画 没有补间 如何水平/垂直居中一个元素? 水平居中 如果需要居中的元素为inline或inline-block,为父元素设置 text-align: center;即可实现 如果要居中的元素为一个块级元素的话,一般使用 margin: 0 auto; 进行居中。 垂直居中 对于绝对定位元素,直接宽高减去一半 #d1 { width: 100px; height: 100px; position: absolute; top: 50%; left: 50%; margin-left: -50px; margin-top: -50px; background: red } 用css3的transform,无需知道宽高 width: 100px; height: 100px; position: absolute; top: 50%; left: 50%; transform: translate( -50%, -50%); background: red 相对定位元素,先水平居中再垂直 li 与 li 之间有看不见的空白间隔是什么原因引起的?有什么解决办法?(也称幽灵字符)行框的排列会受到中间空白(回车\\空格)等的影响,因为空格也属于字符, 这些空白也会被应用样式,占据空间,所以会有间隔,把字符大小设为 0,就没有空格了 display:inline-block 什么时候会显示间隙?(携程) 相邻的 inline-block 元素之间有换行或空格分隔的情况下会产生间距 非 inline-block 水平元素设置为 inline-block 也会有水平间距 可以借助 vertical-align:top; 消除垂直间隙 可以在父级加 font-size:0; 在子元素里设置需要的字体大小,消除垂直间隙 把 li 标签写到同一行可以消除垂直间隙,但代码可读性差 用纯 CSS 创建一个三角形的原理是什么?把border的其他三条边设为透明 注意,这里要把 border-width 、border-style、 border-color 分开写。 .tri { width: 0px; height: 0; border-style: solid; border-width: 100px; border-color: transparent transparent red transparent; } 常用布局方式表格布局 <table> <tr> <td class="left">left</td> <td class="right">right</td> </tr> </table> float+margin <style> .container { width: 500px; height: 500px; } .left { width: 100px; height: 100%; float: left; background: green; } .middle { margin-left: 100px; /*空出和左边width一样*/ margin-right: 200px; /*空出和右边width一样*/ background: #000 } .right { height: 100%; width: 200px; float: right; background: yellow; } </style> <div class="container"> <div class="left">left</div> <div class="right">right</div> <!--先写right,right写在最后会因为float上靠--> <div class="middle">middle</div> </div> inline-block 像文本一样排block元素 问题:中间有间隙: 解决方法:把父元素字体大小设为0,并在子元素中设置字体大小 <style> .container { width: 500px; height: 500px; } .left { width: 100px; height: 100%; display: inline-block; background: green; } .right { height: 100%; width: 200px; display: inline-block; background: yellow; } </style> <div class="container"> <div class="left">left</div> <div class="right">right</div> </div> flexbox参考 容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。 项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。 弹性盒子的属性: flex-direction:属性决定主轴的方向(即项目的排列方向)。 row(默认值):主轴为水平方向,起点在左端。 row-reverse:主轴为水平方向,起点在右端。 column:主轴为垂直方向,起点在上沿。 column-reverse:主轴为垂直方向,起点在下沿。 flex-wrap: 定义,如果一条轴线排不下,如何换行。 nowrap(默认):不换行。 wrap:换行,第一行在上方。 wrap-reverse:换行,第一行在下方。 flex-flow: flex-direction属性和flex-wrap属性的简写形式 justify-content: 定义了项目在主轴上的对齐方式。 flex-start(默认值):左对齐 flex-end:右对齐 center: 居中 space-between:两端对齐,项目之间的间隔都相等。 space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。 align-items: 定义项目在交叉轴上如何对齐。 flex-start:交叉轴的起点对齐。 flex-end:交叉轴的终点对齐。 center:交叉轴的中点对齐。 baseline: 项目的第一行文字的基线对齐。 stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。 align-content: 定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。 flex-start:与交叉轴的起点对齐。 flex-end:与交叉轴的终点对齐。 center:与交叉轴的中点对齐。 space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。 space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。 stretch(默认值):轴线占满整个交叉轴。 项目的属性 order:定义项目的排列顺序。数值越小,排列越靠前,默认为0。 flex-grow:定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。 flex-shrink:定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。 flex-basis:定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。 flex:是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto align-self:允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch <style> .a1 { display: flex; height:100px; width: 500px; background: #000 } .a2 { flex: 1; background: red } </style> <div class="a1"> <div class="a2">123 </div> </div> 响应式设计和布局 响应式设计就是网站能够兼容多个不同大小的终端,而不是为每个终端做一个特定的版本 基本原理是利用 CSS3 媒体查询,为不同尺寸的设备适配不同样式 对于低版本的 IE,可采用 JS 获取屏幕宽度,然后通过监听window.onresize 方法来实现兼容 主要考虑屏幕大小 主要方法: 隐藏:隐藏导航栏等不重要的东西 折行:pc端一行显示多个的在移动端一行显示少一些 自适应空间:多留出自适应空间 方式: rem:通过html的字体大小确定元素大小 html默认的样式字体大小为16px,1rem=16px,不同屏幕在mediaquery中改html的字体大小即 viewport:在meta中手工确定屏幕大小content="width=320" 媒体查询:为不同屏幕写样式 @media (max-width: 640px) { .left{display: none} /*为移动端隐藏样式*/ } 请列举几种隐藏元素的方法 visibility: hidden; 这个属性只是简单的隐藏某个元素,但是元素占用的空间任然存在 opacity: 0; CSS3 属性,设置 0 可以使一个元素完全透明 position: absolute; 设置一个很大的 left 负值定位,使元素定位在可见区域之外 display: none; 元素会变得不可见,并且不会再占用文档的空间。 transform: scale(0); 将一个元素设置为缩放无限小,元素将不可见,元素原来所在的位置将被保留 HTML5 属性,效果和 display:none;相同,但这个属性用于记录一个元素的状态 height: 0; 将元素高度设为 0 ,并消除边框 filter: blur(0); CSS3 属性,将一个元素的模糊度设置为 0 css 属性 content 有什么作用?content 属性专门应用在 before/after 伪元素上,用于插入额外内容或样式 元素竖向的百分比设定是相对于容器的高度吗?元素竖向的百分比设定是相对于容器的宽度,而不是高度 a 标签上四个伪类的使用顺序是怎么样的?link > visited > hover > active 简称 lvha(love-ha) 伪类的特殊性(应用优先级)是同样的,所以后出现的伪类会覆盖先出现的伪类(同时激活) 在这里,比如把hover放在active后面,那么实际你在激活(active)链接的时候就触发了hover伪类,hover在后面覆盖了active的颜色,所以始终无法看到active的颜色 设置元素浮动后,该元素的 display 值会如何变化?设置元素浮动后,该元素的 display 值自动变成 block 请解释 CSS sprites,以及你要如何在页面或 CSS Sprites 其实就是把网页中一些背景图片整合到一张图片文件中,再利用 CSS 的“background-image”,“background- repeat”,“background-position”的组合进行背景定位,background-position 可以用数字能精确的定位出背景图片的位置。 CSS Sprites 为一些大型的网站节约了带宽,让提高了用户的加载速度和用户体验,不需要加载更多的图片。 margin叠加几种情况margin叠加的意思是:当两个或者更多的margin相遇时,它们将形成一个外边距,这个外边距的高度等于两个发生叠加的外边距中高度较大者。 当一个元素出现在另一个元素上面时,第一个元素的底边外边距与第二个元素的顶边外边距发生叠加。如图: 一个元素在另一个元素中时,它们的顶边距和低边距也会发生叠加 果一个元素是空元素(即一个元素没有内容,内边距和边框),这种情况外边距的顶边距和低边距碰在一起也会发生叠加 在上面那种空元素的情况,如果该空元素与另一个元素的外边距碰在一起,也会发生叠加。 以上4种外边距叠加情况只会发生在普通文档流的垂直方向。行内框、浮动框、绝对定位框之间的外边距不会发生叠加,同样水平方向也不会发生叠加。 水平居中和垂直居中css问题 css优先级 权重:id>class>tag !important: 最高 内联样式高 后写的优先级高 伪类和伪元素的区别 伪类表状态 hoover等 伪元素是真的元素 before after 在页面中会显示 前者单冒号 后者双冒号 实现两栏(三栏)布局的方法 表格布局 float+margin 清楚浮动 inline-block 处理间隙 flexbox 兼容性差 absolute和fix有什么区别 absolute相对于最近的absolute/relative来定位 fix相对于屏幕/viewport定位 inlineblock为什么有间隙 空白字符 解决:消灭字符;父元素字体设为0 清除浮动 为什么有浮动:浮动的元素不会占据父元素的布局空间,父元素不会管浮动元素,所以可能会高度塌陷 清除:给父元素加定高宽;父元素加overflowhidden;给父元素加:after{clearboth};最后加一行空行clearboth 如何适配移动端页面 viewport rem/viewport/media query 设计上:隐藏/折行/自适应visibility: hidden;display: block;font-size: 0;content: “ “;clear: both;height: 0;","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"css","slug":"前端/css","permalink":"http://yoursite.com/categories/前端/css/"}],"tags":[{"name":"css","slug":"css","permalink":"http://yoursite.com/tags/css/"}]},{"title":"Alexnet图像分类","slug":"Alexnet图像分类","date":"2019-05-22T13:12:11.000Z","updated":"2019-09-19T09:45:17.230Z","comments":true,"path":"2019/05/22/Alexnet图像分类/","link":"","permalink":"http://yoursite.com/2019/05/22/Alexnet图像分类/","excerpt":"","text":"github链接:https://github.com/tedqin/Alexnet_Imagenet 背景 概述 Alexnet是Hinton小组在ImageNet图像处理大赛ISVRC2012中使用的神经网络模型,并获得了第一名,测试错误率相比往年的第一名都有大幅度的提升,top5测试错误率是15.3%,第二名是26.2%。Alexnet有60M个参数,650,000个神经元,5个卷积层和3个全连接层(1000类的softmax分类器)。Alexnet模型由Alex Krizhevsky 等人在两个GTX 580 3GB GPU上训练5、6天左右得到。目前是深度学习图像处理领域当中最常用的模型之一。AlexNet相比于以前的一些网络模型来说,做出了很多创新,主要包括以下几点 框架 使用激活函数ReLu 多GPU并行训练 局部影响标准化 重叠池化 模型结构Alexnet有5个卷积层和3个全连接层,并且Alex发现移除任意一层都会降低最终的效果。网络结构如图 这个网络前面5层是卷积层,后面三层是全连接层,最终softmax输出是1000类。 第三卷积层用384个33256的卷积核,得到1313192*2的卷积层。 第四卷积层用384个33192的卷积核,得到1313192*2的卷积层。 第五卷积层用256个33192的卷积核,得到1313128*2的卷积层。每个全连接层有4096个神经元。 总体而言,Alexnet网络的结构如下: 数据集 测试caffe提供的预训练模型一共包括了1000类图像,涵盖了生物、天文、自然、科技等多个方面的相关图像,具体在caffe_classes.py下,由于文件本身较大就没放在github上,可以很容易在网上找到测试集包括1000张图像,共200类,标签存储在lable.txt当中。取测试图像概率最大类的下标作为测试的分类结果(即top-1测试),并且与label对比,最后计算得出整个测试集得precision在75%左右,算是比较好的结果。 总结AlexNet可以说是深度神经网络的鼻祖,相比于后来的VGG和googlenet而言,它的构造更加简单,而且结构也已经非常的成熟和稳固。作为学校的大创项目用alexnet有点蠢,但是时间紧迫,也分享下自己学习cnn的过程。","categories":[{"name":"machine learning","slug":"machine-learning","permalink":"http://yoursite.com/categories/machine-learning/"},{"name":"cnn","slug":"machine-learning/cnn","permalink":"http://yoursite.com/categories/machine-learning/cnn/"}],"tags":[{"name":"python","slug":"python","permalink":"http://yoursite.com/tags/python/"},{"name":"machine learning","slug":"machine-learning","permalink":"http://yoursite.com/tags/machine-learning/"}]},{"title":"learningJS","slug":"learningJS","date":"2018-12-13T09:02:36.000Z","updated":"2019-07-31T01:51:16.146Z","comments":true,"path":"2018/12/13/learningJS/","link":"","permalink":"http://yoursite.com/2018/12/13/learningJS/","excerpt":"","text":"output is the best input,以下每一项都可以单独写一篇文章javascript 原型、原型链 闭包 es6的新特性 作用域 全局和局部环境 var let const的区别 ajax xhr this 箭头函数 事件绑定、监听、委托、代理 继承 常用数组方法 defer和async 虚拟dom html html的语义标签 html5新特性 canvas css bootstrap dom 定位元素的几种方法 遍历 浏览器 渲染和绘制 兼容性 布局 模块化 webpack 性能优化","categories":[{"name":"前端","slug":"前端","permalink":"http://yoursite.com/categories/前端/"},{"name":"javascript","slug":"前端/javascript","permalink":"http://yoursite.com/categories/前端/javascript/"}],"tags":[{"name":"javascript","slug":"javascript","permalink":"http://yoursite.com/tags/javascript/"},{"name":"前端","slug":"前端","permalink":"http://yoursite.com/tags/前端/"}]},{"title":"c++tips笔记","slug":"cpp笔记","date":"2018-10-18T08:19:02.000Z","updated":"2019-07-28T17:52:43.745Z","comments":true,"path":"2018/10/18/cpp笔记/","link":"","permalink":"http://yoursite.com/2018/10/18/cpp笔记/","excerpt":"","text":"指针* 是取值运算符,对地址使用可以获得地址中储存的数值。对于指针a,*a表示取a中的值 在 定义 时, 是一个标识符,声明该变量是一个指针,比如说int p; 那p就是一个指向int型的指针 在 调用 时, p是指针p指向的那个变量,比如说之前有int a=5;int p=&a;那么p的值是a的地址,也就是指针p指向a, p则等于a的值,即p=5。 & &在 定义 时则是引用,比如说有定义int a=5;再定义int b=&a;那么这里的b则引用a的值,即b=5,而再给b赋值:b=10,a的值也会变为10。 &在 调用 是地址运算符,对变量使用可以获得该变量的地址, 对于变量b,&b表示取b的地址 example 先定义有int x = 0;int *p = &x; 若定义函数: void fun1(int a){ a=5;} ,则调用:fun1(x); 之后,x还等于0;因为fun1函数只改变了形参a的值,a只是fun1函数里的局部变量,调用fun1(x)相当于是“a=x;a=5;”,x没变; 若定义函数:void fun2(int &a){ a=5;} , 则调用:fun2(x); 之后,x等于5;因为这里的a引用了x的值; 若定义函数:void fun3(int a){ a=5;} , 则调用:fun3(p); 之后,x也等于5;因为fun3函数的参数a是一个指针,相当于a=p; a则与 p指向同一地址,改变 a即改变p即x return *this: strcpy和strncpy:strcpy(char *ch1, char *ch2): 直接将ch2指向的由”\\0”结束的字符串复制到ch1,ch1必须有足够的空间来存储ch2 若ch2长于ch1,还是会复制,但是ch1会溢出* strncpy(char *ch1, char *ch2, n): 将ch2中最多n个字符复制到ch1 如果n>ch1长度,ch1溢出 如果n<ch1长度,且如果 ch2长度<=ch1长度,则ch2前n个字符复制到ch1 ch2长度>ch1长度,出错 建议:将n设置为ch1长度","categories":[{"name":"cpp","slug":"cpp","permalink":"http://yoursite.com/categories/cpp/"}],"tags":[{"name":"cpp","slug":"cpp","permalink":"http://yoursite.com/tags/cpp/"}]},{"title":"mac常用指令","slug":"mac常用指令","date":"2018-10-09T18:55:04.000Z","updated":"2019-07-28T17:57:50.521Z","comments":true,"path":"2018/10/10/mac常用指令/","link":"","permalink":"http://yoursite.com/2018/10/10/mac常用指令/","excerpt":"","text":"ps: * 指令名称 指令 实例 参考:https://www.jianshu.com/p/8803bf591956 基本指令目录操作 创建目录 mkdir mkdir dirname 删除目录 rmdir rmdir dirname 移动或重命名一个目录 mvdir mvdir dir1 dir2 改变当前目录 rmdir rmdir dirname 显示当前目录的路径名 pwd pwd 显示当前目录的内容 ls ls -la 文件操作 显示文件内容或连接文件 cat cat filename 显示非文本文件的内容 od od -c filename 复制文件或目录 cp cp file1 file2 删除文件或目录 rm rm filename 改变文件名或所在目录 mv mv file1 file2 使用匹配表达式查找文件 find find . -name "*.c" -print 显示文件类型 file file filename 选择操作 显示文件的最初几行 head head -20 filename 显示文件的最后几行 tail tail -15 filename 显示文件每行中的某些域 cut cut -f1,7 -d: /etc/passwd 从标准输入中删除若干列 colrm colrm 8 20 file2 排序或归并文件 sort sort -d -f -u file1 去掉文件中的重复行 uniq uniq file1 file2 显示两有序文件的公共和非公共行 comm comm file1 file2 统计文件的字符数、词数和行数 wc wc filename 给文件加上行号 nl nl file1 >file2 进程操作 显示进程当前状态 ps ps u 终止进程 kill kill -9 30142 时间操作 显示系统的当前日期和时间 diff diff file1 file2 显示⽇日历 cal cal 8 1996 统计程序的执⾏行行时间 time time a.out 网络与通信操作 远程登录 telnet telnet hpc.sp.net.edu.cn 远程登录 rlogin rlogin hostname -l username 在远程主机执⾏行行指定命令 rsh rsh f01n03 date 在本地主机与远程主机之间传输⽂文件 ftp ftp[ftp.sp.net.edu.cn] 在本地主机与远程主机之间复制⽂文件 rcp rcp[ftp.sp.net.edu.cn] 给⼀一个⽹网络主机发送 回应请求 ping ping hpc.sp.net.edu.cn 阅读和发送电⼦子邮件 mail mail 允许或拒绝接收报⽂文 mesg mesg n core shell 指令 列列出最近执⾏行行过的⼏条命令及编号 history history 重复执⾏行行最近执⾏过的某条命令 r r-2 给某个命令定义别名 alias alias del=rm -i 取消对某个别名的定义 diff diff file1 file2 比较并显示两个文件的差异 unalias unalias del 其它命令 显示操作系统的有关信息 uname uname -a 清除屏幕或窗⼝口内容 clear clear 显示当前所有设置过的环境变量量 env env 列列出当前登录的所有⽤用户 who who 显示当前正进⾏行行操作的⽤用户名 whoami whoami 显示终端或伪终端的名称 tty tty 显示或重置控制键定义 stty stty -a 查询磁盘使⽤用情况 du du -k subdirdf 显示⽂文件系统的总空间和可⽤用空间 /tmp 显示当前系统活动的总信息 w 在本地主机与远程主机之间复制⽂文件 rcp rcp[ftp.sp.net.edu.cn] 给⼀一个⽹网络主机发送 回应请求 ping sudo命令 临时使⽤用root权限来编辑/etc/shadow密码⽂文件 sudo gedit /etc/shadow 注意$和#的变化,#表示你在最⾼高权限root⾥里里⾯面","categories":[{"name":"基础知识","slug":"基础知识","permalink":"http://yoursite.com/categories/基础知识/"}],"tags":[{"name":"基础","slug":"基础","permalink":"http://yoursite.com/tags/基础/"}]},{"title":"hexo搭建blog常用命令","slug":"hexo搭建blog常用命令","date":"2018-10-09T18:29:32.000Z","updated":"2019-07-28T17:55:28.956Z","comments":true,"path":"2018/10/10/hexo搭建blog常用命令/","link":"","permalink":"http://yoursite.com/2018/10/10/hexo搭建blog常用命令/","excerpt":"","text":"常规搭建常规指令hexo new "blogname" #新建博客 hexo g #生成 hexo s #启动服务器预览 hexo d #部署 hexo clean #清除缓存 更换设备搭建参考:https://www.zhihu.com/question/21193762/answer/103097754 打开git bash,在用户主目录下运行: ssh-keygen -t rsa -C "[email protected]" 把其中的邮件地址换成自己的邮件地址,然后一路回车 最后完成后,会在用户主目录下生成.ssh目录,里面有id_rsa和id_rsa.pub两个文件,这两个就是SSH key密钥对,id_rsa是私钥,千万不能泄露出去,id_rsa.pub是公钥,可以放心地告诉任何人。 登陆GitHub,打开「Settings」->「SSH and GPG keys」,然后点击「new SSH key」,填上任意Title,在Key文本框里粘贴公钥id_rsa.pub文件的内容(千万不要粘贴成私钥了!),最后点击「Add SSH Key」,你就应该看到已经添加的Key。注意:不要在git版本库中运行ssh,然后又将它提交,这样就把密码泄露出去了。 下载Node.js,并安装. 打开git bash客户端,输入 npm install hexo-cli -g,开始安装hexo 下面就将原来的文件拷贝到新电脑中,但是要注意哪些文件是必须的,哪些文件是可以删除的。 1)讨论下哪些文件是必须拷贝的:首先是之前自己修改的文 件,像站点配置_config.yml,theme文件夹里面的主题, 以及source里面自己写的博客文件,这些肯定要拷贝的。除 此之外,还有 三个文件需要有,就是scaffolds文件夹(文章的模板)、 package.json(说明使用哪些包)和.gitignore(限定在 提交的时候哪些文件可以忽略)。其实,这三个文件不是我们 修改的,所以即使丢失了,也没有关系,我们可以建立一个新 的文件夹,然后在里面执行hexo init,就会生成这三个文 件,我们只需要将它们拷贝过来使用即可。总结: _config.yml,theme/,source/,scaffolds/, package.json,.gitignore,是需要拷贝的。 (2)再讨论下哪些文件是不必拷贝的,或者说可以删除的: 首先是.git文件,无论是在站点根目录下,还是主题目录下 的.git文件,都可以删掉。然后是文件夹 node_modules(在用npm install会重新生成), public(这个在用hexo g时会重新生成),.deploy_git 文件夹(在使用hexo d时也会重新生成),db.json文件。 其实上面这些文件也就是.gitignore文件里面记载的可以忽 略的内容。总结:.git/,node_modules/, public/,.deploy_git/,db.json文件需要删除。 在git bash中切换目录到新拷贝的文件夹里,使用 npm install 命令,进行模块安装。很明显我们这里没用hexo init初始化,因为有的文件我们已经拷贝生成过来了,所以不必用hexo init去整体初始化,如果不慎在此时用了hexo init,则站点的配置文件_config.yml里面内容会被清空使用默认值,所以这一步一定要慎重,不要用hexo init。 安装其他的一些必要组件,如果在node_modules里面有的,就不要重复安装了: (1)为了使用hexo d来部署到git上,需要安装 npm install hexo-deployer-git --save (2)为了建立RSS订阅,需要安装 npm install hexo-generator-feed --save (3)为了建立站点地图,需要安装 npm install hexo-generator-sitemap --save 插件安装后,有的需要对配置文件_config.yml进行配置,具体怎么配置,可以参考上面插件在github主页上的具体说明 使用hexo g,然后使用hexo d进行部署,如果都没有出错,就转移成功了!","categories":[{"name":"blog","slug":"blog","permalink":"http://yoursite.com/categories/blog/"},{"name":"hexo","slug":"blog/hexo","permalink":"http://yoursite.com/categories/blog/hexo/"}],"tags":[{"name":"hexo","slug":"hexo","permalink":"http://yoursite.com/tags/hexo/"}]},{"title":"用CNN实现深度生成对抗网络GAN","slug":"用CNN实现深度生成对抗网络GAN","date":"2018-09-10T14:32:01.000Z","updated":"2019-09-19T09:01:00.912Z","comments":true,"path":"2018/09/10/用CNN实现深度生成对抗网络GAN/","link":"","permalink":"http://yoursite.com/2018/09/10/用CNN实现深度生成对抗网络GAN/","excerpt":"","text":"GAN生成对抗网络(Generative Adversarial Network,GAN)是近几年很热门的一种深度学习神经网络模型,是目前在复杂分布上进行无监督学习最前沿的模型之一,这个概念由Ian Goodfellow和Yoshua Bengio等人在2014年提出,GAN的核心思想源自博弈论,它通过构造生成器(Generator)和判别器(Discriminator)在训练过程中互相博弈学习,最终得到理想的结果。其中生成器的目的在于生成虚假的样本分布,判别器的目的在于判别出输入的样本是否真实。由于GAN模型“博弈”的这一特点,它已经开始被应用到语音和语言处理、电脑病毒监测、棋类比赛程序等问题的研究当中。另外,GAN最常用的领域还是图像处理和计算机视觉,进行图像生成,构成各种逼真的室内外场景。 GAN的基本模型 CNN实现GANGAN提出的是一种对抗模型的思想,而要实现它,目前流行的是使用感知器或者多层神经网络。而用CNN来实现,可以大大解决GAN难以训练和不够稳定的问题,并且可以提高生成样本的质量、收敛速度,以及拓展维度。CNN实现的改进: 去掉了G和D中的池化层(pooling layer),并用微步幅卷积替代,能够分别使得G和D的下采样和上采样效率更高。 在G和D中使用批量规范化(Batch Normalization),通过将输入的每个样本单元标准化为0均值和单位方差来稳定学习,这有助于处理初始化不良导致的训练问题,也有助于梯度流向更深的网络层。 去掉最后一层卷积层后面的全连接层(fully layer),将生成器和判别器直接相连,能够有效提高模型收敛速率。 生成器中除了输出层采用Tanh激活函数,其余所有层都采用ReLU激活函数。 判别器中所有层都采用Leaky ReLU激活函数。 模型设计生成器模型生成器的网络由4层卷积层构成 第1层:卷积核大小为5”×” 5,步长2,“same”填充,深度512,输出样本尺寸8”×” 8,生成函数ReLU 第2层:卷积核大小为5”×” 5,步长2,“same”填充,深度256,输出样本尺寸16”×” 16,生成函数ReLU 第3层:卷积核大小为5”×” 5,步长2,“same”填充,深度128,输出样本尺寸32”×” 32,生成函数ReLU 第4层:卷积核大小为5”×” 5,步长2,“same”填充,深度3,输出样本尺寸64”×” 64,生成函数Tanh 判别器模型判别器的4层卷积层具体如下: 第1层:卷积核大小为5”×” 5,步长2,“same”填充,深度64,输出样本尺寸32”×” 32,生成函数Leaky ReLU。 第2层:卷积核大小为5”×” 5,步长2,“same”填充,深度128,输出样本尺寸16”×” 16,生成函数Leaky ReLU。 第3层:卷积核大小为5”×” 5,步长2,“same”填充,深度256,输出样本尺寸8”×” 8,生成函数Leaky ReLU。 第4层:卷积核大小为5”×” 5,步长2,“same”填充,深度512,输出样本尺寸4”×” 4,生成函数Sigmoid。 构建模型 构建生成器模型def generator(self, z): self.z_, self.h0_w, self.h0_b = linear(z, self.gf_dim84*4, 'g_h0_lin', with_w=True) self.h0 = tf.reshape(self.z_, [-1, 4, 4, self.gf_dim * 8])h0 = tf.nn.relu(self.g_bn0(self.h0)) //第1层微步幅卷积层 self.h1, self.h1_w, self.h1_b = conv2d_transpose(h0,[self.batch_size, 8, 8, self.gf_dim*4], name=’g_h1’, with_w=True)h1 = tf.nn.relu(self.g_bn1(self.h1)) //第2层微步幅卷积层 h2, self.h2_w, self.h2_b = conv2d_transpose(h1, [self.batch_size, 16, 16, self.gf_dim*2], name=’g_h2’, with_w=True)h2 = tf.nn.relu(self.g_bn2(h2)) //第3层微步幅卷积层 h3, self.h3_w, self.h3_b = conv2d_transpose(h2, [self.batch_size, 32, 32, self.gf_dim*1], name=’g_h3’, with_w=True) h3 = tf.nn.relu(self.g_bn3(h3)) //第4层微步幅卷积层,4层微步幅卷积后,矩阵维度变为(64, 64, 3) h4, self.h4_w, self.h4_b = conv2d_transpose(h3, [self.batch_size, 64, 64, 3], name=’g_h4’, with_w=True) return tf.nn.tanh(h4) 构建判别器模型def discriminator(self, image, reuse=False)://第1层卷积h0 = lrelu(conv2d(image, self.df_dim, name=’d_h0_conv’)) //第2层卷积h1 = lrelu(self.d_bn1(conv2d(h0, self.df_dim*2, name=’d_h1_conv’))) //第3层卷积h2 = lrelu(self.d_bn2(conv2d(h1, self.df_dim*4, name=’d_h2_conv’))) //第4层卷积 h3 = lrelu(self.d_bn3(conv2d(h2, self.df_dim*8, name=’d_h3_conv’))) h4 = linear(tf.reshape(h3, [-1, 8192]), 1, ‘d_h3_lin’) return tf.nn.sigmoid(h4), h4 构建优化器//判别器优化器,最小化损失函数d_optim = tf.train.AdamOptimizer(config.learning_rate, beta1=config.beta1) \\ .minimize(self.d_loss, var_list=self.d_vars) //判别器优化器,最小化损失函数g_optim = tf.train.AdamOptimizer(config.learning_rate, beta1=config.beta1) \\ .minimize(self.g_loss, var_list=self.g_vars)","categories":[{"name":"machine learning","slug":"machine-learning","permalink":"http://yoursite.com/categories/machine-learning/"},{"name":"gan","slug":"machine-learning/gan","permalink":"http://yoursite.com/categories/machine-learning/gan/"}],"tags":[{"name":"python","slug":"python","permalink":"http://yoursite.com/tags/python/"},{"name":"machine learning","slug":"machine-learning","permalink":"http://yoursite.com/tags/machine-learning/"}]},{"title":"目前的learning plan","slug":"基础知识","date":"2018-07-15T13:23:22.000Z","updated":"2019-07-29T05:03:56.987Z","comments":true,"path":"2018/07/15/基础知识/","link":"","permalink":"http://yoursite.com/2018/07/15/基础知识/","excerpt":"","text":"必须掌握的基础知识,主要分为数据结构、算法、操作系统、数据库、前端等。不定期更新数据结构 表 堆栈 队列 数组 树 完全二叉树:除了最后一层以外,其余层必满;最后一层可以是满,如果不满,则节点必须集中在左边 最大堆:1.必须是完全二叉树 2.节点的值必须大于左右子树的值 二叉搜索树:左孩子比父母小,右孩子比父母大。 avl树:一种平衡二叉搜索树,并且任意节点的孩子节点高度差最大为1. 平衡因子:某节点的平衡因子是该节点左子树的高度减右子树的高度(avl只能是0,1,-1 红黑树: 节点是红色或黑色。 根是黑色。 每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。) 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。 图 算法 排序 查找 hash 算法思想-递归 算法思想-贪心 算法思想-回溯 算法思想-分支 算法思想-动态规划 数据库 索引 视图 触发器 范式 锁 存储过程 事物 B+树 E-R图 3.10补充-mysql、mongodb 操作系统 并发性(concurrence) 在一个系统(或者一段时间)中,有多个同时执行的程序进行计算,并且它们之间存在潜在的交互。优点:资源利用率高、程序设计更简化、程序响应更快、系统性能更高;缺点:存在并发性的系统会有不同的程序运行路径,所以系统的处理结果会有不确定性。 进程(process)、线程(thread) 一个应用程序包含一个或多个相互协作的进程。 进程:一块包含一些资源的内存区域,组成为一段一定大小(4GB)的线性内存空间。 线程:进程中包含的一个或多个执行单元,无内存空间,只有指针、栈、寄存器、数据区。 一个程序至少有一个进程,一个进程至少有一个线程。进程和线程都是系统(程序)的执行单元。 差别:进程具有独立的地址空间(供它包含的线程访问),线程没有,所以如果一个进程崩溃,在保护模式下不会对其他进程产生影响;而一个线程死掉就等于整个进程死掉(多进程程序比多线程程序健壮),但是进程切换时耗费的资源多,效率差。 异步、同步处理、阻塞和非阻塞 同步调用:调用之后就能得到结果 异步调用:调用之后需要其他方法(状态、通知、回调函数)来得到结果。 同步线程:两个线程的步调要一致,如果二者运行速度不一样,则快的等慢的(快的阻塞一下等慢的)。 异步线程:两个线程的步调不一致,各自独立运行。 同步I/O:不发送成功或失败状态,一直等待。 异步I/O:输入/输出时立即返回成功或失败的状态。 阻塞:进程或线程停止。 阻塞I/O:资源不可用时(输入/输出未完成,I/O一直阻塞,直到完成。 非阻塞I/O:资源不可用超过一定时间后,直接结束本次I/O。 调度、死锁 死锁:两个或多个执行单元之间相互等待对方结束而引起阻塞的情况。 例:T1有R1的访问权、T2有R2的访问权。 T1想访问R2,同时T2想访问R1,此时T1和T2都要等待对方给出权限,形成死锁。 存储器管理 文件管理 IO阻塞 用户态、核心态 nodejs express框架、es6、es7 前端框架 react、vuejs、angularjs IOS开发","categories":[{"name":"基础知识","slug":"基础知识","permalink":"http://yoursite.com/categories/基础知识/"}],"tags":[{"name":"plan","slug":"plan","permalink":"http://yoursite.com/tags/plan/"}]},{"title":"《深入浅出NodeJS》读书笔记","slug":"《深入浅出NodeJS》读书笔记","date":"2018-07-15T12:20:07.000Z","updated":"2019-08-19T03:00:29.188Z","comments":true,"path":"2018/07/15/《深入浅出NodeJS》读书笔记/","link":"","permalink":"http://yoursite.com/2018/07/15/《深入浅出NodeJS》读书笔记/","excerpt":"","text":"第一章 Node Node:“一个强制不共享任何资源的单线程、单进程系统,通过协议构建不同的node来形成一个大型的网路应用,每一个node为一个节点”,这是书中给的解释原文 非阻塞I/O 书中多次提到的概念,我理解的非阻塞就是线程或进程的停止, 特点 1.异步 2.事件(随意绑定事件),时间绑定轻量级、松耦合 3.回调函数 Ajax请求:快速动态刷新网页,不刷新,直接更新参数 读完第一章以后,觉得云里雾里,这本书对于没有JS基础的人来说有点头疼。不过能肯定的是nodejs是一门异步I/O的语言,和python等编程习惯不一样,需要适应。 至此,我决定先啃《js高级程序设计第三版》这本书,对js有一定的了解以后再来学习nodejs。 第二章C/S模式:客户/服务器模式,例如微信等B/S模式:浏览器/服务器模式,例如各种web应用 CommonJS规范: 相比于python的import,JAVA的类文件等,js是没有模块引入机制的,只能通过<script>标签这种杂乱的方式引入代码。在nodejs未出现之前,js只能用于前端,只有Rhino等后端javascript运行环境来作为小工具。node这么多年发展以来,已经形成了一套响应的规范,也就是CommonJS规范。 1.模块引用:var math = require('math'); 2.模块定义:export.add = function(){...;return sum}; export.increment = function(val){}; 3.模块标识: node模块实现: node引入模块需要3个步骤:路径分析、文件定位、编译执行,其中系统自带的模块为核心模块,直接随node启动时加载进内存,加载速度快;用户自定义的模块称为文件模块,在运行时动态加载,慢。 1.路径分析:require('标识符');//分析标识符,标识符主要分为: *核心模块,如http、fs、path等。 *.或..等相对路径文件模块 *以/开始的绝对路径文件模块 *非路径形式的文件模块,如自定义的connect模块 (自定义模块非核心模块和路径形式的模块,分析速度最慢) 2.文件定位: *扩展名分析:模块文件可以不带扩展名,自动按.js、.json、.node顺序补全。 *目标分析和包: 3.模块编译 *核心模块一般为C/C++或javascript编译,所有的都转换为C/C++然后编译 4.内建模块:全由C/C++编译的模块,使用: process.binding('标识符') 来进行导出 包与NPM: "package.json":包含包的所有信息(版本、名称、作者等) NPM已经是一个包共享平台,实现第三方模块的发布、安装和依赖。 前后端共用模块: 前端规范:AMD规范、CMD规范 1.AMD规范定义的模块需要用define: define(function(){...}) 2.CMD规范申明时要指定所有的依赖 第三章tips:js异步回调函数复习Promise() resolve(): pending->fulfilled pending->rejected reject()","categories":[{"name":"node.js","slug":"node-js","permalink":"http://yoursite.com/categories/node-js/"}],"tags":[{"name":"read","slug":"read","permalink":"http://yoursite.com/tags/read/"}]}]}