React native

React Native

安装

Homebrew,Mac系统的包管理器,用于安装NodeJS和一些其他必需的工具软件。

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

Node

brew install node

React Native 命令

npm install -g yarn react-native-cli

如果你看到EACCES: permission denied这样的权限报错,那么请参照上文的homebrew译注,修复/usr/local目录的所有权:

sudo chown -R `whoami` /usr/local

Watchman 由Facebook提供的监视文件系统变更的工具

brew install watchman

测试安装

推荐使用WebStorm或Sublime Text来编写React Native应用

react-native init AwesomeProject
cd AwesomeProject
react-native run-ios

flex

Flex 布局语法教程

网页布局(layout)是CSS的一个重点应用。

布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性。它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现。

2009年,W3C提出了一种新的方案—-Flex布局,可以简便、完整、响应式地实现各种页面布局。目前,它已经得到了所有浏览器的支持,这意味着,现在就能很安全地使用这项功能。
Flex布局将成为未来布局的首选方案。本文介绍Flex布局的语法。
以下内容主要参考了下面两篇文章:A Complete Guide to FlexboxA Visual Guide to CSS3 Flexbox Properties

一、Flex布局是什么?

Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。

任何一个容器都可以指定为Flex布局

.box{
      display: flex;
}

行内元素也可以使用Flex布局。

.box{
      display: inline-flex;
}

Webkit内核的浏览器,必须加上-webkit前缀。

.box{
      display: -webkit-flex; /* Safari */
      display: flex;
}

注意,设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。

二、基本概念

采用Flex布局的元素,称为Flex容器(flex container),简称”容器”。它的所有子元素自动成为容器成员,称为Flex项目(flex item),简称”项目”。

容器默认存在两根轴:水平的主轴(main axis)和垂直的交叉轴(cross axis)。主轴的开始位置(与边框的交叉点)叫做main start,结束位置叫做main end;交叉轴的开始位置叫做cross start,结束位置叫做cross end。
项目默认沿主轴排列。单个项目占据的主轴空间叫做main size,占据的交叉轴空间叫做cross size。

三、容器的属性

以下6个属性设置在容器上

  • flex-direction
  • flex-wrap
  • flex-flow
  • justify-content
  • align-items
  • align-content

3.1 flex-direction属性

flex-direction属性决定主轴的方向(即项目的排列方向)。

.box {
      flex-direction: row | row-reverse | column |         column-reverse;
}


它可能有4个值。

  • row(默认值):主轴为水平方向,起点在左端。
  • row-reverse:主轴为水平方向,起点在右端。
  • column:主轴为垂直方向,起点在上沿。
  • column-reverse:主轴为垂直方向,起点在下沿。

3.2 flex-wrap属性

默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。

.box{
     flex-wrap: nowrap | wrap | wrap-reverse;
}

它可能取三个值。
(1)nowrap(默认):不换行。

(2)wrap:换行,第一行在上方。

(3)wrap-reverse:换行,第一行在下方。

3.3 flex-flow

flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap。

.box {
      flex-flow: <flex-direction> || <flex-wrap>;
}

3.4 justify-content属性

justify-content属性定义了项目在主轴上的对齐方式。

.box {
      justify-content: flex-start | flex-end | center | space-between | space-around;
}


它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。

  • flex-start(默认值):左对齐
  • flex-end:右对齐
  • center: 居中
  • space-between:两端对齐,项目之间的间隔都相等。
  • space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。

3.5 align-items属性

align-items属性定义项目在交叉轴上如何对齐。

.box {
      align-items: flex-start | flex-end | center | baseline | stretch;
}


它可能取5个值。具体的对齐方式与交叉轴的方向有关,下面假设交叉轴从上到下。

  • flex-start:交叉轴的起点对齐。
  • flex-end:交叉轴的终点对齐。
  • center:交叉轴的中点对齐。
  • baseline: 项目的第一行文字的基线对齐。
  • stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。

3.6 align-content属性

align-content属性定义了多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
.box {
align-content: flex-start | flex-end | center | space-between | space-around | stretch;
}

该属性可能取6个值。

  • flex-start:与交叉轴的起点对齐。
  • flex-end:与交叉轴的终点对齐。
  • center:与交叉轴的中点对齐。
  • space-between:与交叉轴两端对齐,轴线之间的间隔平均分布。
  • space-around:每根轴线两侧的间隔都相等。所以,轴线之间的间隔比轴线与边框的间隔大一倍。
  • stretch(默认值):轴线占满整个交叉轴。

4.1 order属性

order属性定义项目的排列顺序。数值越小,排列越靠前,默认为0。

.item {
      order: <integer>;
}

4.2 flex-grow属性

flex-grow属性定义项目的放大比例,默认为0,即如果存在剩余空间,也不放大。

.item {
      flex-grow: <number>; /* default 0 */
}

如果所有项目的flex-grow属性都为1,则它们将等分剩余空间(如果有的话)。如果一个项目的flex-grow属性为2,其他项目都为1,则前者占据的剩余空间将比其他项多一倍。

4.3 flex-shrink属性

flex-shrink属性定义了项目的缩小比例,默认为1,即如果空间不足,该项目将缩小。

.item {
     flex-shrink: <number>; /* default 1 */
}

如果所有项目的flex-shrink属性都为1,当空间不足时,都将等比例缩小。如果一个项目的flex-shrink属性为0,其他项目都为1,则空间不足时,前者不缩小。
负值对该属性无效。

4.4 flex-basis属性

flex-basis属性定义了在分配多余空间之前,项目占据的主轴空间(main size)。浏览器根据这个属性,计算主轴是否有多余空间。它的默认值为auto,即项目的本来大小。

.item {
      flex-basis: <length> | auto; /* default auto */
}

它可以设为跟width或height属性一样的值(比如350px),则项目将占据固定空间。

4.5 flex属性

flex属性是flex-grow, flex-shrink 和 flex-basis的简写,默认值为0 1 auto。后两个属性可选。

.item {
      flex: none | [ <'flex-grow'> <'flex-shrink'>? || <'flex-basis'> ]
}

该属性有两个快捷值:auto (1 1 auto) 和 none (0 0 auto)。
建议优先使用这个属性,而不是单独写三个分离的属性,因为浏览器会推算相关值。

4.6 align-self属性

align-self属性允许单个项目有与其他项目不一样的对齐方式,可覆盖align-items属性。默认值为auto,表示继承父元素的align-items属性,如果没有父元素,则等同于stretch。

.item {
      align-self: auto | flex-start | flex-end | center | baseline | stretch;
}

该属性可能取6个值,除了auto,其他都与align-items属性完全一致。
来源:
http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html

css

#css 气泡框
气泡框(或者提示框)是网页中一种很常见的元素,大多用来展示提示信息,如下图所示:

拆分来看,形如这种气泡框无外乎就是一个矩形框+一个指示方向的三角形小箭头,要制作出这样的气泡框,如果解决了三角形小箭头就容易了。一种方法就是制作这样一个三角形箭头的图片,然后定位在矩形框上。但这种解决办法在后期更改气泡框会很不方便,可能每修改一次气泡框都要重新制作一个三角形小图标。如果我们能够直接用HTML和CSS代码实现这样一个三角形小箭头一切都迎刃而解了。

首先我们来看一下border这个属性,当我们把一个div的border-color设为不同值的时候,可以看到四边都成了一个梯形。

# test{width:50px; height:50px; border-width:50px; border-style:solid; border-color:#09F #990 #933 #0C9;}

如果我们继续把这个div的width和height都设为0,可以看到四边都成了一个三角形。

# test{width:0; height:0; border-width:75px; border-style:solid; border-color:#09F #990 #933 #0C9;

在主流浏览器中检测一下,发现IE6中存在一个小问题,上下边能形成三角形,左右两边仍然还是梯形

通过实验发现当把div的font-size和line-height都设为0的时候,div的四边在IE6下都能形成完美的三角形:

#test{ width:0; height:0; border-width:75px; border-style:solid; border-color:#09F #990 #933 #0C9; font-size:0; line-height:0;}

很显然我们只需要其中的一个三角形,那么只需要将其他三边的color设置为透明或者跟页面背景一样的颜色,就能模拟出一个三角来,推荐将其他三边颜色设置为透明,即color的值为transparent,如果其他三边颜色跟页面背景一样,虽然视觉上只能看到一个三角,但背景颜色一旦改变,其他三边颜色也要随之改变。

#test{ width:0; height:0; border-width:75px; border-style:solid; border-color:#09F transparent transparent; font-size:0; line-height:0;}

问题又来了,IE6下transparent无效!其他三边被设置成默认的黑色了。

但通过实验发现把border-style设置为dashed后,IE6下其他三边就能透明了!

#test{ width:0; height:0; border-width:75px; border-style:solid dashed dashed; border-color:#09F transparent transparent; font-size:0; line-height:0;}    

到这一步我们已经成功的模拟出了一个小三角,下一步我们把这个小三角同矩形框结合起来。先设置一个矩形框,然后把小三角定位到矩形框上。先来写出HTML结构:

<div class="tag">
  <em></em>   
  CSS气泡框实现
</div>

CSS样式:

.tag{ width:300px; height:100px; border:5px solid #09F; position:relative;}
.tag em{display:block; border-width:20px; position:absolute; bottom:-40px; left:100px;border-style:solid dashed dashed; border-color:#09F transparent transparent;font-size:0; line-height:0;}

效果如下:

现在指示方向的三角形箭头是实心的,而我们想要的是镂空的效果,这里我们再叠加一个同气泡框背景颜色一样的小三角,然后把这个叠加的小三角移动一下位置就能达到了。
首先需要对HTML结构进行调整,如下:

<div class="tag">
  <em></em>   
  <span></span>
  CSS气泡框实现
</div>

CSS样式修改为:

.tag{ width:300px; height:100px; border:5px solid #09F; position:relative; background-color:#FFF;}

.tag em{display:block; border-width:20px; position:absolute; bottom:-40px; left:100px;border-style:solid dashed dashed; border-color:#09F transparent transparent;font-size:0; line-height:0;}

.tag span{display:block; border-width:20px; position:absolute; bottom:-33px; left:100px;border-style:solid dashed dashed; border-color:#FFF transparent transparent;font-size:0; line-height:0;}

最终效果如下所示:

注意:叠加的小三角span的bottom值并不是border-width的值,两个小三角bottom的差值理论上应该是2(border-width)2的平方根

最后来把代码优化一下,以便在后期更容易维护,完整的HTML结构:

<div class="tag">
 <div class="arrow">
     <em></em><span></span>
    </div>
   CSS气泡框实现
</div>

CSS样式修改为:

.tag{ width:300px; height:100px; border:5px solid #09F; position:relative; background-color:#FFF;}

.arrow{ position:absolute; width:40px; height:40px; bottom:-40px; left:100px; }

.arrow *{ display:block; border-width:20px; position:absolute; border-style:solid dashed dashed dashed; font-size:0; line-height:0; }
.arrow em{border-color:#09F transparent transparent;}

.arrow span{border-color:#FFF transparent transparent; top:-7px;}

举一反三:不规则三角箭头的气泡框又如何实现?

HTML结构同前面一样:

<div class="tag">
     <div class="arrow">
     <em></em><span></span>
    </div>
    CSS气泡框实现
</div>

矩形框CSS样式稍微改动一下:

.tag{ width:300px; height:100px;position:relative; background-color:#09F;}

重新定位一下三角箭头:

.arrow{ position:absolute; width:70px; height:60px; left:-70px; bottom:10px;}

元素相邻的两边border-style值设为solid(显示),另两边设为transparent(不会显示)

.arrow *{ display:block; position:absolute; border-style:dashed solid solid dashed; font-size:0; line-height:0; }

首先模拟一个直角三角形,把一个元素的相邻两边color设为相同的值,另外两边颜色设为透明,即可得到一个直角:

.arrow em{border-color:transparent #09F #09F transparent; border-width:30px 35px;}

把两个直角三角形重叠在一起就可以得到一个不规则三角形

.arrow span{ border-width:20px 35px;border-color:transparent #FFF #FFF transparent; bottom:0;}

至此,不规则三角箭头的气泡框效果已经实现。

除了通过设置元素的border来模拟小三角之外,还可以用特殊字符来模拟,用特殊字符模拟小三角同样需要用到定位和重叠覆盖,只不过不需要调整border属性了。

先来看一个菱形“◆” ,它在页面中的代码是“&#9670”,需要注意的是页面编码需要设置为utf-8,在网页中可以把◆当作文字处理,可以通过调整font-size来它的大小、通过color来设置它的颜色。

HTML结构依然用前面的,不同的是在em、span标签中加入了 ◆

<div class="tag">
     <div class="arrow">
         <em>◆</em><span>◆</span>
    </div>
    CSS气泡框实现
</div>

先来设置最外层div的样式,得到一个矩形框:

.tag{ width:300px; height:100px;position:relative; border:5px solid #09F;}

接着定位箭头最外层容器div,便于观察可以先设置一个背景色 :

.arrow{ position:absolute; width:40px; height:40px; left:100px; bottom:-40px; overflow:hidden;}


再对◆设置样式:

.arrow *{ display:block; position:absolute; font-size:40px; line-height:40px; width:40px; font-family:SimSun; font-style:normal; font-weight:normal; text-align:center; vertical-align:middle;}

注意:为了◆主流浏览器中显示一致,需要清除浏览器的默认字体样式,特别注意这里字体的设置

再分别修改em、span标签的字体颜色,并对这两个标签定位:

.arrow em{ color:#09F; top:-15px;}
.arrow span{ color:#FFF; top:-22px;}

注意:该例子中em和span两个元素垂直方向相差约7px,原来同上面提到的一样,差值理论上应该是2(border-width)2的平方根

完整CSS样式:

.tag{ width:300px; height:100px;position:relative; border:5px solid #09F;}
.arrow{ position:absolute; width:40px; height:40px; left:100px; bottom:-40px; overflow:hidden;}
.arrow *{ display:block; position:absolute; font-size:40px; line-height:40px; width:40px;font-family:SimSun; font-style:normal; font-weight:normal;text-align:center; vertical-align:middle;}
.arrow em{ color:#09F; top:-15px;}
.arrow span{ color:#FFF; top:-22px;}

最终效果如下:

HTML特殊字符查询:http://ikwebdesigner.com/special-characters/

补充:以上方式实现小三角的过程中不可避免的增加了多余的标签,如果不要求所有浏览器中显示一致的话, 我们可以利用css3来实现这个小三角

HTML结构:

<div class="tag">
    css3气泡框
</div>

CSS:

.tag{
        width:300px;
    height:100px;
        border:5px solid #09F;
    position:relative;
    background-color:#FFF;
}
.tag:before,.tag:after{
    content:"";display:block;
    border-width:20px;
    position:absolute; bottom:-40px;
        left:100px;
    border-style:solid dashed dashed;
    border-color:#09F transparent transparent;
    font-size:0;
    line-height:0;
}
.tag:after{
    bottom:-33px;
    border-color:#FFF transparent transparent;
}

javascriptObject

JavaScript面向对象核心知识归纳

面向对象

概念

  • 1.面向对象就是使用对象。面向对象开发就是使用对象开发。
  • 2.面向过程就是用过程的方式进行开发。面向对象是对面向过程的封装。

三大特性

抽象性

所谓的抽象性就是:如果需要一个对象描述数据,需要抽取这个对象的核心数据

  • 1.提出需要的核心属性和方法
  • 2.不在特定的环境下无法明确对象的具体意义
封装性

对象是将数据与功能组合到一起,即封装

  • 1.JS对象就是键值对的集合,键值如果是数据(基本数据、符合数据、空数据)就称为属性,如果键值是函数那么就称为方法
  • 2.对象就是将属性与方法封装起来
  • 3.方法是将过程封装起来
继承性

所谓继承性就是自己没有但是别人有,拿过来成为自己的,就是继承,继承是实现复用的一种手段

  • 在Java等语言中继承满足一个class的规则,类是一个class,他规定了一个对象有什么属性和方法。
  • 在这些语言中继承是class之间的继承,一个class继承另一个class,那么该class就有了另一个class的成员,那么由该class创建出来的对象就同时具有两个class的成员。

在JS中没有明确的继承语法(ES6提供了class extend语法),一般都是按照继承的理念实现对象的成员扩充实现继承,因此JS中实现继承的方法非常对多。

传统继承基于类,JS继承基于对象

一个简单的继承模式:混入(mix)

function mix ( o1, o2 ) {
    for ( var k in o2 ) {
        o1[ k ] = o2[ k ];
    }    
}

关于面向对象的一些其他概念

class:在JS中就是构造函数
  • 在传统的面向对象语言中,使用一个叫类的东西定义模板,然后使用模板创建对象。
  • 在构造方法中也具有类似的功能,因此也称其为类
实例(instance)与对象(object
  • 实例一般是指某一个构造函数创建出来的对象,我们称为XXXX 构造函数的实例
  • 实例就是对象。对象是一个泛称
  • 实例与对象是一个近义词
键值对与属性和方法
  • 在JS中键值对的集合称为对象
  • 如果值为数据(非函数),就称该键值对为属性
  • 如果值为函数(方法),就称该键值对为方法method
  • 父类与子类(基类和派生类)
  • 传统的面向对象语言中使用类来实现继承那么就有父类、子类的概念

  • 父类又称为基类,子类又称为派生类
  • 在JS中没有类的概念,在JS中常常称为父对象,子对象,基对象,派生对象。

构造函数

构造函数是干什么用的

  • 初始化数据的
  • 在JS中给对象添加属性用的,初始化属性值用的

创建对象的过程

  • 1.代码:var p = new Person();
  • 2.首先运算符new创建了一个对象,类似于{},是一个没有任何(自定义)成员的对象。
    • 使用 new 创建对象,那么对象的类型就是创建他的构造函数名
    • 使用{}无论如何都是Object类型,相当于 new Object
  • 3.然后调用构造函数,为其初始化成员
    • 构造函数在调用的一开始,有一个赋值操作,即this = 刚刚创建出来的对象。
    • 因此在构造函数中this表示刚刚创建出来的对象。
  • 4.在构造函数中 利用 对象的动态特性 为其对象添加成员。

作用域

什么是作用域

域表示的就是范围,即作用域,就是一个名字在什么地方可以使用,什么时候不能使用。

JS中词法作用域的规则

  • 1.函数允许访问函数外部的数据
  • 整个代码结构中只有函数可以限定作用域
  • 作用规则首先使用提升规则分析
  • 如果当前作用域中有了名字了,就不考虑外面的名字

属性搜索原则

  • 所谓的属性搜索原则,就是对象在访问属性或方法的时候,首先在当前对象中查找
  • 如果当前对象中存储着属性或方法,停止查找,直接使用该属性或方法
  • 如果当前对象没有该成员,那么再在其原型对象中查找
  • 如果原型对象中含有该成员,那么停止查找,直接使用
  • 如果原型中还没有,就到原型的原型中查找
  • 如此往复,直到Object.protitype还没有,那么就返回undefined
  • 如果是调用方法就报错,该xxx不是一个函数

闭包

闭包的概念

什么是闭包?

闭包的含义就是闭合,包起来,简单的来说,就是一个具有封闭功能与包裹功能的结构。所谓的闭包就是一个具有封闭的对外不公开的,包裹结构,或空间。

为什么函数可以构成闭包?

闭包就是一个具有封闭与包裹功能的结构,是为了实现具有私有访问空间的函数的。函数可以构成闭包。函数内部定义的数据函数外部无法访问,即函数具有封闭性;函数可以封装代码即具有包裹性,所以函数可以构成闭包。

闭包有什么用

闭包不允许外部访问,要解决的问题就是让外部间接访问函数内部的数据。事实上,通过使用闭包,我们可以做很多事情。比如模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的执行效率。利用闭包可以实现如下需求:

  • 1.匿名自执行函数一个匿名的函数,并立即执行它,由于外部无法引用它内部的变量,因此在执行完后很快就会被释放,关键是这种机制不会污染全局对象。
  • 2.缓存闭包正是可以做到这一点,因为它不会释放外部的引用,从而函数内部的值可以得以保留。
  • 3.实现封装
  • 4.模拟面向对象的代码风格

闭包的基本模型

  • 1.对象模式函数内部定义个一个对象,对象中绑定多个函数(方法),返回对象,利用对象的方法访问函数内的数据
  • 2.函数模式函数内部定义一个新函数,返回新函数,用新函数获得函数内的数据
  • 3.沙箱模式沙箱模式就是一个自调用函数,代码写到函数中一样会执行,但是不会与外界有任何的影响

闭包的作用举例

  • 1.获得超过一个数据,返回一个对象
  • 2.完成读取一个数据和修改这个数据,对象里面的getset方法

闭包的性能问题

函数执行需要内存,那么函数中定义的变量,会在函数执行结束后自动回收,凡是因为闭包结构的,被引出的数据,如果还有变量引用这些数据的话,那么这些数据就不会被回收。因此在使用闭包的时候如果不使用某些数据了,一定要赋值一个null

var f = (function () {
    var num = 123;
    return function () {
        return num;
    };
})();
// f 引用着函数,函数引用着变量num
// 因此在不使用该数据的时候,最好写上
f = null;

原型

什么是原型

一句话说明什么是原型:原型能存储我们的方法,构造函数创建出来的实例对象能够引用原型中的方法。

JS中一切皆对象,而每个对象都有一个原型(Object除外),这个原型,大概就像Java中的父类,所以,基本上你可以认为原型就是这个对象的父对象,即每一个对象(Object除外)内部都保存了它自己的父对象,这个父对象就是原型。一般创建的对象如果没有特别指定原型,那么它的原型就是Object(这就很类似Java中所有的类默认继承自Object类)。

ES6通过引入class ,extends等关键字,以一种语法糖的形式把构造函数包装成类的概念,更便于大家理解。是希望开发者不再花精力去关注原型以及原型链,也充分说明原型的设计意图和类是一样的。

查看对象的原型

当对象被创建之后,查看它们的原型的方法不止一种,以前一般使用对象的proto属性,ES6推出后,推荐用 Object.getPrototypeOf()方法来获取对象的原型.

function A(){
    this.name='lala';
}
var a=new A();
console.log(a.__proto__) 
//输出:Object {}

//推荐使用这种方式获取对象的原型
console.log(Object.getPrototypeOf(a)) 
//输出:Object {}

无论对象是如何创建的,默认原型都是Object,在这里需要提及的比较特殊的一点就是,通过构造函数来创建对象,函数A本身也是一个对象,而A有两个指向表示原型的属性,分别是proto和prototype,而且两个属性并不相同

function A(){
       this.name='lala';
}
var a=new A();
console.log(A.prototype) 
//输出:Object {}

console.log(A.__proto__) 
//输出:function () {}
console.log(Object.getPrototypeOf(A))
//输出:function () {}

函数的的prototype属性只有在当作构造函数创建的时候,把自身的prototype属性值赋给对象的原型。而实际上,作为函数本身,它的原型应该是function对象,然后function对象的原型才是Object。

总之,建议使用ES6推荐的查看原型和设置原型的方法。

原型的用法

其实原型和类的继承的用法是一致的:当你想用某个对象的属性时,将当前对象的原型指向该对象,你就拥有了该对象的使用权了。

function A(){
    this.name='world ';
}
function B(){
    this.bb="hello"
}
var a=new A();
var b=new B();

//将b设置为a的原型,此处有一个问题,即a的constructor也指向了B构造函数,可能需要纠正 
Object.setPrototypeOf(a,b);
a.constructor=A;
console.log(a.bb);    //hello

如果使用ES6来做的话则简单许多,甚至不涉及到prototype这个属性

class B{
     constructor(){
        this.bb='hello'
     }
}
class A  extends B{
     constructor(){
        super();
        this.name='world';
     }
}

var a=new A();
console.log(a.bb+" "+a.name);    //hello world
console.log(typeof(A))                //"function"

怎么样?是不是已经完全看不到原型的影子了?活脱脱就是类继承,但是你也看得到实际上类A 的类型是function,所以说,本质上class在JS中是一种语法糖,JS继承的本质依然是原型,不过,ES6引入class,extends 来掩盖原型的概念也是一个很友好的举动,对于长期学习那些类继承为基础的面对对象编程语言的程序员而言。

我的建议是,尽可能理解原型,尽可能用class这种语法糖。

好了,问自己两个问题:

  • 1.为什么要使用原型?——提高函数的复用性。
  • 2.为什么属性不放在原型上而方法要放在原型上?

    • 利用对象的动态特性:构造函数.prototype.xxxx = vvv
    • 利用直接替换

      Student.prototype = {
      sayHello : function(){},
      study : function(){}
      };

原型链

什么是原型链?

凡是对象就有原型,那么原型又是对象,因此凡是给定一个对象,那么就可以找到他的原型,原型还有原型,那么如此下去,就构成一个对象的序列,称该结构为原型链。

这个概念其实也变得比较简单,可以类比类的继承链条,即每个对象的原型往上追溯,一直到Object为止,这组成了一个链条,将其中的对象串联起来,当查找当前对象的属性时,如果没找到,就会沿着这个链条去查找,一直到Object,如果还没发现,就会报undefined。

原型链的结构

凡是使用构造函数,创建出对象,并且没有利用赋值的方式修改原型,就说该对象保留默认的原型链。
默认原型链结构是什么样子呢?

function Person(){}
var p = new Person();
//p 具有默认的原型链

默认的原型链结构就是:当前对象 -> 构造函数.prototype -> Object.prototype -> null

在实现继承的时候,有时候会利用替换原型链结构的方式实现原型继承,那么原型链结构就会发生改变

function DunizbCollection(){}
DunizbCollection.prototype = [];
var arr = new DunizbCollection();

此时arr对象的原型链结构被指向了数组对象的原型链结构了:arr -> [] -> Array.prototype -> Object.prototype -> null

用图形表示对象的原型链结构

以如下代码为例绘制原型链结构

function Person(){}
var p = new Person();

原型链结构图为:

使用原型需要注意两点:

  • 1.原型继承链条不要太长,否则会出现效率问题。
  • 2.指定原型时,注意constructor也会改变。
    继承
    实现继承有两种常见方式:

混合式继承:最简单的继承就是将别的对象的属性强加到我身上,那么我就有这个成员了。
混合式继承的简单描述:

var Person = function () {};
Person.prototype.extend = function ( o ) {
     for ( var k in o ) {
          this[ k ] = o[ k ];
     }
};
Person.prototype.extend({
      run: function () { console.log( '我能跑了' ); },
      eat: function () { console.log( '我可以吃了' ); },
      sayHello: function () { console.log( '我吃饱    了' ); }
});

原型继承:利用原型也可以实现继承,不需要在我身上添加任何成员,只要原型有了我就有了。

借用构造函数继承

这种技术的基本思想相当简单,即在子类型构造函数的内部调用超类型构造函数,而函数只不过是在特定环境中执行代码的对象,因此通过使用apply()和call()方法也可以在(将来)新创建的对象上执行构造函数

function Person ( name, age, gender ) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}
// 需要提供一个 Student 的构造函数创建学生对象
// 学生也应该有 name, age, gender, 同时还需要有 course 课程
function Student ( name, age, gender, course ) {
    Person.call( this, name, age, gender );
    this.course = course;
}

在《JavaScript高级程序设计(第三版)》中详细介绍了继承的6种方式

函数的四种调用模式

函数模式

就是一个简单的函数调用。函数名的前面没有任何引导内容。

方法模式

方法一定式依附与一个对象,将函数赋值给对象的一个属性,那么就成为了方法。

构造器调用模式

创建对象的时候构造函数做了什么?由于构造函数只是给 this 添加成员,没有做其他事情。而方法也可以完成这个操作,就是 this 而言,构造函数与方法没有本质的区别。

特征

  • 1.使用 new 关键字,来引导构造函数。
  • 2.构造函数中的 this 与方法中的一样,表示对象,但是构造函数中的对象是刚刚创建出来的对象
    • 3.构造函数中不需要 return ,就会默认的 return this。
    • 如果手动添加return ,就相当于 return this
    • 如果手动的添加 return 基本类型,无效,还是保留原来 返回 this
    • 如果手动添加的 return null,或 return undefined ,无效
    • 如果手动添加 return 对象类型,那么原来创建的 this 就会被丢掉,返回的是 return 后面的对象
创建对象的模式
  • 1.工厂方法,工厂就是用来生产的,因此如果函数创建对象并返回,就称该函数为工厂函数
  • 2.构造方法
  • 3.寄生式创建
  • 4.混合式创建

上下文调用模式

上下文就是环境。就是自己定义设置 this 的含义。

语法

  • 函数名.apply( 对象, [ 参数 ] );
  • 函数名.call( 对象, 参数 );

描述

  • 1.函数名就是表示函数本身,使用函数进行调用的时候默认 this 是全局变量
  • 2.函数名也可以是方法提供,使用方法调用的时候,this 是指向当前对象
  • 3.使用 apply 进行调用后,无论是函数还是方法都无效了,我们的 this ,由 apply 的第一个参数决定

参数问题

无论是 call 还是 apply 在没有后面的参数的情况下(函数无参数,方法五参数)是完全一致的

function foo(){
    console.log( this );
}
foo.apply( obj );
foo.call( obj );

第一个参数的使用也是有规则的:

  • 1.如果传入的是一个对象,那么就相当于设置该函数中的 this 为参数
  • 2.如果不传入参数,或传入 null 、undefined 等,那么相当于 this 默认为 window

    foo();
    foo.apply();
    foo.apply( null );
    foo.call( undefined );
    
  • 3.如果传入的是基本类型,那么 this 就是基本类型对应的包装类型的引用
    在使用上下文调用的时候,原函数(方法)可能会带有参数,那么这个参数再上下文调用中使用 第二个(第 n 个)参数来表示

    function foo( num ) {
        console.log( num );
    }
    foo.apply( null, [ 123 ] );
    // 等价于
    foo( 123 );
    

    参考资料

  • 本文原型部分部分引用自《JavaScript原型详解》,版权归原作者所有
  • js闭包的用途

摘自:慕课网

git

GitHub

用github来展示你的前端页面吧

前言

经常会有人问我如何才能将自己做的静态页面放到网上供他人欣赏,是不是需要自己有一个服务器,是不是还要搞个域名才能访问?对于以上问题我都会回答:用github来展示你的前端页面吧。

工欲善其事,必先利其器。github是一个很好的代码管理与协同开发平台,在程序界又被称为最大的“同性交友网站”。如果你不懂git,没有自己的github账户,那你就丢失了一把能够很好的展示自我,储存知识的利器。

当然知道github的人不在少数,但是大部分人可能仅知道它可以用于管理我们的项目代码,而不知道其还可以用于展示我们前端的静态页面。比如:

https://github.com/luozhihao/demo

了解github的人都知道上方的地址指向的是一个github项目目录,同时你可能还会发现这样的一个地址:

https://luozhihao.github.io/demo

上方的地址就是对应demo项目的展示页面了。

步骤

其实利用github来展示前端静态页面的例子很多,比如各种插件、框架的demo演示地址都会这样做,那么下面我们就来实际操作一下,体验一把展示自己前端项目成果的乐趣。

1.安装git

如果你是mac用户,那么恭喜你mac自带git命令功能,你无须安装git。如果你是windows用户,你可以前往windows地址下载并安装。

2.建立仓库

在你的github主页,我们可以点击右上角的加号按钮下的“New repository”来新建一个项目仓库,如图所示:

点击之后我们给仓库取一个名字并进行相应的描述和配置后点击“Create repository”就ok了。

3.上传代码

仓库建立完毕后,这时候就需要用我们之前安装的git命令来将本地的代码推送到github上了。如果你仅为了展示自己的前端页面,那么只要掌握如下命令即可(不熟悉git命令的可以参考git - 简易指南):

(1)打开你的目录

cd demo

(2)初始化版本库,用于生成.git文件

git init

(3)将所有文件添加到缓存区

git add *

(4)提交当前工作空间的修改内容

git commit -m "first commit"

(5)将仓库连接到远程服务器

git remote add origin <server>

(6)将改动推送到所添加的服务器上

git push -u origin master

上方server中的地址在github上创建仓库后可以找到,如下:

4.创建gh-pages分支

之前的工作只是将我们的代码发布到了github上demo仓库的master分支上,当然你也可以不发布,而我们的展示页面代码必须发布到名为“gh-pages”的分支上。方法很简单,我们只需要在github的demo项目页面手动创建gh-pages分支即可。如图:


输入gh-pages后创建即可,这样的方式会直接拷贝master分支的所有文件到gh-pages分支,而你也可以用命令行的形式创建并重新上传一份新的代码:

(1)新建并切换到gh-pages分支

git checkout --orphan gh-pages

(2)之后的操作和之前一样,只是push的时候是gh-pages

git add *
git commit -m "update"
git push -u origin gh-pages

如此,我们的demo项目就多了一个gh-pages分支,里面的代码文件就可以用来展示页面了。

5.访问页面

创建并上传文件至gh-pages之后,我们就可以访问如下url来查看自己的demo了:

http://(user_name|org_name).github.io/repo_name

这里我们的demo地址为:https://luozhihao.github.io/demo/, 最终页面如图:


这样我们便实现了利用github来展示前端静态页面的目标。

结语

很多时候方法就摆在眼前,就看你会不会捅破那层隔膜,敢不敢进行钻研与尝试。github之所以经久不衰是因为其不仅解决了我们代码提交、版本管理的问题,还提供了其他实用而独特的功能,对我们学习github真的有很大的帮助。

本文只针对Github Pages提供给我们展示静态页面(不支持服务端语言)的功能做了基础的介绍,至于想真正掌握并了解更加深入内容的同学还请付诸于实践,比如利用gihub搭建博客等。

补充:根据读者反馈,现在github有一种更加简便的方式来实现上述功能,将代码上传至仓库后在settings里配置下GitHub Pages为你想展示的分支就行了。
转载自:http://gold.xitu.io/post/582ffaf9da2f600063f40660?utm_source=gold_browser_extension

javascript gif

JavaScript

javaScript总结

javascript变量.gif

javascript函数基础.gif

javascript流程控制.gif

javascript数据类型.gif

javascript 数组.gif

javascript 运算符.gif

javascript 正则表达式.gif

javascript 字符串函数.gif

javascript Window对象.gif

javascript DOM基本操作.gif

希望这几张图能对你有所帮助

blog building

GitHub博客搭建

GitHub,上传hexo博客搭建过程

安装 nodeJS

nodeJS官网网址:http://nodejs.org/en/

测试nodeJS是否安装成功:

1
node -v

安装 hexo

安装命令:

1
$ npm install hexo -g

测试nodeJS是否安装成功:

1
$ hexo

创建目录并进入

初始化hexo目录

1
hexo init

启动本地服务

1
hexo server

GitGub账号一枚

配置ssh-key

连续三次回测

1
ssh-keygen

复制ssh-key

1
vim~/.ssh/id rsa.pub

github设置ssh黏贴

配置github与本地机器验证

1
git config --global user.name ""
1
git config --global user.name ""

新建博客域名仓库

用户名 .github.io

config

deplay字段

type:git

repo:域名仓库https地址

发布

1
npm install hexo-deplayer-git --save
1
hexo g
1
hexo d

新建项目标题

1
bolog $ hexo project

进入source中找到该文件夹,进去Mou中书写格式(偏好设置)

在博客中设置主题背景

网址:http://www.zhihu.com/question/24422335/answer/46357100

具体操作:

  • 命令终端找到themes文件
  • 终端命令
    1
    git clone 主题网址

例:git clone https://github.com/A-limon/pacman.git

  • 命令:
    ls
    
    找到下载的文件夹,将其复制到_config.yml中,themes:复制名
  • 启动终端命令

    hexo server

回到[发布]流程重新输入命令

很惭愧<br><br>只做了一点微小的工作<br>谢谢大家