首页
统计
墙纸
留言
Search
1
PVE8优化
19 阅读
2
mysql创建数据库
12 阅读
3
jenkins根据分支、文件夹打包
12 阅读
4
vue-cli注册全局方法
7 阅读
5
开心的加班
7 阅读
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
登录
/
注册
Search
标签搜索
vue+elementui
Cicaba
累计撰写
146
篇文章
累计收到
13
条评论
首页
栏目
web前端
Vue
CSS
javascript
React
那些年爬过过的坑
ES6
TypeScrippt
ES7
javascript图灵 - 总结
Node
面试总结
React-Native
Web优化
基础
AngularJS
拍摄
Flutter
Dart
Docker
Linux
mysql
PVE
页面
统计
墙纸
留言
搜索到
137
篇与
的结果
2017-10-21
闭包
闭包是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现。概念要理解闭包,首先必须理解Javascript特殊的变量作用域。 变量的作用域无非就是两种:全局变量和局部变量。 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量。 另一方面,在函数外部自然无法读取函数内的局部变量。但是通过闭包,可以在函数外面访问到内部的变量!比如: function foo(){ var b; //在foo函数不能访问bau函数的变量. function bau(){ var a = 1; b = a; //但是在bau函数可以访问foo函数的变量. } //但是我不变量a赋给了变量b bau(); console.log(b); } foo();函数bau就被包括在函数foo内部,这时foo内部的所有局部变量,对bau都是可见的。但是反过来就不行,bau内部的局部变量,对foo就是不可见的。 这就是Javascript语言特有的"链式作用域"结构(chain scope),子对象会一级一级地向上寻找所有父对象的变量。 所以,父对象的所有变量,对子对象都是可见的。 所以,我们说的闭包,就是能够在外部访问函数内部的函数。本质上,闭包就是将函数内部和函数外部连接起来的一座桥。这里有一个地方需要注意,函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量! 闭包的作用闭包的主要作用就是,减少全局污染,把变量和方法私有化. 比如: 方法的私有化 function foo(){ var a = 9; f1 = function(){ a+=1; } function bau(){ console.log(a); } return bau; } var fn = foo(); fn(); //9 f1(); fn(); //10这段代码中值得注意的地方,就是"f1=function(){a+=1}"这一行,首先在f1前面没有使用var关键字,因此f1是一个全局变量,而不是局部变量。 其次,f1的值是一个匿名函数,而这个匿名函数本身也是一个闭包,f1可以在函数外部对函数内部的局部变量进行操作。在这段代码中,结果实际上就是闭包bau函数。它一共运行了两次,第一次的值是9,第二次的值是10。这证明了,函数foo中的局部变量a一直保存在内存中,并没有在foo调用后被自动清除。原因就在于foo是f1的父函数,而f1被赋给了一个全局变量,这导致f1始终在内存中,而f1的存在依赖于foo,因此foo也始终在内存中,不会在调用结束后,被垃圾回收机制回收。 闭包注意点闭包会产生一个特定的作用域, 如果使用不当会得到一个错误的结果. 在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。 总结:1.闭包的体现函数嵌套函数.2.闭包是一种作用域链特殊情况的体现.3.闭包主要用来属性和方法的私有化封装.4.延迟资源回收.
2017年10月21日
3 阅读
0 评论
0 点赞
2017-10-18
理解执行环境与作用域链
函数调用都有与之相关的作用域和上下文。从根本上说,范围是基于函数(function-based)而上下文是基于对象(object-based)。换句话说,作用域是和每次函数调用时变量的访问有关,并且每次调用都是独立的。上下文总是关键字 this 的值,是调用当前可执行代码的对象的引用。执行上下文栈(Execution Context Stack)在ECMASscript中的代码有三种类型:global, function和eval。每一种代码的执行都需要依赖自身的上下文。当然global的上下文可能涵盖了很多的function和eval的实例。函数的每一次调用,都会进入函数执行中的上下文,并且来计算函数中变量等的值。eval函数的每一次执行,也会进入eval执行中的上下文,判断应该从何处获取变量的值。注意,一个function可能产生无限的上下文环境,因为一个函数的调用(甚至递归)都产生了一个新的上下文环境。一系列活动的执行上下文从逻辑上形成一个栈。栈底总是全局上下文,栈顶是当前(活动的)执行上下文。当在不同的执行上下文间切换(退出的而进入新的执行上下文)的时候,栈会被修改(通过压栈或者退栈的形式)。当javascript代码文件被浏览器载入后,默认最先进入的是一个全局的执行上下文。当在全局上下文中调用执行一个函数时,程序流就进入该被调用函数内,此时引擎就会为该函数创建一个新的执行上下文,并且将其压入到执行上下文堆栈的顶部。浏览器总是执行当前在堆栈顶部的上下文,一旦执行完毕,该上下文就会从堆栈顶部被弹出,然后,进入其下的上下文执行代码。这样,堆栈中的上下文就会被依次执行并且弹出堆栈,直到回到全局的上下文。执行上下文(Execution Context)也称为执行环节,一个执行的上下文可以抽象的理解为object。每一个执行的上下文都有一系列的属性(我们称为上下文状态),他们用来追踪关联代码的执行进度。主要有三个属性:变量对象(variable object),this指针(this value),作用域链(scope chain)。变量对象(Variable Object)变量对象(variable object) 是与执行上下文相关的 数据作用域(scope of data) 。 它是与上下文关联的特殊对象,用于存储被定义在上下文中的 变量(variables) 和 函数声明(function declarations) 。 它是一个抽象的概念,不同的上下文中,它表示使用不同的object。例如,在global全局上下文中,变量对象也是全局对象自身[global object]。(这就是我们可以通过全局对象的属性来指向全局变量)。进入执行上下文时,VO的初始化过程具体如下:函数的形参(当进入函数执行上下文时) 变量对象的一个属性,其属性名就是形参的名字,其值就是实参的值;对于没有传递的参数,其值为undefined函数声明(FunctionDeclaration, FD) 变量对象的一个属性,其属性名和值都是函数对象创建出来的;如果变量对象已经包含了相同名字的属性,则替换它的值变量声明(var,VariableDeclaration) 变量对象的一个属性,其属性名即为变量名,其值为undefined;如果变量名和已经声明的函数名或者函数的参数名相同,则不会影响已经存在的属性。执行代码的时候,VO的一些Undefined值会被确定。活动对象(activation object)当函数被调用者激活,这个特殊的活动对象(activation object) 就被创建了。它包含普通参数(formal parameters) 与特殊参数(arguments)对象(具有索引属性的参数映射表)。活动对象在函数上下文中作为变量对象使用。即:函数的变量对象保持不变,但除去存储变量与函数声明之外,还包含以及特殊对象arguments 。AO是在进入函数的执行上下文时创建的,并为该对象初始化一个arguments属性,该属性的值为Arguments对象。作用域链(scope chain)作用域链的原理和原型链很类似,如果这个变量在自己的作用域中没有,那么它会寻找父级的,直到最顶层。JS的语法风格和C/C++类似, 但作用域的实现却和C/C++不同,并非用“堆栈”方式,而是使用列表,具体过程如下(ECMA262中所述):任何执行上下文时刻的作用域, 都是由作用域链(scope chain, 后面介绍)来实现.在一个函数被定义的时候, 会将它定义时刻的scope chain链接到这个函数对象的[[scope]]属性.在一个函数对象被调用的时候,会创建一个活动对象(也就是一个对象), 然后对于每一个函数的形参,都命名为该活动对象的命名属性, 然后将这个活动对象做为此时的作用域链(scope chain)最前端, 并将这个函数对象的[[scope]]加入到scope chain中.在一般情况下,一个作用域链包括父级变量对象(variable object)(作用域链的顶部)、函数自身变量VO和活动对象(activation object)。不过,有些情况下也会包含其它的对象,例如在执行期间,动态加入作用域链中的—例如with或者catch语句。[译注:with-objects指的是with语句,产生的临时作用域对象;catch-clauses指的是catch从句,如catch(e),这会产生异常对象,导致作用域变更]。当查找标识符的时候,会从作用域链的活动对象部分开始查找,然后(如果标识符没有在活动对象中找到)查找作用域链的顶部,循环往复,就像作用域链那样。
2017年10月18日
2 阅读
0 评论
0 点赞
2017-10-17
React受控与非受控组件
React内部分别使用了props, state来区分组件的属性和状态。props用来定义组件外部传进来的属性, 属于那种经过外部定义之后, 组件内部就无法改变。而state维持组件内部的状态更新和变化, 组件渲染出来后响应用户的一些操作,更新组件的一些状态。如果组件内部状态不需要更新,即没有调用过this.setState, 全部通过props来渲染也是没问题的, 不过这种情况不常见。本文所介绍的内容就是通过props和state的定义来谈谈React的受控组件和非受控组件。非受控组件顾名思义, 非受控组件即组件的状态改变不受控制.接来下我们以一个简单input组件代码来描述。import React, { Component } from 'react'; import ReactDOM from 'react-dom'; class Demo1 extends Component { render() { return ( <input type="text"/> ) } } ReactDOM.render(<Demo1/>, document.getElementById('content'))在这个最简单的输入框组件里,我们并没有干涉input中的value展示,即用户输入的内容都会展示在上面。如果我们通过props给组件设置一个初始默认值,<input defaultValue={this.props.value}/>defaultValue属性是React内部实现的一个属性,目的类似于input的placeholder属性。ps: 此处如果使用value代替defaultValue,会发现输入框的值无法改变。受控组件上面提到过,既然通过设置input的value属性, 无法改变输入框值,那么我们把它和state结合在一起,再绑定onChange事件,实时更新value值就行了。class Demo1 extends Component { constructor(props) { super(props); this.state = { value: props.value } } handleChange(e) { this.setState({ value: e.target.value }) } render() { return ( <input value={this.state.value} onChange={e => this.handleChange(e)}/> ) } }这就是最简单的受控组件模型, 我们可以通过在onChange的回调里控制input要显示的值,例如我们设置input框只能输入数字this.setState({value: e.target.value.replace(/\D/g, '')})现在我们应该完全明白form表单中受控组件和非受控组件的关系。受控组件采取的理念类似于redux的单项数据流理念,即value值是在调用者上更新的。那么问题来了。。。最后的思考现在我们要实现一个简单的input的number类型组件,后面紧跟一个+的button按钮,将输入框内的数字每次加一。所以此处只能按照受控组件的理念来写import React, { Component } from 'react'; export default class extends Component { constructor(props) { super(props); this.state = { value: props.value } } handleChange(e) { this.setState({ value: e.target.value.replace(/\D/g, '') }) } plus() { const value = ++this.input.value this.setState({ value, }) } render() { return ( <div> <input value={this.state.value} onChange={e => this.handleChange(e)} ref={ref => this.input = ref} /> <button onClick={() => this.plus()}>+</button> </div> ) } }此处功能基本实现完全,但是发现使用此组件之后,面临了另一个问题,我们如何在外部获取到这个输入框的值。一种方法是给组件增加个getValue回调的props,每次value值变化都调用一次getValue,即在handleChange和plus函数里调用,但是存在一个问题是,调用者只能通过getValue被动获取值,而且value值得改变此时还是在组件内部自行变化,不符合受控组件原理,也不满足React单向数据流概念。另一种方法就是将input组件的将要改变的值传到调用者里面,由调用者来决定更不更新组件的值,即此时数据由被调用者input组件生成,传至调用者,调用者判断满足条件后决定更新,再将数据重新传入到被调用者里。而调用者与被调用者彼此之间建立的联系方式通过input组件的props和调用者的state。此时input组件的代码如下export default class extends Component { constructor(props) { super(props); this.state = { value: props.value } } componentWillReceiveProps(nextProps) { this.setState({ value: nextProps.value }) } handleChange(e) { this.props.onChange(e.target.value) } plus() { const value = ++this.input.value this.props.onChange(value) } render() { return ( <div> <input value={this.state.value} onChange={e => this.handleChange(e)} ref={ref => this.input = ref} /> <button onClick={() => this.plus()}>+</button> </div> ) } }代码中的this.props.onChange就是调用者内部的函数,通过setState来更新input组件的value值。
2017年10月17日
1 阅读
0 评论
0 点赞
2017-10-16
jQuery事件注册和取消
事件注册bind这是1.x早起版本的一种绑定方式,你看名称就比较直接。主要适用于直接绑定到已经存在的对象上,但是在1.7版本之后,推荐使用的绑定方式是on方法,原因很简单,支持事件委托嘛(I guess)! 并且jQuery自身代码中,所有与事件注册相关的操作使用的都是on方法。还有一点需要提到的,就是通过bind绑定的事件,可以通过unbind取消。delegate用作事件代理代理。live也是用作事件代理,区别就是绑定的选择器每次都会更新。已经弃用了!on上面的三个方法: bind, delegate, live就是早期jQuery事件处理的主要方法,但是on出现之后,都被替换掉了。也就是说,凡事和事件打交道的时候,都要使用on,这才是老大!one用法和on类似,触发一次后自动取消。off取消事件绑定。trigger手动触发事件。命名空间使用了很久jQuery的事件绑定,才在同事那里学到可以添加命名空间这个概念。充分表明了文档的重要性,因为这个是文档里提及到的,并且就在前几段!!!首先jQuery绑定的事件名称可以是任意String,因为可以通过trigger触发,对于不同的事件名称,可以通过添加命名空间的形式进行区分,比如click事件,我们可以添加click.namespace,也可以是click.name.space,多个命名空间并行。其实主要原因就是jQuery将每一个绑定事件对应的处理函数都存储起来了,添加命名空间,也就是对相同事件上的不同或多处事件处理函数进行区分。这样在trigger的时候,就可以进行区分了,从而不触发其他绑定的处理函数。事件代理jQuery中事件流是冒泡的,也就是从触发的那个元素(event.target)开始,向document冒泡。我们可以通过event.stopPorpagation()停止冒泡。事件代理的一大好处就是可以绑定一个元素上,检测子元素触发,而不需要绑定在N多个相同的子元素上,这样效率上会好很多。事件对象Event Object,jQuery的事件对象是遵守W3C标准的。关于事件对象的详细内容,参见: Event Object。
2017年10月16日
3 阅读
0 评论
0 点赞
2017-10-15
CSS定位方式
display属性每一个元素都有默认的display属性,使用最多的是block, inline和inline-block,不常用的是table-cell。根据display属性,我们可以将元素分为块级元素(block)和内联级元素(inline)。它们最大区别是:block元素可以设置宽度,独占一行。inline元素宽度由内容决定,与其他元素并列在一行。常见的block属性元素有:div, h1-h6, ul, li, ol, dl, dd, dt。常见的inline属性元素有: span, a, em。block宽高可以自行设置,默认宽度由父容器决定,默认高度有内容决定。自己独占一行。inline宽度和高度都有内容决定,与其他元素共占一行。inline-block宽度可以自行设置,类似block,但是与其他元素共占一行,类似inline。长用于设置垂直居中。table-cell此属性指让标签元素以表格单元格的形式呈现,单元格有一些比较特殊的属性,可以设置元素的垂直居中等。position属性元素在页面中的布局遵守一套文档流的方式,默认的定位属性值为static。它其实是未被设置定位的。元素如果被定位了,那么它的top,left,bottom,right值就会生效,能设置定位的属性是relative,absolute和fixed。需要注意的另一点是被定位的元素层次(z-index)会得到提高。relative(相对定位)设置了相对定位之后,通过修改top,left,bottom,right值,元素会在自身文档流所在位置上被移动,其他的元素则不会调整位置来弥补它偏离后剩下的空隙。absolute(绝对定位)设置了绝对定位之后,元素脱离文档流,其他的元素会调整位置来弥补它偏离后剩下的空隙。元素偏移是相对于是它最近的设置了定位属性(position值不为static)的元素。且如果元素为块级元素(display属性值为block),那么它的宽度也会由内容撑开。因为:默认文档流中块级元素如果没有设置宽度属性,会自动填满整行。fixed(固定定位)设置了固定定位之后,元素相对的偏移的参考是可视窗口,即使页面滚动,元素仍然会在固定位置。
2017年10月15日
2 阅读
0 评论
0 点赞
2017-10-15
JS继承特性
了解JS继承特性我们必须了解原型链:JavaScript 对象有一个指向一个原型对象的链。 当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型, 以及该对象的原型的原型,依此层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾, 这就是原型链.概念JavaScript的所有对象,都有自己的继承链。也就是说,每个对象都继承另一个对象,该对象称为“原型”(prototype)对象。只有null除外,它没有自己的原型对象。原型对象的重要性在于,如果A对象是B对象的原型,那么B对象可以拿到A对象的所有属性和方法。Object.getPrototypof方法用于获取当前对象的原型对象。 通过对象__proto__属性来继承 var obj = {}; var a = {}; obj.__proto__ = a;这里将obj对象原型设为a对象 var a = {x: 99}; var b = {__proto__: a}; b.x // 99上面的示例代码, b对象通过__proto__属性,将自己的原型对象设为a对象,因此b对象可以拿到a对象的所有属性和方法。 b对象本身并没有x属性,但是JavaScript引擎通过__proto__属性,找到它的原型对象a,然后读取a的x属性。 var a = { x: 1 }; var b = { __proto__: a }; var c = { __proto__: b }; c.x // 1这里要注意的是,在原型链寻找某个属性,对性能是有影响的。 寻找的属性在越上层的原型对象,对性能的影响越大。如果寻找某个不存在的属性,将会遍历整个原型链。 原型链继承这里使用了匿名闭包的方式避免全局污染(function(){ function Foo(n,a){ this.name=n; this.age=a; this.action=function(){ console.debug(this.name,this.age); } } function Bua(){ Foo.apply(this,arguments); //Bua继承了Foo的属性和方法 } Bua.prototype=new Foo(); //Bua继承Foo的原型(constructor丢失) Bua.prototype.constructor=Bua; //重新定义Bua函数的constructor })();这里Foo函数的this指针指向了Bua函数,结果就是调用Bua函数相当于调用了Foo(最终实现Bua函数继承了Foo函数的属性和方法), 但是会造成Bua函数的constructor丢失;原因是因为Bua的原型被new Foo()这个实例给重新定义了.而new Foo()这个实例没上没有constructor. 解决办法就是从新定义Bua函数的constructor.ES6的继承Object.create()部分浏览器不支 以上一个为例 Object.create(Foo.prototype,{constructor : {value:Bua}})//会返回一个新对象 Object.create(prototype, descriptors) :创建一个具有指定原型且可选择性地包含指定属性的对象;这里要说一下prototype和__proto__的概念prototype是函数的一个属性(每个函数都有一个prototype属性),这个属性是一个指针,指向一个对象。它是显示修改对象的原型的属性。 __proto__是一个对象拥有的内置属性(请注意:prototype是函数的内置属性,__proto__是对象的内置属性),是JS内部使用寻找原型链的属性。总结:1.__proto__的继承, 只是改变了原型的指向.2.原型链继承, 缺点会产生垃圾属性和方法.3.ES6的继承(推荐), 缺点部分浏览器不支.
2017年10月15日
2 阅读
0 评论
0 点赞
2017-10-10
CSS3新增特性
@Font-face 特性加载字体样式,而且它还能够加载服务器端的字体文件,让客户端显示客户端所没有安装的字体。Word-wrap & Text-overflow 样式Word-wrap设置word-wrap: break-word的话,在单词换行的情况下,可保持单词的完整性。Text-overflow它与 word-wrap 是协同工作的,word-wrap 设置或检索当当前行超过指定容器的边界时是否断开转行,而 text-overflow 则设置或检索当当前行超过指定容器的边界时如何显示, 我们在父容器设置overflow: hidden, 然后设置“text-overflow”属性,有“clip”和“ellipsis”两种可供选择。"clip"表示直接切割,"ellipsis"表示用省略号代替。文字渲染(Text-decoration)Text-fill-color: 文字内部填充颜色Text-stroke-color: 文字边界填充颜色Text-stroke-width: 文字边界宽度CSS3 的多列布局(multi-column layout)Column-count:表示布局几列。Column-rule:表示列与列之间的间隔条的样式Column-gap:表示列于列之间的间隔边框和颜色(color, border)支持rgba和hsl表示颜色, 支持圆角,阴影等效果。CSS3 的渐变效果(Gradient)支持线性渐变和径向渐变。CSS3 的阴影(Shadow)和反射(Reflect)效果阴影效果,阴影效果既可用于普通元素,也可用于文字。CSS3 的背景效果“Background Clip”,该属确定背景画区“Background Origin”,用于确定背景的位置,它通常与 background-position 联合使用,您可以从 border、padding、content 来计算 background-position(就像 background-clip)。“Background Size”,常用来调整背景图片的大小,注意别和 clip 弄混,这个主要用于设定图片本身。“Background Break”属性,CSS3 中,元素可以被分成几个独立的盒子(如使内联元素 span 跨越多行),background-break 属性用来控制背景怎样在这些不同的盒子中显示。多背景图片支持CSS3 的盒子模型display: -webkit-box; display: -moz-box; -webkit-box-orient: horizontal; -moz-box-orient: horizontal;“display: -webkit-box; display: -moz-box;”,它针对 webkit 和 gecko 浏览器定义了该元素的盒子模型。注意这里的“-webkit-box-orient: horizontal;”,他表示水平排列的盒子模型。如果配合元素的box-flex属性:.flex { -webkit-box-flex: 1; -moz-box-flex: 1; } .flex2 { -webkit-box-flex: 2; -moz-box-flex: 2; }水平方向设下的宽度,就可以按照1:2的比例关系自动去计算了。CSS3 的 Transitions, Transforms 和 AnimationTransitionstransition-property:用于指定过渡的性质,比如 transition-property:backgrond 就是指 backgound 参与这个过渡transition-duration:用于指定这个过渡的持续时间transition-delay:用于制定延迟过渡的时间transition-timing-function:用于指定过渡类型,有 ease | linear | ease-in | ease-out | ease-in-out | cubic-bezierTransforms指拉伸,压缩,旋转,偏移等等一些图形学里面的基本变换。Animation @-webkit-keyframes anim1 { 0% { Opacity: 0; Font-size: 12px; } 100% { Opacity: 1; Font-size: 24px; } } .anim1Div { -webkit-animation-name: anim1 ; -webkit-animation-duration: 1.5s; -webkit-animation-iteration-count: 4; -webkit-animation-direction: alternate; -webkit-animation-timing-function: ease-in-out; }
2017年10月10日
1 阅读
0 评论
0 点赞
1
...
13
14