<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Tsrot Space</title>
  
  <subtitle>This is tsrot blog</subtitle>
  <link href="/atom.xml" rel="self"/>
  
  <link href="http://blog.xieliqun.com/"/>
  <updated>2018-10-23T07:33:44.279Z</updated>
  <id>http://blog.xieliqun.com/</id>
  
  <author>
    <name>Tsrot</name>
    
  </author>
  
  <generator uri="http://hexo.io/">Hexo</generator>
  
  <entry>
    <title>锋阅网杂志APP产品体验分析</title>
    <link href="http://blog.xieliqun.com/2018/10/20/%E9%94%8B%E9%98%85%E7%BD%91APP%E4%BA%A7%E5%93%81%E5%88%86%E6%9E%90/"/>
    <id>http://blog.xieliqun.com/2018/10/20/锋阅网APP产品分析/</id>
    <published>2018-10-20T05:05:46.000Z</published>
    <updated>2018-10-23T07:33:44.279Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>我是一个阅读爱好者，在高中时代，读者、意林、青年文摘基本上每期都买。里面的每篇文章都选取的还不错，让人深受启发或感动。所以第一眼看到这类APP我是充满兴趣的，我是带着情怀去体验的。<br><a id="more"></a></excerpt></p><the rest="" of="" contents="" |="" 余下全文=""><h2 id="市场与需求分析"><a href="#市场与需求分析" class="headerlink" title="市场与需求分析"></a>市场与需求分析</h2><h3 id="1、产品的用户群体是哪些？"><a href="#1、产品的用户群体是哪些？" class="headerlink" title="1、产品的用户群体是哪些？"></a>1、产品的用户群体是哪些？</h3><p>根据APP的推荐文章和杂志阅读排行榜来看，APP的用户应该还是偏年轻，所以我认为APP的目标用户应该是24岁以下的学生群体或一些自由作家等，主要偏高中生、初中生等。他们有一些课外时间，比较有兴趣去阅读这些简短的文章。在繁重的学习作业之外，这可能是他们唯一的释放学习压力的课外读物。</p><p>因为没有做问卷调查和用户访谈，没法精准的做一些用户画像分析。我用了一些互联网用户分析工具。下面是易观万象的一些统计截图。</p><p><img src="https://ws2.sinaimg.cn/large/006tNbRwly1fwdmd9dod1j317k0g2whi.jpg" alt=""></p><p><img src="https://ws4.sinaimg.cn/large/006tNbRwly1fwdmgl4fnoj31kw0hln2w.jpg" alt=""></p><p>根据分析工具，我们发现：这部分目标用户大部分为女性，消费水平偏中下水平，使用的手机主要还是中低档手机，人群分布主要在长三角、珠三角等沿海发达城市。</p><h3 id="2、产品的用户需求是什么？"><a href="#2、产品的用户需求是什么？" class="headerlink" title="2、产品的用户需求是什么？"></a>2、产品的用户需求是什么？</h3><p>根据每个人的所处环境和生活习惯不同，读文章和看书籍的品味也是不一样的。一般来说，读者，意林等杂志类的书刊，是有一些共同性的，也就有类似的用户需求：</p><p>（1）从内容上得到一些启发。读者一类的书刊，文章都是短篇的，具有较为完整的寓意和结构，一般结尾都是有情感的抒发和道理的论述。我们读一读，有的时候会有一些思维上的启发，这是比较重要的。</p><p>（2）打发时间。虽然这样说起来有一些唐突，但实际上，因为都是短篇的小文章，更适合于短时间内品读。比如等车的时候，外出乘车的时候，阶段性的时间内可以打发一下时间，这类书刊主要针对的就是这些情况。</p><p>（3）写作素材，这些杂志里的文章都还选取的不错，对于一些中学生来说，可以得到一些不错的写作素材。</p><p>（4）文化的传播，这类书刊一般价格较低，更能被大众接受。有些文章是可以从其他书刊上转载来的，也相对精华。由于传播范围较广，也能使一些精华的文章被更多人品读，这也是在一定程度上，对于优秀文化的传播，起到了推动作用。</p><p>上面介绍的是纸质书就可以解决的用户需求，为什么要用APP去看这些杂志书籍呢？</p><p>（1）在APP里看杂志方便，只要打开手机就能看，不受时间、空间的限制。可以充分利用碎片时间，无论是乘车、课间、饭后、还是睡前都可以看。</p><p>（2）在APP里看杂志省钱，一本杂志大概是七八块钱左右，一个月按两期算，订两三种，一个月大概要几十块钱左右。而在APP里可能也就十几块钱。</p><p>（3）在APP里内容更加丰富，我可以看同类型的所有杂志，我也可以快速找到我想看的文章。</p><p>（4）在APP里更加方便的收藏好的文章、好的句子，更加方便的去做一些笔记。</p><p>###3、用户需求的市场量有多大？</p><p><strong>行业概述</strong>：2017年中国移动阅读市场规模稳步上升达132.2亿，同比增长32.1%，增长率相比去年有所降低。2017年中国移动阅读行业用户规模达到3.4亿，同比增长13.2%，增长率较之去年有明显下降。</p><p><strong>发展现状</strong>：移动阅读行业正版化得到极大的发展，各大内容平台的优势逐渐凸显，整个市场竞争格局趋于稳定。其中阅文集团、掌阅科技、咪咕数媒、阿里文学以超过7%的APP月度覆盖人数占比稳坐第一梯队。</p><p><strong>发展趋势</strong>：移动阅读APP不断正版化，用户付费习惯逐渐养成且持续提升。影视二次元游戏全IP化，共享版权模式出现。</p><p><img src="https://ws1.sinaimg.cn/large/006tNbRwly1fwdwump0mfj31ha0ui42q.jpg" alt=""></p><p><img src="https://ws1.sinaimg.cn/large/006tNbRwly1fwdwymbpikj31480p0juv.jpg" alt=""></p><p>轻阅读领域类似产品情况如下：</p><p><img src="https://ws3.sinaimg.cn/large/006tNbRwly1fwg650qybuj31kw0jq42e.jpg" alt=""></p><p>这些APP2018年2月月活量分别是一个148万、知乎日报158万、每天读点故事63万、诗歌本42万。在轻阅读领域已经算非常不错了，毕竟这个需求不是像即时通讯那么大众。</p><p>根据百度和其官网等一些渠道可得知：读者月发行量大约在800万左右，意林月发行量大约在200万左右。如果能将这些纸质上的用户完全转化为产品用户，那其实也是一个比较可观的用户量。</p><p>意林2010年6月，数字出版部成立。</p><p>读者2011年首款苹果App上线，当年客户端下载量即突破300万。</p><p>随着移动互联网的崛起，传统杂志社逐渐面临转型，杂志类移动数字阅读变得越来越重要。</p><h3 id="4、这个市场是否存在竞争对手，对手的情况如何？"><a href="#4、这个市场是否存在竞争对手，对手的情况如何？" class="headerlink" title="4、这个市场是否存在竞争对手，对手的情况如何？"></a>4、这个市场是否存在竞争对手，对手的情况如何？</h3><p>（1）<strong>移动数字阅读 VS 传统纸质阅读</strong></p><p>现如今，对于读者、意林等杂志用户数量传统纸质阅读应该还是占据主导，但随着出版社和用户观念的逐渐转变，相信移动数字阅读会逐渐展现优势。</p><p>传统纸质阅读代表：线下书店。</p><p>（2）<strong>杂志数字出版物 VS 网络文学出版物</strong></p><p>杂志数字出版物和网络文学出版物，在用户层次上将会有大部分重合，所以它们可能存在竞争关系。但在需求层次上，它们将是两个不同的需求，杂志数字出版物面对的需求可能更多的是学习、心灵启发等；网络文学出版物更多是快餐式文化，解决的是用户精神娱乐层面的需求。</p><p>网络文学出版物代表：咪咕、阅文集团、掌阅等。</p><p><img src="https://ws4.sinaimg.cn/large/006tNbRwly1fwdx0duqx6j31kw0kitmz.jpg" alt=""></p><p>（3）<strong>杂志数字出版物 VS 其他数字出版物</strong></p><p>杂志数字出版物与其他数字出版物，在用户层次上有部分重合，杂志数字出版物偏向于24岁以下的学生群体，他们学习压力较重，没有足够多的时间去阅读内容较长的文学作品，他们更多的精力是会花在课内学习中；而其他数字出版物偏向于毕业之后的上班白领阶级，他们有较好的收入，有积极提升自己的意向。</p><p>其他数字出版物代表：一些职业提升书籍、世界名著等。</p><h2 id="产品分析"><a href="#产品分析" class="headerlink" title="产品分析"></a>产品分析</h2><p>下面的产品分析没有说明的部分，都以小读APP为例。</p><h3 id="1、产品定位分析"><a href="#1、产品定位分析" class="headerlink" title="1、产品定位分析"></a>1、产品定位分析</h3><p><strong>定位</strong>：成功人士的随身轻阅读应用</p><p><strong>slogan</strong>：小读怡情</p><p><strong>主要亮点</strong>：</p><p>1、每日小文推送，小读怡神旷心</p><p>告别碎片阅读，告别长篇大论，小读，带给你不一样的阅读体验</p><p>2、千册杂志更新，小读增雅添趣</p><p>海量杂志，随时阅读，“小读”会员，畅读百余种国内主流杂志，轻松掌握各类讯息。<br>杂志内容完整，排版精良，阅读体验媲美纸版杂志<br>高质量的文章与图片,负责任的内容。<br>您将无需再奔波于路边报刊亭,或翻阅厚重的纸刊，轻松下载既可享受时尚的阅读新体。</p><p>3、查找便捷</p><p>可以搜索你想看的杂志和内容</p><p>上面都是小读APP里介绍的，经过几天的体验和一些用户分析，说说我的感受。</p><p>产品是内容定位是杂志类内容阅读，用户群体大部分是从纸质阅读迁移过来的。所以产品的用户群体应该只是纸质用户的一个子集。从产品的用户数据来看这部分用户大部分是24岁以下的年轻用户。APP里排名前三的杂志分别是：读者、故事会、意林。这些杂志的用户群体应该都是偏年轻的，而不是偏商业的。而且推荐文章也基本上是偏娱乐、文艺的，而不是偏商业的。所以用户定位为成功人士我感觉是矛盾的。</p><p>“告别碎片阅读，告别长篇大论”，并没有突出重点。我认为应该突出“精选阅读，推荐优质文章，告别信息繁多，无效阅读”。</p><p><img src="https://ws1.sinaimg.cn/large/006tNbRwly1fw99v26fvjj31kw0ob42b.jpg" alt=""></p><p><img src="https://ws3.sinaimg.cn/large/006tNbRwly1fwejgqvui1j30ni13e1f4.jpg" alt=""></p><h3 id="2、产品功能分析"><a href="#2、产品功能分析" class="headerlink" title="2、产品功能分析"></a>2、产品功能分析</h3><h4 id="（1）产品功能结构分析"><a href="#（1）产品功能结构分析" class="headerlink" title="（1）产品功能结构分析"></a>（1）产品功能结构分析</h4><p><img src="https://ws3.sinaimg.cn/large/006tNbRwly1fwelyv7z67j31kw201190.jpg" alt=""></p><p>产品分为5大板块：小文、小书、全站畅读、书架、我的。</p><p><strong>小文</strong>：每日推送文章，用户可以签到，可以阅读自己喜欢的文章，也可以搜索自己喜欢的文章，但是查找功能有点弱，只能按标题名或杂志书名查找，其实可以给文章分类加标签等，用户搜索的时候可以查找的范围包括标题、书名、标签等，这样查找出的内容可能更符合用户思维。</p><p>进入文章页面，可以阅读文章，可以调整自己的阅读风格，阅读完文章，系统将推荐两篇相关文章，当然也可以为该文章点赞，可以评论文章等。</p><p><strong>小书</strong>：这个版块，用户一进入就可以看到书籍分类菜单，左上角也可以查看分类信息，用户可以直接了当的进入自己喜欢的类目。如果用户比较盲目，不知道看哪些书，那么系统将会给一些推荐，如排行榜、免费专区、编辑推荐、新书上架等。如果用户一进入页面目标就很明确，那么用户也可以用右上角的搜索书籍功能。</p><p>选择好自己想要阅读的书名后，用户可以查看该书的所有期数，可以选择查看哪期，然后进入当前期杂志页面，在该页面你可以查看到这本杂志的一些介绍，阅读、下载、关注该杂志。系统也将会为用户推荐看过此杂志的人还看过哪些杂志。这个阅读书籍的路径有点长，对于用户来说，是比较烦的一个过程，每次阅读一本杂志都要经过这么长的一个路径，应该尽量缩短阅读路径。在小书界面，查找或选中那本杂志之后，直接进入该杂志最新一期的杂志介绍页面，至于往期杂志的入口也可以放在这个地方。对于用户来说，尤其是经常使用的用户，他往往想看的就是最新一期的杂志。在产品设计理念里，用户路径最好控制在三层以内。</p><p><strong>全站畅读</strong>：这个版块做的其实比较简单，就是一个付费订阅页面，而且放在一个最显著的位置。我感觉是有点不妥的。整个APP到处都放着VIP订阅入口，感觉还是以传统的思维在做互联网产品，这似乎时刻在告诉用户：“你再不付费，我就不给你看了”。其实放在这也不是不可以，可以参考喜马拉雅APP的VIP页面，作为一个产品，你得要有足够的吸引力，才能促使用户付费，不是说我一直在你耳边念叨着“赶紧付费，赶紧付费，赶紧付费  ….. ”，用户就会付费订阅，这样只会引起用户的反感。</p><p><strong>书架</strong>：在书架版块你可以查看到你最近阅读的是哪本书，你的书架里有哪些书。你可以整理你的书架，把一些不看的书籍删掉。如果你的书籍很多，你可以用右上角的搜索去搜索你想看的书，当然这里的书是指你书架里的书。有个不好的体验，这里书籍的排列顺序是按照你加入的时间，之后的顺序就不能再变化了，因为并不能对书籍排序。整理书籍和查找书籍，我猜想可能正是为了解决这个问题吧。</p><p>点击最近阅读进入的是该书的目录页面，并没有回到你上次阅读的起点，也没有书签功能。点击下面的书籍进入的是该书籍集合页面，选择哪期后才能进入该书的目录。这个阅读路径还是比较长，虽然文章很短，但有时也不知道自己读到了哪里，没有书签真的是会比较麻烦，至少也要告诉用户哪些是已经阅读过的。</p><p><strong>我的</strong>：在“我的”版块，用户可以看到自己的一些个人账户信息、关注收藏信息，还有一些设置项。这个版块有个不好的地方是，直接把用户的手机号作为用户名了，虽然这个地方可以修改，但有些不注重个人信息隐私的人，将很容易泄露自己的电话号码。</p><h4 id="（2）产品UI与交互分析"><a href="#（2）产品UI与交互分析" class="headerlink" title="（2）产品UI与交互分析"></a>（2）产品UI与交互分析</h4><p>产品的整体UI看来，感觉还是比较陈旧。</p><p>“小文”这个模块有点像资讯类APP，感觉内容过多，页面过于凌乱，在这个信息爆炸的时代，你越能击中用户的需求点，就越能获取用户的喜爱。精准的推荐和简洁的界面是产品比较欠缺的。</p><p>里面文章的阅读风格还是偏资讯类的风格，并没有突出自己的特点。很多用户可能都是从纸质阅读迁移过来的，他们更希望能体验到纸质阅读那种畅快。作为一页到底的去展示一篇文章，而不是书籍翻页去展示，我感觉是比较好的。评论模块，我感觉是体验比较差的，虽然需要评论，但可以隐藏一点，我有自己的感想，我有自己的认知，我不想受别人影响，可能也不想和别人分享。毕竟杂志类文章，不是时事评论，不是新闻资讯，里面的文章基本上是观点类文章。</p><p>书籍阅读界面不太统一。有的像资讯文章界面，有的是PDF扫描版。我觉得需要统一，尽可能保持一致的体验。</p><p>支付宝支付接口经常支付失败。</p><h4 id="（3）用户评价"><a href="#（3）用户评价" class="headerlink" title="（3）用户评价"></a>（3）用户评价</h4><p>从用户评价反馈来看，还是有挺多待优化的地方，丰富的内容是APP最大的优势。</p><p>优点：内容丰富、更新比较快。</p><p>缺点：交互体验差、不太稳定，时常黑屏闪退。</p><p><img src="https://ws1.sinaimg.cn/large/006tNbRwly1fweyeo4rqfj31ja0cowfu.jpg" alt=""></p><p><img src="https://ws3.sinaimg.cn/large/006tNbRwly1fwey7mlrm3j31kw07xtaw.jpg" alt=""></p><p><img src="https://ws1.sinaimg.cn/large/006tNbRwly1fwey94bq9oj31kw08amza.jpg" alt=""></p><p><img src="https://ws2.sinaimg.cn/large/006tNbRwly1fweykrdaemj31kw0qg78z.jpg" alt=""></p><h3 id="3、产品运营数据分析"><a href="#3、产品运营数据分析" class="headerlink" title="3、产品运营数据分析"></a>3、产品运营数据分析</h3><p>毕竟是一款比较小众的APP，网上可以查询到数据太少了，只做了一个大概的下载量和月活数的推测。其他的用户人群分析、访问时长与时段、访问终端等数据还是比较难推测。</p><p>我从锋阅网APP中选取了用户量最大的三个APP，作为此次运营分析的重点。以下数据来源根据艾瑞数据、易观千帆、七麦数据、APP Annie等数据源推测而来，数据为Android和iOS的总和。</p><table><thead><tr><th></th><th>读者</th><th>意林</th><th>小读</th></tr></thead><tbody><tr><td><strong>下载量</strong></td><td>约162万</td><td>约67万</td><td>约25万</td></tr><tr><td><strong>月活</strong></td><td>约3万</td><td>小于1万</td><td>小于1万</td></tr></tbody></table><p><strong>简单介绍一下我的数据推算过程</strong></p><p>下载量：下面是七麦数据关于读者杂志APP的下载量统计，其中华为的下载量占比约为25.69%，而我的华为手机下载量显示34万，则安卓的下载量大约为132.3万，iOS的下载量为29.8万，所以总下载量大约为162万。</p><p>月活：直接查看的艾瑞指数，读者2018年8月大约3万月独立设备数。</p><p><img src="https://ws3.sinaimg.cn/large/006tNbRwly1fwex9nif9wj31kw0bvgoy.jpg" alt=""></p><p><img src="https://ws4.sinaimg.cn/large/006tNbRwly1fwexb9b7nej31kw065405.jpg" alt=""></p><p><img src="https://ws4.sinaimg.cn/large/006tNbRwly1fw99pnhgfcj31fq0riq6w.jpg" alt="读者APP安卓下载量"></p><p><img src="https://ws1.sinaimg.cn/large/006tNbRwly1fwexmg3y8wj31cy0redjm.jpg" alt=""></p><p><img src="https://ws2.sinaimg.cn/large/006tNbRwly1fw99waowjsj31kw0re46h.jpg" alt=""></p><p>无论是读书，还是看杂志都是一种提升自我、丰富生活、充满正能量的事情。但并不是每个人都能坚持去阅读，兴趣使然的用户可能仅是一小部分，怎样使更多的人去养成这种习惯，是产品经理和运营人员都得考虑的一个问题。</p><h2 id="产品规划预测"><a href="#产品规划预测" class="headerlink" title="产品规划预测"></a>产品规划预测</h2><p>只做简单的介绍，抛个砖，不做深入探讨，毕竟没有深入了解过这个行业，不敢妄下结论。但无论什么行业什么产品，完美的解决用户需求、更好的实现企业发展、良好的用户体验与粘性都是产品规划必须要考虑的。曾经有个做产品的师长对我说，产品无小事。的确，做好一个产品你得关注每一个细节，每个节点。</p><h3 id="1、痛点深度挖掘"><a href="#1、痛点深度挖掘" class="headerlink" title="1、痛点深度挖掘"></a>1、痛点深度挖掘</h3><p>（1）更加便捷的获取信息</p><p>（2）更纯粹的还原纸质阅读</p><p>（3）智能化推荐文章</p><p>（4）优化产品交互体验</p><h3 id="2、内容布局拓展"><a href="#2、内容布局拓展" class="headerlink" title="2、内容布局拓展"></a>2、内容布局拓展</h3><p>（1）提高书籍制作的质量</p><p>（2）内容多样化，后面可以增加纸媒、非杂志类出版物等</p><p>（3）UGC内容社区或者PGC内容社区</p><h3 id="3、商业模式拓展"><a href="#3、商业模式拓展" class="headerlink" title="3、商业模式拓展"></a>3、商业模式拓展</h3><p>（1）内容付费</p><p>（2）优质内容打赏</p><p>（3）衍生IP产品</p><h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p><strong>优势（Strengths）</strong>：丰富的杂志内容，这将吸引一大批相应杂志的喜爱者，这一优势将明显降低用户获取成本和提高用户付费转化率。</p><p><strong>劣势（Weaknesses）</strong>：相对于纸质杂志阅读，在体验上还有待提升。对于杂志，更多人可能还是更喜欢纸质阅读。降低产品的转移成本，提高产品使用体验。</p><p><strong>机会（Opportunities）</strong>：综合性的杂志阅读APP基本上是一片空白，虽然有一些杂志出版社也推出了属于自己的APP，但用户群体还是仅限于喜爱该杂志的用户。</p><p><strong>威胁（Threats）</strong>：品牌识别度过小，用户缺乏对APP的信任感。受杂志出版社的版权限制。</p></the>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;我是一个阅读爱好者，在高中时代，读者、意林、青年文摘基本上每期都买。里面的每篇文章都选取的还不错，让人深受启发或感动。所以第一眼看到这类APP我是充满兴趣的，我是带着情怀去体验的。&lt;br&gt;
    
    </summary>
    
      <category term="产品" scheme="http://blog.xieliqun.com/categories/%E4%BA%A7%E5%93%81/"/>
    
    
      <category term="个人笔记" scheme="http://blog.xieliqun.com/tags/%E4%B8%AA%E4%BA%BA%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>关于梦想</title>
    <link href="http://blog.xieliqun.com/2018/07/21/about-dream/"/>
    <id>http://blog.xieliqun.com/2018/07/21/about-dream/</id>
    <published>2018-07-21T09:32:16.000Z</published>
    <updated>2018-10-23T07:34:54.444Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>好久没写文章了，今天其实想谈一下关于梦想的事。<br><a id="more"></a></excerpt></p><the rest="" of="" contents="" |="" 余下全文=""><p><img src="http://cdn.xieliqun.com/WechatIMG225.jpeg" alt="产品相关书籍"></p><p>2017年，在我身上其实发生了很多事。也许没有找到合适且懂你的人，很多事都宁愿埋在自己的心里，也不愿和别人分享。</p><p>2017年前，我一直以为我会是一个很好的前端，会在这条道路上越走越远，成为一个别人认为很厉害的人，这应该是我当初的梦想。可是人生的轨迹似乎总是难以预料。</p><p>2017年3月，我眼睛出现了问题，视网膜脱落，很严重。我请了三个月的病假，在家养病。这段时间，我不能看电脑玩手机，一切需要眼睛做的事情，我都做不了。我除了吃饭，就是躺在床上听有声书、广播新闻等。有一段时间，我真的很沮丧，迷茫。可能已经不能用迷茫来描述了，应该是绝望。</p><p>这段时间让我想了很多，我考虑了最坏的情况，也想了我的未来。我在想，我未来会不会在哪个盲人按摩店，帮客人按摩，或是在街头卖艺乞讨 . . .</p><p>我其实挺感谢老天给我这次经历的，虽然这远远不是我最悲惨的一段时光。养病期间，我一天可能十八小时都在听喜马拉雅，我听一些有声小说，一些心理学，一些历史评书，一些经融财经等等。这段时间让我明白了很多东西，让我再次回到社会的时候学会了怎么淡然处事，怎么管理情绪，怎么去规划自己。</p><p>2017年6月，我再次回到了工作岗位，工作时眼睛还是很不舒服。虽然很不想去面对，但是现实的一些原因，我不得不去工作。我边工作边考虑怎么转行去做一些其他的事情。例如，去做销售，去做一些体力活，回老家开个小店 . . .</p><p>2017年11月，我辞职了，辞去了技术的工作，开始了销售工作。由于没有销售经验，干的很吃力，我不懂得怎么找客户，不会打电话，不知道怎么向客户介绍产品。干了将近两个月，我还是放弃了。我重新考虑自己的职业发展，虽然我不能再回到技术岗位上了，但我还是热爱互联网这个行业。于是我决定，我要从事这个离技术最近的岗位，我要做产品。</p><p>2018年1月，我正式开始了产品相关的工作。其实我发现自己一直有一个产品的梦想，12年大一的时候，学习着怎么去建站，怎么去运营推广网站，16年小程序火的时候，熬夜去看了微信的开发文档，想去做一款小游戏，17年年初的时候，想做一款别致的社交APP，熟人间的匿名社交，当初和朋友同事谈了想法后，好几个人都想和我一起去开发这款应用，我都开始准备写文档做原型了，可是后面因为眼睛的问题便放弃了。</p><p>自从做了产品经理后，发现很多事情并不是自己想的那么简单。以前关于产品经理的理解都停留在“术”的层面，以为懂了一些画原型的工具就以为可以做产品经理了。现在逐渐明白“道”才是产品经理的关键。</p><p>关于产品，我一直认为，一个好的产品，它要满足企业的需求，它能解决用户需求，有黏性，有良好的交互体验。在这半年多时间里，我也一直往这个方向学习，理解并辅助公司的发展战略，学习挖掘用户需求，分析需求，管理需求，优化业务流程，保证良好的交互效果，分析运营数据，提高用户黏性。</p><p>努力去做好一个产品经理，努力去做好一个产品。不求可以改变世界，只想把事情做成，让用户更满意，但求可以为社会创造一点价值。</p></the>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;好久没写文章了，今天其实想谈一下关于梦想的事。&lt;br&gt;
    
    </summary>
    
      <category term="产品" scheme="http://blog.xieliqun.com/categories/%E4%BA%A7%E5%93%81/"/>
    
    
      <category term="职业规划" scheme="http://blog.xieliqun.com/tags/%E8%81%8C%E4%B8%9A%E8%A7%84%E5%88%92/"/>
    
      <category term="梦想" scheme="http://blog.xieliqun.com/tags/%E6%A2%A6%E6%83%B3/"/>
    
  </entry>
  
  <entry>
    <title>React学习资源汇总</title>
    <link href="http://blog.xieliqun.com/2016/11/06/react-study/"/>
    <id>http://blog.xieliqun.com/2016/11/06/react-study/</id>
    <published>2016-11-05T18:44:46.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>React是如今最热门的前端框架，它设计思路独特，性能卓越，逻辑简单，受到了广泛开发者的喜爱。一旦接触她，你就会被她深深吸引。<br>我断断续续的学了将近两个月，今天终于有时间把自己学习React的一些学习资料总结一下。<br><a id="more"></a></excerpt></p><the rest="" of="" contents="" |="" 余下全文=""><p><strong>React 官方</strong><br>官网地址：<a href="http://facebook.github.io/react/" target="_blank" rel="external">http://facebook.github.io/react/</a><br>Github地址：<a href="https://github.com/facebook/react" target="_blank" rel="external">https://github.com/facebook/react</a></p><h2 id="设计思想"><a href="#设计思想" class="headerlink" title="设计思想"></a>设计思想</h2><p>学习React之前，我们先了解一下它的设计思想，它与如今其他热门的前端框架有什么不同？它能为我们的开发解决哪些痛点？</p><p>1、<a href="https://github.com/react-guide/react-basic" target="_blank" rel="external">React 设计思想</a><br>2、<a href="http://www.infoq.com/cn/articles/react-art-of-simplity/" target="_blank" rel="external">React的设计哲学 - 简单之美</a><br>3、<a href="http://www.infoq.com/cn/articles/subversion-front-end-ui-development-framework-react/" target="_blank" rel="external">颠覆式前端UI开发框架:React</a></p><h2 id="初学者入门"><a href="#初学者入门" class="headerlink" title="初学者入门"></a>初学者入门</h2><h3 id="文章"><a href="#文章" class="headerlink" title="文章"></a>文章</h3><p>可以结合一些简单demo去看文章，例如你在看阮一峰的React 入门实例教程时，可结合他写的入门demo，或官方给的demo。当然你也要边学习边自己去写一些简单demo，去改改别人写的一些React 项目。一定要多动手。</p><p>1、<a href="http://www.ruanyifeng.com/blog/2015/03/react.html" target="_blank" rel="external">React 入门实例教程-阮一峰</a>：建议先看demo<br>2、<a href="http://www.cocoachina.com/webapp/20150721/12692.html" target="_blank" rel="external">一看就懂的ReactJs入门教程（精华版）</a><br>3、<a href="http://www.runoob.com/react/react-tutorial.html" target="_blank" rel="external">React 教程-菜鸟教程</a>：安装那节好像有点错<br>4、<a href="http://blog.csdn.net/iambinger/article/details/51803606" target="_blank" rel="external">React 入门，5个常用DEMO展示</a><br>5、<a href="http://www.360doc.com/content/16/0129/07/13518188_531384175.shtml" target="_blank" rel="external">如何学习React</a><br>6、<a href="https://github.com/theJian/build-a-hn-front-page" target="_blank" rel="external">给新手的 React&amp;Webpack 上手教程</a><br>7、<a href="https://zhuanlan.zhihu.com/p/19896745?columnSlug=FrontendMagazine" target="_blank" rel="external">ReactJS 傻瓜教程</a><br>8、<a href="http://guodavid.tk/2016/08/29/React-Message-board/" target="_blank" rel="external">React 最简单的入门应用项目</a></p><h3 id="入门-demo"><a href="#入门-demo" class="headerlink" title="入门 demo"></a>入门 demo</h3><p>1、<a href="https://github.com/facebook/react/tree/master/examples" target="_blank" rel="external">官方入门 demo</a>：可结合官方的入门文档<br>2、<a href="https://github.com/ruanyf/react-demos" target="_blank" rel="external">入门 demo-阮一峰</a>：结合入门文章<br>3、<a href="https://github.com/tsrot/react-zhihu" target="_blank" rel="external">模仿知乎界面的一个简单React demo</a>：结合 <a href="http://www.icoolxue.com/album/show/262" target="_blank" rel="external">ReactJS中文基础视频教程-爱酷</a></p><h3 id="入门视频教程"><a href="#入门视频教程" class="headerlink" title="入门视频教程"></a>入门视频教程</h3><p>一定要边看边写，不要囫囵吞枣的看一遍就好了。</p><p>1、<a href="http://www.imooc.com/learn/504" target="_blank" rel="external">React入门-慕课网</a><br>2、<a href="http://www.icoolxue.com/album/show/262" target="_blank" rel="external">ReactJS中文基础视频教程-爱酷</a><br>3、<a href="http://react-china.org/t/reactjs/584" target="_blank" rel="external">ReactJS中文视频教程</a><br>4、<a href="http://www.hubwiz.com/course/552762019964049d1872fc88/?ch=alloyteam" target="_blank" rel="external">React教程- 汇智网</a></p><h3 id="入门实战视频"><a href="#入门实战视频" class="headerlink" title="入门实战视频"></a>入门实战视频</h3><p>了解React开发流程，作者的编码思路，写作规范。</p><p>1、<a href="http://www.imooc.com/learn/507" target="_blank" rel="external">React实战–打造画廊应用（上）</a><br>2、<a href="http://www.imooc.com/learn/652" target="_blank" rel="external">React实战–打造画廊应用（下）</a><br>3、<a href="http://zexeo.com/course/56753a22b2b8de861c0d281a" target="_blank" rel="external">ReactJS中文基础视频教程</a><br>4、<a href="http://zexeo.com/course/5672c2bd52b470c02bc28b6c" target="_blank" rel="external">构建实时聊天应用</a></p><h2 id="开发文档"><a href="#开发文档" class="headerlink" title="开发文档"></a>开发文档</h2><p>开发其实不用详细去全看，在你做项目时，遇到不懂的就去查看一下文档，我认为这样效率更高一点。当然你有时间也可以一步步去阅读。</p><p>1、<a href="https://facebook.github.io/react/docs/hello-world.html" target="_blank" rel="external">官方文档</a><br>2、<a href="http://reactjs.cn/react/docs/getting-started-zh-CN.html" target="_blank" rel="external">中文文档</a></p><h2 id="学习网站"><a href="#学习网站" class="headerlink" title="学习网站"></a>学习网站</h2><p>在学习中我们会遇到 一些问题，可以去社区或一些网站寻找答案，下面推荐一些好的React 社区和学习网站。</p><p>1、<a href="http://react-china.org/" target="_blank" rel="external">React中文社区</a><br>2、<a href="http://nav.react-china.org/" target="_blank" rel="external">React 中文索引</a><br>2、<a href="http://lib.csdn.net/base/react" target="_blank" rel="external">React知识库</a><br>3、<a href="https://codepicnic.com/posts/a-quick-start-to-react-0777d5c17d4066b82ab86dff8a46af6f" target="_blank" rel="external">A quick start to React</a><br>4、<a href="http://stackoverflow.com/questions/tagged/reactjs" target="_blank" rel="external">stack overflow</a><br>5、<a href="https://www.zhihu.com/topic/20013159/hot" target="_blank" rel="external">知乎 React 话题</a><br>6、<a href="https://segmentfault.com/t/react.js" target="_blank" rel="external">segmentfault React 话题</a></p><h2 id="React技术栈"><a href="#React技术栈" class="headerlink" title="React技术栈"></a>React技术栈</h2><p>React是一款非常优秀的前端框架，你要发挥它完全的性能，你就要结合其他一些技术，例如webpack、redux、react-router等。</p><p>1、<a href="http://www.ruanyifeng.com/blog/2016/09/react-technology-stack.html" target="_blank" rel="external">React 技术栈系列教程</a><br>2、<a href="https://github.com/my-fe/wiki/issues/1" target="_blank" rel="external">百度母婴技术团队—基于Reactjs实现webapp</a><br>3、<a href="https://www.sitepoint.com/building-a-react-universal-blog-app-a-step-by-step-guide/" target="_blank" rel="external">Building a React Universal Blog App</a><br>4、<a href="http://react-china.org/t/react-immutable-js/3770" target="_blank" rel="external">React为啥非得使用immutable.js</a><br>5、<a href="https://blog.coding.net/blog/React-Server-Side-Rendering-for-SPA-SEO" target="_blank" rel="external">React Server Side Rendering 解决 SPA 应用的 SEO 问题</a></p><p>6、<a href="http://webpack.github.io/docs/" target="_blank" rel="external">webpack官方文档</a><br>7、<a href="http://webpackdoc.com/" target="_blank" rel="external">Webpack 中文指南</a><br>8、<a href="http://www.w2bc.com/Article/50764" target="_blank" rel="external">webpack一小时快速入门</a><br>9、<a href="http://www.jianshu.com/p/c8a805145046" target="_blank" rel="external">使用webpack轻松构建你的第一个react开发框架</a></p><p>10、<a href="https://github.com/ReactTraining/react-router" target="_blank" rel="external">react-router</a><br>11、<a href="https://react-guide.github.io/react-router-cn/" target="_blank" rel="external">React Router 中文文档</a><br>12、<a href="https://github.com/reactjs/react-router-tutorial/tree/master/lessons" target="_blank" rel="external">React Router 官方 demo</a></p><p>13、<a href="http://redux.js.org/" target="_blank" rel="external">Redux官网</a><br>14、<a href="http://cn.redux.js.org/index.html" target="_blank" rel="external">Redux 中文文档</a><br>15、<a href="https://github.com/reactjs/redux/tree/master/examples" target="_blank" rel="external">Redux 官方 demo</a><br>16、<a href="https://github.com/kenberkeley/redux-simple-tutorial" target="_blank" rel="external">Redux 莞式教程</a><br>17、<a href="https://egghead.io/courses/getting-started-with-redux" target="_blank" rel="external">Redux 视频教程</a><br>18、<a href="http://qiutc.me/post/redux-%E5%A4%A7%E6%B3%95%E5%A5%BD-%E2%80%94%E2%80%94-%E5%85%A5%E9%97%A8%E5%AE%9E%E4%BE%8B-TodoList.html" target="_blank" rel="external">redux 大法好</a><br>19、<a href="https://zhuanlan.zhihu.com/p/19900243?columnSlug=FrontendMagazine" target="_blank" rel="external">Flux 傻瓜教程</a><br>20、<a href="http://foio.github.io/react-redux-performance-boost/" target="_blank" rel="external">react+redux渲染性能优化原理</a></p><h2 id="React-开源项目"><a href="#React-开源项目" class="headerlink" title="React 开源项目"></a>React 开源项目</h2><p>介绍一些国内外比较好的 React 开源项目。</p><p>国内：<br>1、<a href="https://github.com/react-component" target="_blank" rel="external">阿里的 React 组件库</a><br>2、<a href="https://github.com/ant-design/ant-design" target="_blank" rel="external">Ant Design</a><br>3、<a href="https://github.com/tsrot/react-demo" target="_blank" rel="external">简易留言板</a><br>4、<a href="https://github.com/tsrot/react-zhihu" target="_blank" rel="external">react-zhihu</a><br>5、<a href="https://github.com/cjohansen/react-sweeper" target="_blank" rel="external">React的扫雷游戏</a><br>6、<a href="https://github.com/redsx/CR" target="_blank" rel="external">在线聊天室</a><br>7、<a href="https://github.com/JasonBai007/reactSPA" target="_blank" rel="external">使用React技术栈开发SPA</a><br>8、<a href="https://github.com/NumerHero/kuolun" target="_blank" rel="external">阔论留言评论</a><br>9、<a href="https://github.com/lzxb/react-cnode" target="_blank" rel="external">React版cnode社区</a></p><p>国外：<br>1、<a href="https://github.com/relax/relax" target="_blank" rel="external">Relax</a><br>2、<a href="https://github.com/andrewngu/sound-redux/" target="_blank" rel="external">SoundRedux</a><br>3、<a href="https://github.com/gatsbyjs/gatsby" target="_blank" rel="external">Gatsby</a><br>4、<a href="https://github.com/gpbl/isomorphic500" target="_blank" rel="external">isomorphic500</a><br>5、<a href="https://github.com/ianobermiller/nuclearmail" target="_blank" rel="external">NuclearMail</a><br>6、<a href="https://github.com/Automattic/Picard" target="_blank" rel="external">Picard</a><br>7、<a href="https://github.com/casesandberg/react-color" target="_blank" rel="external">React Color</a><br>8、<a href="https://github.com/getsentry/sentry/" target="_blank" rel="external">Sentry</a><br>9、<a href="https://github.com/insin/react-hn" target="_blank" rel="external">react-hn</a><br>10、<a href="https://github.com/khan/perseus" target="_blank" rel="external">Perseus</a></p></the>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;React是如今最热门的前端框架，它设计思路独特，性能卓越，逻辑简单，受到了广泛开发者的喜爱。一旦接触她，你就会被她深深吸引。&lt;br&gt;我断断续续的学了将近两个月，今天终于有时间把自己学习React的一些学习资料总结一下。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript框架" scheme="http://blog.xieliqun.com/categories/JavaScript%E6%A1%86%E6%9E%B6/"/>
    
    
      <category term="React" scheme="http://blog.xieliqun.com/tags/React/"/>
    
  </entry>
  
  <entry>
    <title>模仿知乎界面的一个简单React demo</title>
    <link href="http://blog.xieliqun.com/2016/11/05/react-zhihu/"/>
    <id>http://blog.xieliqun.com/2016/11/05/react-zhihu/</id>
    <published>2016-11-04T17:13:44.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>这是一个模仿知乎界面的简单React demo。这个React demo能让你从零开始学习React，并逐渐掌握React。它包括了一个项目从零到项目完成的整个过程。<br><a id="more"></a></excerpt></p><the rest="" of="" contents="" |="" 余下全文=""><p>项目地址：<a href="https://github.com/tsrot/react-zhihu" target="_blank" rel="external">https://github.com/tsrot/react-zhihu</a><br>项目预览：<a href="http://blog.xieliqun.com/react-zhihu/">http://blog.xieliqun.com/react-zhihu/</a></p><p><strong>项目运行</strong><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">$ git clone https:<span class="comment">//github.com/tsrot/react-zhihu.git</span></div><div class="line">$ cd react-zhihu</div><div class="line"></div><div class="line">$ npm install</div><div class="line"></div><div class="line">$ bower install</div><div class="line"></div><div class="line">$ gulp server   <span class="comment">//用浏览器打开 localhost:5000</span></div></pre></td></tr></table></figure></p><h2 id="搭建开发环境"><a href="#搭建开发环境" class="headerlink" title="搭建开发环境"></a>搭建开发环境</h2><h3 id="初始化npm-bower"><a href="#初始化npm-bower" class="headerlink" title="初始化npm bower"></a>初始化npm bower</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">npm init  <span class="comment">//一直enter，默认就好</span></div><div class="line"></div><div class="line">bower init <span class="comment">//同上</span></div></pre></td></tr></table></figure><h3 id="安装必要的开发工具包"><a href="#安装必要的开发工具包" class="headerlink" title="安装必要的开发工具包"></a>安装必要的开发工具包</h3><ul><li>gulp ：基于流的自动化构建工具</li><li>gulp-browserify ：前端模块及依赖管理</li><li>gulp-concat ：文件合并插件</li><li>gulp-react ：JSX语法转化工具</li><li>gulp-connect ：构建本地开发Web服务器</li><li>lodash ：一个具有一致接口、模块化、高性能等特性的 JavaScript 工具库</li><li>reactify ：React 编译器</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install gulp gulp-browserify gulp-concat gulp-react gulp-connect lodash reactify --save-dev</div></pre></td></tr></table></figure><h3 id="安装生产环境依赖包"><a href="#安装生产环境依赖包" class="headerlink" title="安装生产环境依赖包"></a>安装生产环境依赖包</h3><ul><li>react ：主要框架</li><li>react-dom ：React的DOM操作类</li><li>bootstrap ：bootstrap样式</li></ul><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">npm install --save react react-dom</div><div class="line"></div><div class="line">bower install --save bootstrap</div></pre></td></tr></table></figure><h3 id="写入gulp配置文件gulpfile-js"><a href="#写入gulp配置文件gulpfile-js" class="headerlink" title="写入gulp配置文件gulpfile.js"></a>写入gulp配置文件gulpfile.js</h3><p>你可以在npm的网站上找到相应插件的gulp配置写法。我配置的<a href="https://github.com/tsrot/" target="_blank" rel="external">gulpfile.js</a></p><h2 id="开发"><a href="#开发" class="headerlink" title="开发"></a>开发</h2><ul><li>切分相应的模块</li><li>分清UI组件和容器组件</li><li>学会如何在组件之间通信</li><li>注意写作规范和开发细节</li></ul><h2 id="部署生产"><a href="#部署生产" class="headerlink" title="部署生产"></a>部署生产</h2><p>请切换分支到 product 分支</p><h3 id="修改gulpfile文件"><a href="#修改gulpfile文件" class="headerlink" title="修改gulpfile文件"></a>修改gulpfile文件</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//添加copy任务</span></div><div class="line">gulp.task(<span class="string">'copy'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    gulp.src(<span class="string">'./app/css/*'</span>)</div><div class="line">    .pipe(gulp.dest(<span class="string">'./dist/css'</span>));</div><div class="line"></div><div class="line">    gulp.src(<span class="string">'./bower_components/**/*'</span>)</div><div class="line">    .pipe(gulp.dest(<span class="string">'./dist/libs'</span>));</div><div class="line"></div><div class="line">    gulp.src(<span class="string">'./*.html'</span>)</div><div class="line">    .pipe(gulp.dest(<span class="string">'./dist'</span>));</div><div class="line">&#125;);</div><div class="line"></div><div class="line"><span class="comment">//生产服务器</span></div><div class="line">gulp.task(<span class="string">'connect-pro'</span>,<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    connect.server(&#123;</div><div class="line">        root:<span class="string">'./dist'</span>,</div><div class="line">        port:port,</div><div class="line">        livereload:<span class="literal">true</span>,</div><div class="line">    &#125;)</div><div class="line">&#125;);</div><div class="line"></div><div class="line"><span class="comment">//添加build任务</span></div><div class="line">gulp.task(<span class="string">'build'</span>,[<span class="string">'browserify'</span>,<span class="string">'copy'</span>]);</div><div class="line"></div><div class="line"><span class="comment">//添加启动生产服务器任务</span></div><div class="line">gulp.task(<span class="string">'server-pro'</span>,[<span class="string">'build'</span>,<span class="string">'connect-pro'</span>,<span class="string">'watch'</span>]);</div></pre></td></tr></table></figure><h3 id="修改index-html引用目录"><a href="#修改index-html引用目录" class="headerlink" title="修改index.html引用目录"></a>修改index.html引用目录</h3><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">&lt;link rel=<span class="string">"stylesheet"</span> href=<span class="string">"./libs/bootstrap/dist/css/bootstrap.css"</span>&gt;</div><div class="line">&lt;link rel=<span class="string">"stylesheet"</span> href=<span class="string">"./css/index.css"</span>&gt;</div><div class="line"></div><div class="line">&lt;script src=<span class="string">"./js/main.js"</span>&gt;&lt;/script&gt;</div></pre></td></tr></table></figure><h3 id="使用gulp-gh-pages部署到github-pages"><a href="#使用gulp-gh-pages部署到github-pages" class="headerlink" title="使用gulp-gh-pages部署到github pages"></a>使用gulp-gh-pages部署到github pages</h3><p>下载gulp-gh-pages插件<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install --save-dev gulp-gh-pages</div></pre></td></tr></table></figure></p><p>在gulpfile文件中添加配置gulp-gh-pages代码<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> ghPages = <span class="built_in">require</span>(<span class="string">'gulp-gh-pages'</span>);</div><div class="line"></div><div class="line">gulp.task(<span class="string">'deploy'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line">  <span class="keyword">return</span> gulp.src(<span class="string">'./dist/**/*'</span>)</div><div class="line">    .pipe(ghPages());</div><div class="line">&#125;);</div></pre></td></tr></table></figure></p><h2 id="后续"><a href="#后续" class="headerlink" title="后续"></a>后续</h2><p>将在分支中更新使用下列技术的版本</p><ul><li>webpack</li><li>webpack + redux</li><li>webkack + redux + react-router</li></ul></the>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;这是一个模仿知乎界面的简单React demo。这个React demo能让你从零开始学习React，并逐渐掌握React。它包括了一个项目从零到项目完成的整个过程。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript框架" scheme="http://blog.xieliqun.com/categories/JavaScript%E6%A1%86%E6%9E%B6/"/>
    
    
      <category term="React" scheme="http://blog.xieliqun.com/tags/React/"/>
    
  </entry>
  
  <entry>
    <title>深入了解JavaScript，优化作用域链（2）</title>
    <link href="http://blog.xieliqun.com/2016/10/06/scope-chain-2/"/>
    <id>http://blog.xieliqun.com/2016/10/06/scope-chain-2/</id>
    <published>2016-10-06T04:58:03.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>作为一个良好的开发者必需考虑程序的运行性能，作用域链的层级关系是JavaScript性能优化的一个重要部分。因为这关系到变量在内存里的读写速度。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><h3 id="尽量使用局部变量"><a href="#尽量使用局部变量" class="headerlink" title="尽量使用局部变量"></a>尽量使用局部变量</h3><p>从作用域链的结构可以看出，在执行上下文的作用域链中，标识符所在的位置越深，读写速度就会越慢。</p><p>全局变量总是存在于执行上下文作用域链的最末端，因此在标识符解析的时候，查找全局变量是最慢的，并且全局变量将常驻内存直到程序退出，而局部变量会在函数运行完直接销毁。所以，在编写代码的时候应尽量少使用全局变量，尽可能使用局部变量。</p><p>一个好的经验法则是：如果一个跨作用域的对象被引用了一次以上，则先把它存储到局部变量里再使用。例如：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">toggle</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">if</span>(<span class="built_in">document</span>.getElementById(<span class="string">'btn'</span>).className == <span class="string">'active'</span>)&#123;</div><div class="line"><span class="built_in">document</span>.getElementById(<span class="string">'btn'</span>).className = <span class="string">''</span>;</div><div class="line"><span class="comment">//do someThing</span></div><div class="line">&#125;<span class="keyword">else</span>&#123;</div><div class="line"><span class="built_in">document</span>.getElementById(<span class="string">'btn'</span>).className = <span class="string">'active'</span>;</div><div class="line"><span class="comment">//do someThing</span></div><div class="line">&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p><p>以上代码中<code>document.getElementById(&#39;btn&#39;).className</code>被引用了三次，查找该变量必须遍历整个作用域链，直到最后在全局对象中才能找到<code>document</code>，然后再去找它的方法和属性，这样严重的影响了程序性能。我们可以改为：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">toggle</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> btnClass = <span class="built_in">document</span>.getElementById(<span class="string">'btn'</span>).className;</div><div class="line"><span class="keyword">if</span>(btnClass == <span class="string">'active'</span>)&#123;</div><div class="line">btnClass = <span class="string">''</span>;</div><div class="line"><span class="comment">//do someThing</span></div><div class="line">&#125;<span class="keyword">else</span>&#123;</div><div class="line">btnClass = <span class="string">'active'</span>;</div><div class="line"><span class="comment">//do someThing</span></div><div class="line">&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p><h3 id="尽量不要改变作用域链"><a href="#尽量不要改变作用域链" class="headerlink" title="尽量不要改变作用域链"></a>尽量不要改变作用域链</h3><p>函数每次执行时对应的执行上下文都是独一无二的，所以多次调用同一个函数就会导致创建多个执行上下文，当函数执行完毕，执行上下文会被销毁。每一个执行上下文都和一个作用域链关联。一般情况下，在执行上下文运行的过程中，其作用域链只会被 with 语句和 catch 语句影响。</p><p>with语句是对象的快捷应用方式，用来避免书写重复代码。例如：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> o = &#123;<span class="attr">href</span>:<span class="string">"github.com"</span>&#125;;</div><div class="line"><span class="keyword">var</span> href = <span class="string">"blog.xieliqun.com"</span>;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">buildUrl</span>(<span class="params"></span>)</span>&#123;</div><div class="line">     <span class="keyword">var</span> q = <span class="string">"?name=tsrot"</span>;</div><div class="line">     <span class="keyword">with</span>(o)&#123;</div><div class="line">          <span class="keyword">var</span> url = href+q;</div><div class="line">     &#125;</div><div class="line">     <span class="keyword">return</span> url;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> result = buildUrl();</div><div class="line">alert(result);  <span class="comment">//github.com?name=tsrot</span></div><div class="line">alert(href);    <span class="comment">//blog.xieliqun.com</span></div></pre></td></tr></table></figure></p><p>第一个alert使用的o对象里的href，所以弹出github.com?name=tsrot，第二个alert使用的就是全局的href。</p><p>当代码运行到with语句时，运行期上下文的作用域链临时被改变了。一个新的可变对象被创建，它包含了参数指定的对象的所有属性。这个对象将被推入作用域链的头部，这意味着函数的所有局部变量现在处于第二个作用域链对象中，因此访问代价更高了。此时的作用域链为：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"></div><div class="line">scope -&gt; with.AO -&gt; with.VO -&gt; buildUrl.AO -&gt; Global Object</div><div class="line"></div><div class="line">with.AO = &#123;</div><div class="line">url : undefined</div><div class="line">&#125;</div><div class="line"></div><div class="line">with.VO = &#123;</div><div class="line">href : &quot;github.com&quot;</div><div class="line">&#125;</div><div class="line"></div><div class="line">buildUrl.AO = &#123;</div><div class="line">q : &quot;?name=tsrot&quot;</div><div class="line">&#125;</div><div class="line"></div><div class="line">Global Object = &#123;</div><div class="line">o : &#123;href:&quot;github.com&quot;&#125;,</div><div class="line">href : &quot;blog.xieliqun.com&quot;,</div><div class="line">buildUrl : &lt;reference to function&gt;,</div><div class="line">result : undefined</div><div class="line">&#125;</div></pre></td></tr></table></figure></p><p>另外一个会改变作用域链的是try-catch语句中的catch语句。当try代码块中发生错误时，执行过程会跳转到catch语句，然后把异常对象推入一个可变对象并置于作用域的头部。在catch代码块内部，函数的所有局部变量将会被放在第二个作用域链对象中。</p><h3 id="闭包问题"><a href="#闭包问题" class="headerlink" title="闭包问题"></a>闭包问题</h3><p>一个函数只要内部函数未销毁（内部函数存在被调用的可能），这个函数就不会销毁，将一直存在于内存中，只有所有内部函数都销毁了，并所有的业务代码都已执行完，这个函数才会被释放。我们看看最常见的闭包问题：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">show</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> li = <span class="built_in">document</span>.getElementsByTagName(<span class="string">'li'</span>);</div><div class="line"><span class="keyword">var</span> length = li.length;</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;length;i++)&#123;</div><div class="line">li[i].onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(i);</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">show();</div></pre></td></tr></table></figure></p><p>当点击li标签时，弹出的一直都是length的大小。这是一个比较经典的错误。为什么会这样呢？</p><p>由于show的内部函数（click事件处理程序时刻有调用可能），所以show的作用域链不能被销毁（只能页面卸载是销毁），i的值一直保持for循环执行完后的length值，此时的click的函数只是进行了声明而未运行，当click触发的时候，函数才开始执行，这个时候i的值已经是length了。所以每次触发onclick的时候才会alert length。我们进行改一下：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">show</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> li = <span class="built_in">document</span>.getElementsByTagName(<span class="string">'li'</span>);</div><div class="line"><span class="keyword">var</span> length = li.length;</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;length;i++)&#123;</div><div class="line">(<span class="function"><span class="keyword">function</span>(<span class="params">n</span>)</span>&#123;</div><div class="line">li[n].onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(n);</div><div class="line">&#125;</div><div class="line">&#125;)(i)</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">show();</div></pre></td></tr></table></figure></p><p>为什么这样就行了呢，这时候onclick引用的变量变成了n，而由于立即执行函数的原因，每个onclick函数在作用域链中分别保持着对应的n（0~length-1），这时候就可以了。</p><p>闭包会使子函数保持其作用域链的所有变量及函数与内存中，内存消耗很大，在使用的时候尽量销毁父函数不再使用的变量。你经常访问一些范围之外的标识符，每次访问都将导致一些性能损失。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;作为一个良好的开发者必需考虑程序的运行性能，作用域链的层级关系是JavaScript性能优化的一个重要部分。因为这关系到变量在内存里的读写速度。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="Scope chain" scheme="http://blog.xieliqun.com/tags/Scope-chain/"/>
    
      <category term="性能优化" scheme="http://blog.xieliqun.com/tags/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/"/>
    
  </entry>
  
  <entry>
    <title>深入了解JavaScript，从作用域链开始（1）</title>
    <link href="http://blog.xieliqun.com/2016/10/06/scope-chain/"/>
    <id>http://blog.xieliqun.com/2016/10/06/scope-chain/</id>
    <published>2016-10-05T19:16:45.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>作用域是每种计算机语言最重要的基础之一，当然它也是JavaScript最重要的概念之一。要想真正的深入了解JavaScript，了解JavaScript的作用域链非常必要。现在让我们深入了解JavaScript作用域和作用域链的工作原理。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><h3 id="JavaScript的作用域是什么"><a href="#JavaScript的作用域是什么" class="headerlink" title="JavaScript的作用域是什么"></a>JavaScript的作用域是什么</h3><p>作用域，在维基百科上解释是：在电脑程序设计中，作用域（scope，或译作有效范围）是名字（name）与实体（entity）的绑定（binding）保持有效的那部分计算机程序。<br>简单的说，作用域就是变量与函数的可访问范围，即作用域控制着变量与函数的可见性和生命周期。在JavaScript中，变量的作用域有全局作用域和局部作用域两种，局部作用域又称为函数作用域。</p><h4 id="全局作用域"><a href="#全局作用域" class="headerlink" title="全局作用域"></a>全局作用域</h4><p>在代码中任何地方都能访问到的对象拥有全局作用域，一般来说以下几种情形拥有全局作用域：</p><h5 id="（1）程序最外层定义的函数或者变量"><a href="#（1）程序最外层定义的函数或者变量" class="headerlink" title="（1）程序最外层定义的函数或者变量"></a>（1）程序最外层定义的函数或者变量</h5><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> a = <span class="string">"tsrot"</span>;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(a);</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">hello();</div><div class="line">&#125;</div><div class="line"></div><div class="line">alert(a);     <span class="comment">//能访问到tsrot</span></div><div class="line">hello();      <span class="comment">//能访问到tsrot</span></div><div class="line">sayHello();   <span class="comment">//能访问到hello函数，然后也能访问到tsrot</span></div></pre></td></tr></table></figure><h5 id="（2）所有末定义直接赋值的变量（不推荐）"><a href="#（2）所有末定义直接赋值的变量（不推荐）" class="headerlink" title="（2）所有末定义直接赋值的变量（不推荐）"></a>（2）所有末定义直接赋值的变量（不推荐）</h5><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">a = <span class="string">"tsrot"</span>;</div><div class="line"><span class="keyword">var</span> b = <span class="string">"hello tsrot"</span>;</div><div class="line">&#125;</div><div class="line"></div><div class="line">alert(a);  <span class="comment">//能访问到tsrot</span></div><div class="line">alert(b);  <span class="comment">//error 不能访问</span></div></pre></td></tr></table></figure><h5 id="（3）所有window对象的属性和方法"><a href="#（3）所有window对象的属性和方法" class="headerlink" title="（3）所有window对象的属性和方法"></a>（3）所有window对象的属性和方法</h5><p>一般情况下，window对象的内置属性都拥有全局作用域，例如window.name、window.location、window.top等等。</p><h4 id="局部作用域（函数作用域）"><a href="#局部作用域（函数作用域）" class="headerlink" title="局部作用域（函数作用域）"></a>局部作用域（函数作用域）</h4><p>局部作用域在函数内创建，在函数内可访问，函数外不可访问。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> a = <span class="string">"tsrot"</span>;</div><div class="line">alert(a);</div><div class="line">&#125;</div><div class="line"></div><div class="line">hello(); <span class="comment">//函数内可访问到tsrot</span></div><div class="line">alert(a); <span class="comment">//error not defined</span></div></pre></td></tr></table></figure></p><h3 id="作用域链是什么"><a href="#作用域链是什么" class="headerlink" title="作用域链是什么"></a>作用域链是什么</h3><p>了解作用域链之前我们要知道一下几个概念：</p><ul><li>变量和函数的声明</li><li>函数的生命周期</li><li>Activetion Object（AO）、Variable Object（VO）</li></ul><h4 id="变量和函数的声明"><a href="#变量和函数的声明" class="headerlink" title="变量和函数的声明"></a>变量和函数的声明</h4><p>在JavaScript引擎解析JavaScript代码的时候，首先，JavaScript引擎会把变量和函数的声明提前进行预解析，然后再去执行其他代码。</p><p>变量声明：变量的声明只有一种方式，那就是用<code>var</code>关键字声明，直接赋值不是一种声明方式。这仅仅是在全局对象上创建了新的属性（而不是变量）。它们有一下区别：<br>（1）因为它只是一种赋值，所以不会声明提前<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">alert(a); <span class="comment">// undefined</span></div><div class="line">alert(b); <span class="comment">// error "b" is not defined</span></div><div class="line">b = <span class="number">10</span>;</div><div class="line"><span class="keyword">var</span> a = <span class="number">20</span>;</div></pre></td></tr></table></figure></p><p>（2）直接赋值形式是在执行阶段创建<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">alert(a); <span class="comment">// undefined, 这个大家都知道</span></div><div class="line">b = <span class="number">10</span>;</div><div class="line">alert(b); <span class="comment">// 10, 代码执行阶段创建</span></div><div class="line"> </div><div class="line"><span class="keyword">var</span> a = <span class="number">20</span>;</div><div class="line">alert(a); <span class="comment">// 20, 代码执行阶段修改</span></div></pre></td></tr></table></figure></p><p>（3）变量不能删除（delete），属性可以删除<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">a = <span class="number">10</span>;</div><div class="line">alert(<span class="built_in">window</span>.a); <span class="comment">// 10</span></div><div class="line"> </div><div class="line">alert(<span class="keyword">delete</span> a); <span class="comment">// true</span></div><div class="line"> </div><div class="line">alert(<span class="built_in">window</span>.a); <span class="comment">// undefined</span></div><div class="line"> </div><div class="line"><span class="keyword">var</span> b = <span class="number">20</span>;</div><div class="line">alert(<span class="built_in">window</span>.b); <span class="comment">// 20</span></div><div class="line"> </div><div class="line">alert(<span class="keyword">delete</span> b); <span class="comment">// false</span></div><div class="line"> </div><div class="line">alert(<span class="built_in">window</span>.b); <span class="comment">// 仍然为 20，因为变量是不能够删除的。</span></div></pre></td></tr></table></figure></p><p>但是，这里有一个意外情况，就是在“eval”的上下文中，变量是可以删除的：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">eval</span>(<span class="string">'var a = 10;'</span>);</div><div class="line">alert(<span class="built_in">window</span>.a); <span class="comment">// 10</span></div><div class="line"> </div><div class="line">alert(<span class="keyword">delete</span> a); <span class="comment">// true</span></div><div class="line"> </div><div class="line">alert(<span class="built_in">window</span>.a); <span class="comment">// undefined</span></div></pre></td></tr></table></figure></p><p>有些debug工具也是可以删除的，因为它们使用了 eval()方法来执行代码的。</p><p>函数声明：函数的声明有三种方式<br>（1）function name( ){ }直接创建方式<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">a,b</span>)</span>&#123;</div><div class="line"><span class="keyword">return</span> a+b;</div><div class="line">&#125;</div><div class="line"></div><div class="line">add(<span class="number">5</span>,<span class="number">4</span>);</div></pre></td></tr></table></figure></p><p>（2）new Funtion构建函数创建<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> add=<span class="keyword">new</span> <span class="built_in">Function</span>(<span class="string">"a"</span>, <span class="string">"b"</span>, <span class="string">"return a+b;"</span>);</div><div class="line"></div><div class="line">add(<span class="number">4</span>,<span class="number">5</span>);</div></pre></td></tr></table></figure></p><p>（3）给变量赋值匿名函数方法创建<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> add = <span class="function"><span class="keyword">function</span>(<span class="params">a,b</span>)</span>&#123;</div><div class="line"><span class="keyword">return</span> a+b;</div><div class="line">&#125;</div><div class="line"></div><div class="line">add(<span class="number">4</span>,<span class="number">5</span>);</div></pre></td></tr></table></figure></p><p>后面两种方法，在声明前访问时，返回的都是一个undefined的变量。当然，在声明后访问它们都是一个function的函数。</p><p><strong>注意</strong>：如果变量名和函数名声明时相同，函数优先声明。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">alert(x); <span class="comment">// function</span></div><div class="line"></div><div class="line"><span class="keyword">var</span> x = <span class="number">10</span>;</div><div class="line">alert(x); <span class="comment">// 10</span></div><div class="line"> </div><div class="line">x = <span class="number">20</span>;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">x</span>(<span class="params"></span>) </span>&#123;&#125;;</div><div class="line"> </div><div class="line">alert(x); <span class="comment">// 20</span></div></pre></td></tr></table></figure></p><h4 id="函数的生命周期"><a href="#函数的生命周期" class="headerlink" title="函数的生命周期"></a>函数的生命周期</h4><p>函数的的生命周期分为创建和执行两个阶段。</p><p>在函数创建阶段，JS解析引擎进行预解析，会将函数声明提前，同时将该函数放到全局作用域中或当前函数的上一级函数的局部作用域中。</p><p>在函数执行阶段，JS引擎会将当前函数的局部变量和内部函数进行声明提前，然后再执行业务代码，当函数执行完退出时，释放该函数的执行上下文，并注销该函数的局部变量。</p><h4 id="什么是AO、VO"><a href="#什么是AO、VO" class="headerlink" title="什么是AO、VO"></a>什么是AO、VO</h4><p>英文解释：<br>AO：Activetion Object（活动对象）<br>VO：Variable Object（变量对象）</p><p>VO对应的是函数创建阶段，JS解析引擎进行预解析时，所有的变量和函数的声明，统称为Variable Object。该变量与执行上下文相关，知道自己的数据存储在哪里，并且知道如何访问。VO是一个与执行上下文相关的特殊对象，它存储着在上下文中声明的以下内容：</p><ul><li>变量 (var, 变量声明);</li><li>函数声明 (FunctionDeclaration, 缩写为FD);</li><li>函数的形参</li></ul><p>举个例子：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">a,b</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> sum = a + b;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">say</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(sum);</div><div class="line">&#125;</div><div class="line"><span class="keyword">return</span> sum;</div><div class="line">&#125;</div><div class="line"><span class="comment">// sum,say,a,b 组合的对象就是VO，不过该对象的值基本上都是undefined</span></div></pre></td></tr></table></figure></p><p>AO对应的是函数执行阶段，当函数被调用执行时，会建立一个执行上下文，该执行上下文包含了函数所需的所有变量，该变量共同组成了一个新的对象就是Activetion Object。该对象包含了：</p><ul><li>函数的所有局部变量</li><li>函数的所有命名参数</li><li>函数的参数集合</li><li>函数的this指向</li></ul><p>举个例子：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">a,b</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> sum = a + b;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">say</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(sum);</div><div class="line">&#125;</div><div class="line"><span class="keyword">return</span> sum;</div><div class="line">&#125;</div><div class="line"></div><div class="line">add(<span class="number">4</span>,<span class="number">5</span>);</div><div class="line"><span class="comment">//  我用JS对象来表示AO</span></div><div class="line"><span class="comment">//  AO = &#123;</span></div><div class="line"><span class="comment">//    this : window,</span></div><div class="line"><span class="comment">//    arguments : [4,5],</span></div><div class="line"><span class="comment">//    a : 4,</span></div><div class="line"><span class="comment">//    b : 5,</span></div><div class="line"><span class="comment">//    say : &lt;reference to function&gt;,</span></div><div class="line"><span class="comment">//    sum : undefined</span></div><div class="line"><span class="comment">//  &#125;</span></div></pre></td></tr></table></figure></p><h4 id="JavaScript作用域链"><a href="#JavaScript作用域链" class="headerlink" title="JavaScript作用域链"></a>JavaScript作用域链</h4><p>现在我们回到主题，作用域链。</p><p>当代码在一个环境中执行时，会创建变量对象的一个作用域链（scope chain）来保证对执行环境有权访问的变量和函数的有序访问。作用域第一个对象始终是当前执行代码所在环境的变量对象（VO）。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">a,b</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> sum = a + b;</div><div class="line"><span class="keyword">return</span> sum;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p><p>假设函数是在全局作用域中创建的，在函数a创建的时候，它的作用域链填入全局对象,全局对象中有所有全局变量，此时的全局变量就是VO。此时的作用域链就是：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">此时作用域链（Scope Chain）只有一级,就为Global Object</div><div class="line"></div><div class="line">scope(add) -&gt; Global Object(VO)</div><div class="line"></div><div class="line">VO = &#123;</div><div class="line">this : window,</div><div class="line">add : &lt;reference to function&gt;</div><div class="line">&#125;</div></pre></td></tr></table></figure><p>如果是函数执行阶段，那么将其activation object（AO）作为作用域链第一个对象，第二个对象是上级函数的执行上下文AO，下一个对象依次类推。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">add(<span class="number">4</span>,<span class="number">5</span>);</div></pre></td></tr></table></figure></p><p>例如，调用add后的作用域链是：</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line">此时作用域链（Scope Chain）有两级，第一级为AO，然后Global Object（VO）</div><div class="line"></div><div class="line">scope(add) -&gt; AO -&gt; VO</div><div class="line"></div><div class="line">AO = &#123;</div><div class="line">this : window,</div><div class="line">arguments : [4,5],</div><div class="line">a : 4,</div><div class="line">b : 5,</div><div class="line">sum : undefined</div><div class="line">&#125;</div><div class="line"></div><div class="line">VO = &#123;</div><div class="line">this : window,</div><div class="line">add : &lt;reference to function&gt;</div><div class="line">&#125;</div></pre></td></tr></table></figure><p>在函数运行过程中标识符的解析是沿着作用域链一级一级搜索的过程，从第一个对象开始，逐级向后回溯，直到找到同名标识符为止，找到后不再继续遍历，找不到就报错。</p><p>看过上面的内容后，可能还有人不懂，我再通熟易懂的解释一遍，先举个例子：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> x = <span class="number">10</span>;</div><div class="line"> </div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">foo</span>(<span class="params"></span>) </span>&#123;</div><div class="line">    <span class="keyword">var</span> y = <span class="number">20</span>;</div><div class="line"> </div><div class="line">    <span class="function"><span class="keyword">function</span> <span class="title">bar</span>(<span class="params"></span>) </span>&#123;</div><div class="line">        <span class="keyword">var</span> z = <span class="number">30</span>;</div><div class="line"> </div><div class="line">        <span class="built_in">console</span>.log(x + y + z);</div><div class="line">    &#125;;</div><div class="line"> </div><div class="line">    bar()</div><div class="line">&#125;;</div><div class="line"> </div><div class="line">foo();</div></pre></td></tr></table></figure></p><p>上面代码的输出结果为”60″，函数bar可以直接访问”z”，然后通过作用域链访问上层的”x”和”y”。此时的作用域链为：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line">此时作用域链（Scope Chain）有三级，第一级为bar AO，第二级为foo AO,然后Global Object（VO）</div><div class="line"></div><div class="line">scope -&gt; bar.AO -&gt; foo.AO -&gt; Global Object</div><div class="line"></div><div class="line">bar.AO = &#123;</div><div class="line">z : 30,</div><div class="line">__parent__ : foo.AO</div><div class="line">&#125;</div><div class="line"></div><div class="line">foo.AO = &#123;</div><div class="line">y : 20,</div><div class="line">bar : &lt;reference to function&gt;,</div><div class="line">__parent__ : &lt;Global Object&gt;</div><div class="line">&#125;</div><div class="line"></div><div class="line">Global Object = &#123;</div><div class="line">x : 10,</div><div class="line">foo : &lt;reference to function&gt;,</div><div class="line">__parent__ : null</div><div class="line">&#125;</div></pre></td></tr></table></figure></p><p>未完待续。。。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;作用域是每种计算机语言最重要的基础之一，当然它也是JavaScript最重要的概念之一。要想真正的深入了解JavaScript，了解JavaScript的作用域链非常必要。现在让我们深入了解JavaScript作用域和作用域链的工作原理。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="Scope chain" scheme="http://blog.xieliqun.com/tags/Scope-chain/"/>
    
      <category term="作用域" scheme="http://blog.xieliqun.com/tags/%E4%BD%9C%E7%94%A8%E5%9F%9F/"/>
    
  </entry>
  
  <entry>
    <title>Yeoman 中文网</title>
    <link href="http://blog.xieliqun.com/2016/09/21/yeoman-chinese-website/"/>
    <id>http://blog.xieliqun.com/2016/09/21/yeoman-chinese-website/</id>
    <published>2016-09-20T16:51:50.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>如今前端的项目变得越来越庞大，靠人工手动终究不符合现代化技术发展的趋势。作为一名前端开发人员，我们需要更加自动化的coding。由于国内关于Yeoman的技术资料还是比较少，而且比较基础，比较过时，所以前段时间，我把Yeoman官网，翻译成了中文：www.yowebapp.com。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""><br>Yeoman是一个比较好的前端解决方案，它优化了前端开发的工作流，让前端开发人员更加专注业务代码的开发，像什么项目构建、代码校验、项目测试等，这些都交给Yeoman来做。</the></p><p><strong> Yeoman中文 </strong><br>1、中文翻译（可能有些地方翻译的很粗糙）<br>2、提高页面加载速度<br>3、使用 google 字体镜像资源<br>4、优化国内 youtube 视频不能加载</p><p>欢迎访问 <a href="http://www.yowebapp.com" target="_blank" rel="external">Yeoman中文</a>,如有错误欢迎指正。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;如今前端的项目变得越来越庞大，靠人工手动终究不符合现代化技术发展的趋势。作为一名前端开发人员，我们需要更加自动化的coding。由于国内关于Yeoman的技术资料还是比较少，而且比较基础，比较过时，所以前段时间，我把Yeoman官网，翻译成了中文：www.yowebapp.com。&lt;br&gt;
    
    </summary>
    
      <category term="前端自动化" scheme="http://blog.xieliqun.com/categories/%E5%89%8D%E7%AB%AF%E8%87%AA%E5%8A%A8%E5%8C%96/"/>
    
    
      <category term="Yeoman" scheme="http://blog.xieliqun.com/tags/Yeoman/"/>
    
  </entry>
  
  <entry>
    <title>折腾：coding.net IDE node环境的安装</title>
    <link href="http://blog.xieliqun.com/2016/08/27/online-IDE-node-enviroment/"/>
    <id>http://blog.xieliqun.com/2016/08/27/online-IDE-node-enviroment/</id>
    <published>2016-08-27T04:11:24.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>作为一个码农，我们经常会有这样一个痛点：项目出现一个紧急bug，但自己又不在公司，怎办呢？虽然项目可能在git或者svn上，但clone下来安装测试环境也是个麻烦的是啊。于是，我们想到了在线IDE。作为一个前端开发者nodeJS环境是非常重要的，今天花了一个多小时折腾了下<a href="https://ide.coding.net" target="_blank" rel="external">coding.net</a>。虽然coding IDE可以切换nodeJS环境，但是当你需要多种环境的时候就有点必要了。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><h3 id="IDE介绍"><a href="#IDE介绍" class="headerlink" title="IDE介绍"></a>IDE介绍</h3><p>以前我一直在用<a href="https://nitrous.io" target="_blank" rel="external">nitrous.io</a>的在线IDE，它是一个国外的在线IDE，访问有点慢，一旦网络不好就掉线，挺好的地方就是，它每个月有50个小时的免费使用。coding.net相当于是一个国内版的github，也是一个远程的git仓库，它有个在线IDE还挺好用的。有终端命令面板、支持vim和 Emacs的编辑器、在线运行环境、支持git。</p><p>下面进入主题。</p><h3 id="安装nvm"><a href="#安装nvm" class="headerlink" title="安装nvm"></a>安装nvm</h3><p>nvm是nodejs版本管理工具。可以在多个nodejs版本中进行切换，降低了升级nodejs时的成本。</p><p>下载nvm，直接在终端面板把它clone过来就行了。为了不影响项目目录，我们把它clone在项目根目录的同级目录。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ <span class="built_in">cd</span> ..</div><div class="line">-&gt; ~ git <span class="built_in">clone</span> https://github.com/creationix/nvm.git</div></pre></td></tr></table></figure></p><p>接下来，进入nvm目录<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ <span class="built_in">cd</span> nvm</div></pre></td></tr></table></figure></p><p>安装nvm<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ ./install.sh</div></pre></td></tr></table></figure></p><p>安装完后，让系统自动执行它<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ <span class="built_in">source</span> ./nvm.sh</div></pre></td></tr></table></figure></p><p>现在就可以使用nvm命令了，查看一下help<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ nvm -<span class="built_in">help</span></div></pre></td></tr></table></figure></p><h3 id="安装nodeJS"><a href="#安装nodeJS" class="headerlink" title="安装nodeJS"></a>安装nodeJS</h3><p>查看可以安装的nodejs版本，这里将会输出一大堆可供安装的nodejs版本<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ nvm ls-remote</div></pre></td></tr></table></figure></p><p>选择一个进行安装，我安装的是v4.5.0<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ nvm install v4.5.0</div></pre></td></tr></table></figure></p><p>当然你可以安装多个版本，例如我还要安装最新版本，测试一下它的新特性<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ nvm install v6.4.0</div></pre></td></tr></table></figure></p><p>当你想切换回原先稳定版本时，你可以<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ nvm use v4.5.0</div></pre></td></tr></table></figure></p><p>安装完node，你就可以使用node和npm了。你可以安装一些自动化工具啊，一些插件啊什么的。</p><h3 id="一些问题"><a href="#一些问题" class="headerlink" title="一些问题"></a>一些问题</h3><p>1、这些在线IDE虽然挺方便的，但毕竟没有本地的好，还有一些安全和网络限制的问题，另外到后面可能还要收费。</p><p>2、nvm问题，因为coding没有给用户root权限,不能够执行source /root/nvm/nvm.sh，让nvm每次启动项目自动执行。所以你每次在运行node前都必须先执行一下nvm。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">-&gt; ~ <span class="built_in">cd</span> ..</div><div class="line">-&gt; ~ <span class="built_in">cd</span> nvm</div><div class="line">-&gt; ~ <span class="built_in">source</span> ./nvm.sh</div></pre></td></tr></table></figure><h3 id="END"><a href="#END" class="headerlink" title="END"></a>END</h3>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;作为一个码农，我们经常会有这样一个痛点：项目出现一个紧急bug，但自己又不在公司，怎办呢？虽然项目可能在git或者svn上，但clone下来安装测试环境也是个麻烦的是啊。于是，我们想到了在线IDE。作为一个前端开发者nodeJS环境是非常重要的，今天花了一个多小时折腾了下&lt;a href=&quot;https://ide.coding.net&quot; target=&quot;_blank&quot; rel=&quot;external&quot;&gt;coding.net&lt;/a&gt;。虽然coding IDE可以切换nodeJS环境，但是当你需要多种环境的时候就有点必要了。&lt;br&gt;
    
    </summary>
    
      <category term="IDE" scheme="http://blog.xieliqun.com/categories/IDE/"/>
    
    
      <category term="nodeJS" scheme="http://blog.xieliqun.com/tags/nodeJS/"/>
    
      <category term="折腾" scheme="http://blog.xieliqun.com/tags/%E6%8A%98%E8%85%BE/"/>
    
  </entry>
  
  <entry>
    <title>window.name跨域详解</title>
    <link href="http://blog.xieliqun.com/2016/08/26/windowName-cross-domain/"/>
    <id>http://blog.xieliqun.com/2016/08/26/windowName-cross-domain/</id>
    <published>2016-08-25T17:31:00.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>window.name属性的神奇之处在于name 值在不同的页面（甚至不同域名）加载后依旧存在（如果没修改则值不会变化），并且可以支持非常长的 name 值（2MB）。并且window.name很方便。<br><a id="more"></a></excerpt></p><the rest="" of="" contents="" |="" 余下全文=""><h3 id="用法介绍"><a href="#用法介绍" class="headerlink" title="用法介绍"></a>用法介绍</h3><p>name 在浏览器环境中是一个全局/window对象的属性，且当在 frame 中加载新页面（可以是不同域的）时，name 的属性值依旧保持不变（只要不重新赋值）。name属性的值虽然不变，但对它的访问还是受到同域原则，不允许访问。所以我们要把iframe重新定向回原域，这样name的值也没变，并且可以访问了。</p><p>在最顶层，name 属性是不安全的，对于所有后续页面，设置在 name 属性中的任何信息都是可获得的。然而 windowName 模块总是在一个 iframe 中加载资源，并且一旦获取到数据，或者当你在最顶层浏览了一个新页面，这个 iframe 将被销毁，所以其他页面永远访问不到 window.name 属性。</p><h3 id="函数封装"><a href="#函数封装" class="headerlink" title="函数封装"></a>函数封装</h3><p>为了方便以后的使用，我们把window.name进行一下封装。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">proxy</span>(<span class="params">url, func</span>)</span>&#123;</div><div class="line">  <span class="keyword">var</span> isFirst = <span class="literal">true</span>,<span class="comment">//判断url第一次是否加载完</span></div><div class="line">      ifr = <span class="built_in">document</span>.createElement(<span class="string">'iframe'</span>),</div><div class="line">      loadFunc = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">        <span class="keyword">if</span>(isFirst)&#123;</div><div class="line">        <span class="comment">//加载完url后，重新定向回原域</span></div><div class="line">          ifr.contentWindow.location = <span class="string">'about:blank'</span>;</div><div class="line">          isFirst = <span class="literal">false</span>;</div><div class="line">        &#125;<span class="keyword">else</span>&#123;</div><div class="line">        <span class="comment">//iframe回到原域后，获取name的值，执行回调函数，然后销毁iframe</span></div><div class="line">          func(ifr.contentWindow.name);</div><div class="line">          ifr.contentWindow.close();</div><div class="line">          <span class="built_in">document</span>.body.removeChild(ifr);</div><div class="line">          ifr.src = <span class="string">''</span>;</div><div class="line">          ifr = <span class="literal">null</span>;</div><div class="line">        &#125;</div><div class="line">      &#125;;</div><div class="line"></div><div class="line">  ifr.src = url; <span class="comment">//第一次加载url</span></div><div class="line">  ifr.style.display = <span class="string">'none'</span>;</div><div class="line">  <span class="built_in">document</span>.body.appendChild(ifr);</div><div class="line"></div><div class="line">  <span class="comment">//监听iframe是否加载，加载完执行loadFunc</span></div><div class="line">  <span class="keyword">if</span>(ifr.attachEvent)&#123;</div><div class="line">  ifr.attachEvent(<span class="string">'onload'</span>, loadFunc);</div><div class="line">  &#125;<span class="keyword">else</span>&#123;</div><div class="line">  ifr.onload = loadFunc;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure><h3 id="详细案例"><a href="#详细案例" class="headerlink" title="详细案例"></a>详细案例</h3><p>假设我现在在<a href="http://127.0.0.1:8080" target="_blank" rel="external">http://127.0.0.1:8080</a> ，我有一个页面叫做a.html，现在我想获取<a href="http://127.0.0.1:9090" target="_blank" rel="external">http://127.0.0.1:9090</a> 上的b.html的数据。</p><p>a.html<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div></pre></td><td class="code"><pre><div class="line">&lt;!DOCTYPE html&gt;</div><div class="line">&lt;html lang=<span class="string">"en"</span>&gt;</div><div class="line">&lt;head&gt;</div><div class="line">&lt;script&gt;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">proxy</span>(<span class="params">url, func</span>)</span>&#123;</div><div class="line">  <span class="keyword">var</span> isFirst = <span class="literal">true</span>,</div><div class="line">      ifr = <span class="built_in">document</span>.createElement(<span class="string">'iframe'</span>),</div><div class="line">      loadFunc = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">        <span class="keyword">if</span>(isFirst)&#123;</div><div class="line">          ifr.contentWindow.location = <span class="string">'about:blank'</span>;</div><div class="line">          isFirst = <span class="literal">false</span>;</div><div class="line">        &#125;<span class="keyword">else</span>&#123;</div><div class="line">          func(ifr.contentWindow.name);</div><div class="line">          ifr.contentWindow.close();</div><div class="line">          <span class="built_in">document</span>.body.removeChild(ifr);</div><div class="line">          ifr.src = <span class="string">''</span>;</div><div class="line">          ifr = <span class="literal">null</span>;</div><div class="line">        &#125;</div><div class="line">      &#125;;</div><div class="line"></div><div class="line">  ifr.src = url;</div><div class="line">  ifr.style.display = <span class="string">'none'</span>;</div><div class="line">  <span class="built_in">document</span>.body.appendChild(ifr);</div><div class="line"></div><div class="line">  <span class="keyword">if</span>(ifr.attachEvent)&#123;</div><div class="line">  ifr.attachEvent(<span class="string">'onload'</span>, loadFunc);</div><div class="line">  &#125;<span class="keyword">else</span>&#123;</div><div class="line">  ifr.onload = loadFunc;</div><div class="line">  &#125;</div><div class="line"></div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>head&gt;</div><div class="line">&lt;body&gt;</div><div class="line">&lt;script&gt;</div><div class="line">  proxy(<span class="string">'http://127.0.0.1:9090/b.html'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">data</span>)</span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="built_in">JSON</span>.parse(data).name);</div><div class="line">    <span class="built_in">console</span>.log(<span class="built_in">JSON</span>.parse(data).age);</div><div class="line">  &#125;);</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>body&gt;</div><div class="line">&lt;<span class="regexp">/html&gt;</span></div></pre></td></tr></table></figure></p><p>b.html<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line">&lt;!DOCTYPE html&gt;</div><div class="line">&lt;html lang=<span class="string">"en"</span>&gt;</div><div class="line">&lt;head&gt;</div><div class="line">&lt;meta charset=<span class="string">"UTF-8"</span>&gt;</div><div class="line">&lt;title&gt;Document&lt;<span class="regexp">/title&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>head&gt;</div><div class="line">&lt;body&gt;</div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> obj = &#123;</div><div class="line">name:<span class="string">"tsrot"</span>,</div><div class="line">age:<span class="number">24</span></div><div class="line">&#125;;</div><div class="line">    <span class="built_in">window</span>.name = <span class="built_in">JSON</span>.stringify(obj);</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>body&gt;</div><div class="line">&lt;<span class="regexp">/html&gt;</span></div></pre></td></tr></table></figure></p></the>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;window.name属性的神奇之处在于name 值在不同的页面（甚至不同域名）加载后依旧存在（如果没修改则值不会变化），并且可以支持非常长的 name 值（2MB）。并且window.name很方便。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="跨域" scheme="http://blog.xieliqun.com/tags/%E8%B7%A8%E5%9F%9F/"/>
    
      <category term="window.name" scheme="http://blog.xieliqun.com/tags/window-name/"/>
    
  </entry>
  
  <entry>
    <title>html5 API postMessage跨域详解</title>
    <link href="http://blog.xieliqun.com/2016/08/25/postMessage-cross-domain/"/>
    <id>http://blog.xieliqun.com/2016/08/25/postMessage-cross-domain/</id>
    <published>2016-08-25T05:11:32.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>window.postMessage(message,targetOrigin) 方法是html5新引进的特性，可以使用它来向其它的window对象发送消息，无论这个window对象是属于同源或不同源，目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><h3 id="准备"><a href="#准备" class="headerlink" title="准备"></a>准备</h3><p>跨域是什么，我就不详细解释了，我相信你在看这篇文章前就已经了解的差不多了。现在我就直接进入实战阶段。</p><p><strong>两个服务器</strong>：</p><ul><li><a href="http://127.0.0.1:8080" target="_blank" rel="external">http://127.0.0.1:8080</a></li><li><a href="http://127.0.0.1:9090" target="_blank" rel="external">http://127.0.0.1:9090</a></li></ul><p>先建立两个不同域的测试环境。我用http-server（一个node服务器插件）建立了两个不同端口的本地服务器。</p><p><strong>两个页面</strong>：</p><ul><li>a.html</li><li>b.html</li></ul><p>在<a href="http://127.0.0.1:8080" target="_blank" rel="external">http://127.0.0.1:8080</a> 中新建a.html，在<a href="http://127.0.0.1:9090" target="_blank" rel="external">http://127.0.0.1:9090</a> 中新建b.html。</p><h3 id="数据发送"><a href="#数据发送" class="headerlink" title="数据发送"></a>数据发送</h3><p>postMessage允许用户在两个窗口或frame之间传递数据，无论这个window对象是不是同源都能发送。</p><p>首先我们先在a.html中建立一个iframe。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">&lt;iframe src=<span class="string">"http://127.0.0.1:9090/b.html"</span> name=<span class="string">"postIframe"</span> onload=<span class="string">"messageLoad()"</span>&gt;&lt;/iframe&gt;</div></pre></td></tr></table></figure><p>当iframe加载完时，发送数据</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">messageLoad</span>(<span class="params"></span>)</span>&#123;</div><div class="line"></div><div class="line"><span class="keyword">var</span> url = <span class="string">"http://127.0.0.1:9090"</span>;</div><div class="line"></div><div class="line"><span class="built_in">window</span>.postIframe.postMessage(<span class="string">"给我tsort的信息"</span>,url);</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure><p>postMessage包括两个参数data和url，data为发送的数据，url为发送地址。</p><h3 id="数据接收"><a href="#数据接收" class="headerlink" title="数据接收"></a>数据接收</h3><p>html5新增了onmessage事件，它和onclick之类用法差不多。当窗口或frame接收到postMessage发送过来的数据时，将触发onmessage事件。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">window</span>.onmessage = <span class="function"><span class="keyword">function</span>(<span class="params">e</span>)</span>&#123;</div><div class="line">e = e || event;</div><div class="line">alert(e.data);</div><div class="line">&#125;</div></pre></td></tr></table></figure><p>该事件接收一个event对象，这个对象有三个属性，分别为source，origin，data。</p><p><strong>source</strong>： 消息源，消息的发送窗口/iframe。<br><strong>origin</strong>：消息源的URI(可能包含协议、域名和端口)，用来验证数据源。<br><strong>data</strong>：发送方发送给接收方的数据。</p><h3 id="完整例子"><a href="#完整例子" class="headerlink" title="完整例子"></a>完整例子</h3><p>这个例子是这样的，a页面中有一个iframe，这个iframe是另一个域的b页面。当b加载完的时候，让它去给iframe里的页面发送一条信息。然后里面的页面立即回复已经接收到信息，然后再等三秒，回复a所请求的数据。</p><p>a.html</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div></pre></td><td class="code"><pre><div class="line">&lt;!DOCTYPE html&gt;</div><div class="line">&lt;html lang=<span class="string">"en"</span>&gt;</div><div class="line">&lt;head&gt;</div><div class="line">&lt;meta charset=<span class="string">"UTF-8"</span>&gt;</div><div class="line">&lt;title&gt;Document&lt;<span class="regexp">/title&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>head&gt;</div><div class="line">&lt;body&gt;</div><div class="line"></div><div class="line">&lt;iframe src=<span class="string">"http://127.0.0.1:9090/b.html"</span> name=<span class="string">"postIframe"</span> onload=<span class="string">"messageLoad()"</span>&gt;&lt;/iframe&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">messageLoad</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> url = <span class="string">"http://127.0.0.1:9090"</span>;</div><div class="line"><span class="built_in">window</span>.postIframe.postMessage(<span class="string">"给我tsort的信息"</span>,url); <span class="comment">//发送数据</span></div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="built_in">window</span>.onmessage = <span class="function"><span class="keyword">function</span>(<span class="params">e</span>)</span>&#123;</div><div class="line">e = e || event;</div><div class="line"><span class="built_in">console</span>.log(e.data); <span class="comment">//接收b返回的数据，在控制台有两次输出</span></div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>body&gt;</div><div class="line">&lt;<span class="regexp">/html&gt;</span></div></pre></td></tr></table></figure><p>b.html</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line">&lt;!DOCTYPE html&gt;</div><div class="line">&lt;html lang=<span class="string">"en"</span>&gt;</div><div class="line">&lt;head&gt;</div><div class="line">&lt;meta charset=<span class="string">"UTF-8"</span>&gt;</div><div class="line">&lt;title&gt;Document&lt;<span class="regexp">/title&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>head&gt;</div><div class="line">&lt;body&gt;</div><div class="line">&lt;script&gt;</div><div class="line"><span class="built_in">window</span>.onmessage = <span class="function"><span class="keyword">function</span>(<span class="params">e</span>)</span>&#123;</div><div class="line">e = e || event;</div><div class="line">alert(e.data); <span class="comment">//立即弹出a发送过来的数据</span></div><div class="line">e.source.postMessage(<span class="string">"好的，请稍等三秒！"</span>,e.origin); <span class="comment">//立即回复a</span></div><div class="line"></div><div class="line"><span class="keyword">var</span> postData = &#123;<span class="attr">name</span>:<span class="string">"tsrot"</span>,<span class="attr">age</span>:<span class="number">24</span>&#125;;</div><div class="line"><span class="keyword">var</span> strData = <span class="built_in">JSON</span>.stringify(postData); <span class="comment">//json对象转化为字符串</span></div><div class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">e.source.postMessage(strData,e.origin);</div><div class="line">&#125;,<span class="number">3000</span>); <span class="comment">//3秒后向a发送数据</span></div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>body&gt;</div><div class="line">&lt;<span class="regexp">/html&gt;</span></div></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;window.postMessage(message,targetOrigin) 方法是html5新引进的特性，可以使用它来向其它的window对象发送消息，无论这个window对象是属于同源或不同源，目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="跨域" scheme="http://blog.xieliqun.com/tags/%E8%B7%A8%E5%9F%9F/"/>
    
  </entry>
  
  <entry>
    <title>JS原型和原型链</title>
    <link href="http://blog.xieliqun.com/2016/08/21/prototype/"/>
    <id>http://blog.xieliqun.com/2016/08/21/prototype/</id>
    <published>2016-08-20T19:32:55.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>在JavaScript的使用过程中，我们经常会遇到prototype，可能了解一点，它是一个对象的原型，用来做原型继承的。这样去理解就有点不准确了，今天就让我们深入的去了解它。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><h3 id="了解一些概念"><a href="#了解一些概念" class="headerlink" title="了解一些概念"></a>了解一些概念</h3><p>在读这篇文章之前，你应该去在自己的脑海问几个问题：<br>1、什么是原型？<br>2、什么事原型链？<br>3、prototype与__proto__有什么不同，有什么联系？<br>4、constructor与面两个有什么联系，怎么用？</p><p>如果你把上面这四个问题都解决了，那你就真正了解了JS的原型和原型链。接下来，咱们一个一个问题去解决。</p><h3 id="什么是原型"><a href="#什么是原型" class="headerlink" title="什么是原型"></a>什么是原型</h3><p>JavaScript 中，万物皆对象！但对象也是有区别的。分为普通对象和函数对象，Object ，Function 是JS自带的函数对象。每个对象都有原型（null和undefined除外），你可以把它理解为对象的默认属性和方法。</p><p>你可以把下面的代码在浏览器打印出来看一下。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">console</span>.log(<span class="built_in">Object</span>.prototype); <span class="comment">//Object&#123;&#125;</span></div><div class="line"></div><div class="line"><span class="keyword">var</span> o = <span class="keyword">new</span> <span class="built_in">Object</span>();</div><div class="line"><span class="built_in">console</span>.log(o.prototype);  <span class="comment">//undefined</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(<span class="built_in">Array</span>.prototype); <span class="comment">//[Symbol(Symbol.unscopables): Object]</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(<span class="built_in">Function</span>.prototype); <span class="comment">//function()&#123;&#125;</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="built_in">console</span>.log(<span class="string">"hello"</span>);</div><div class="line">&#125;</div><div class="line">hello.prototype = <span class="string">"hello world"</span>;</div><div class="line"><span class="built_in">console</span>.log(hello.prototype); <span class="comment">//hello world</span></div></pre></td></tr></table></figure><p><strong>Object</strong>：Object是一个函数对象，Object的原型就是一个Object对象，它里面存在着一些对象的方法和属性，例如最常见的toString方法。</p><p><strong>新建对象</strong>：用new Object或者{}建的对象是普通对象，它没有prototype属性，只有__proto__属性，它指向Object.prototype。</p><p><strong>Array</strong>：Array也是一个函数对象，它的原型就是Array.prototype，它里面存在着一些数组的方法和属性，例如常见的push，pop等方法。</p><p><strong>Function</strong>：Function也是一个函数对象，但它有点特殊，它的原型就是一个function空函数。</p><p><strong>自定义函数</strong>：它的原型就是你给它指定的那个东西。如果你不指定，那它的原型就是一个Object.prototype。</p><h3 id="什么是原型链"><a href="#什么是原型链" class="headerlink" title="什么是原型链"></a>什么是原型链</h3><p>在 javaScript 中，每个对象都有一个指向它的原型（prototype）对象的内部链接。这个原型对象又有自己的原型，直到某个对象的原型为 null 为止（也就是不再有原型指向），组成这条链的最后一环。这种一级一级的链结构就称为原型链（prototype chain）。</p><p>JavaScript 对象是动态的属性“包”（指其自己的属性）。JavaScript 对象有一个指向一个原型对象的链。当试图访问一个对象的属性时，它不仅仅在该对象上搜寻，还会搜寻该对象的原型，以及该对象的原型的原型，依此层层向上搜索，直到找到一个名字匹配的属性或到达原型链的末尾。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> o = &#123;</div><div class="line">a:<span class="number">1</span>,</div><div class="line">b:<span class="number">2</span></div><div class="line">&#125;;</div><div class="line"><span class="built_in">console</span>.log(o.toString()); <span class="comment">//不报错，o上没有toString方法，但是Object上有</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(o.push(<span class="string">"c"</span>)); <span class="comment">//报错，o上没有这个方法，Object上也没有这个方法。</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(o.a); <span class="comment">//1</span></div><div class="line"><span class="built_in">console</span>.log(o.c); <span class="comment">//undefined</span></div></pre></td></tr></table></figure><p>当你用new Object或者直接定义一个对象时，它的原型链就是：<br>o  ==》 Object.prototype ==》 null<br>但你访问o上没有的属性或方法时，JS会往Object.prototype上寻找该属性和方法。如果有则直接返回，如果没有，方法则报错，这个方法未定义，属性则返回undefined。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params">name</span>)</span>&#123;</div><div class="line"><span class="keyword">this</span>.name = name;</div><div class="line">&#125;</div><div class="line">Person.prototype = &#123;<span class="attr">age</span>:<span class="number">24</span>&#125;;</div><div class="line"></div><div class="line"><span class="keyword">var</span> tsrot = <span class="keyword">new</span> Person(<span class="string">"tsrot"</span>);</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(tsrot.name); <span class="comment">//tsrot</span></div><div class="line"><span class="built_in">console</span>.log(tsrot.age);  <span class="comment">//24</span></div><div class="line"><span class="built_in">console</span>.log(tsrot.toString()); <span class="comment">//[object Object]</span></div></pre></td></tr></table></figure><p>当你用构造函数（构造函数我们一般首字母大写）建立一个对象时，它的原型链就是：<br>tsrot  ==》 Person.prototype ==》 Object.prototype ==》 null<br>如果没有定义Person.prototype这一环，则直接跳到下一环。</p><p>来点更复杂的。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Parent</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">this</span>.name = <span class="string">"i am parent"</span>;</div><div class="line">&#125;</div><div class="line">Parent.prototype = &#123;<span class="attr">age</span>:<span class="number">24</span>&#125;;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Child</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">this</span>.name = <span class="string">"i am child"</span>;</div><div class="line">&#125;</div><div class="line"></div><div class="line">Child.prototype = <span class="built_in">Object</span>.create(Parent.prototype); <span class="comment">//让Child的原型指向Parent的原型</span></div><div class="line">Child.prototype.constructor = Child; <span class="comment">//把child的构造函数指向回来，否则它将指向Parent。虽然在这没什么影响，但要养成代码的严谨性</span></div><div class="line"></div><div class="line"><span class="keyword">var</span> child = <span class="keyword">new</span> Child();</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(child.name); <span class="comment">//i am child</span></div><div class="line"><span class="built_in">console</span>.log(child.age);   <span class="comment">//24</span></div><div class="line"><span class="built_in">console</span>.log(child.toString()); <span class="comment">//[object Object]</span></div></pre></td></tr></table></figure></p><p>当你需要父类的属性和方法时，你可以把它的原型指向父类的原型。此时的原型链就是：<br>child ==》 Parent.prototype ==》 Object.prototype ==》 null</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(arr); <span class="comment">//[1,2,3]</span></div><div class="line">arr.push(<span class="number">4</span>);</div><div class="line"><span class="built_in">console</span>.log(arr); <span class="comment">//[1,2,3,4]</span></div></pre></td></tr></table></figure><p>数组也是一个对象，不过它是由Array构造函数new而来的，所以它的原型链就是：<br>arr ==》 Array.prototype ==》 Object.prototype ==》 null</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> fun = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> hello = <span class="string">"i am function"</span>;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(fun.name); <span class="comment">//fun</span></div></pre></td></tr></table></figure><p>fun是一个函数对象，它是由Function构造函数new而来的，所以它的原型链就是：<br>fun ==》 Function.prototype  ==》 Object.prototype ==》 null<br>fun它没有name属性，但是Function它有，所以这个name就是Function原型上的。</p><h3 id="prototype与-proto"><a href="#prototype与-proto" class="headerlink" title="prototype与__proto__"></a>prototype与__proto__</h3><p>在Javascript中，每个函数都有一个原型属性prototype指向自身的原型，而由这个函数创建的对象也有一个__proto__属性指向这个原型，而函数的原型是一个对象（函数点prototype也是一个普通对象，Function.prototype除外,它是函数对象，但它很特殊，他没有prototype属性），所以这个对象也会有一个__proto__指向自己的原型，这样逐层深入直到Object对象的原型，这样就形成了原型链。普通对象没有prototype，但有__proto__属性。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">f1</span>(<span class="params"></span>)</span>&#123;&#125;;</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(f1.prototype) <span class="comment">//Object&#123;&#125;</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> f1.prototype) <span class="comment">//Object</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> <span class="built_in">Function</span>.prototype) <span class="comment">// Function，这个特殊</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> <span class="built_in">Object</span>.prototype) <span class="comment">//Object</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(<span class="keyword">typeof</span> <span class="built_in">Function</span>.prototype.prototype) <span class="comment">//undefined</span></div></pre></td></tr></table></figure><p>JS在创建对象（不论是普通对象还是函数对象）的时候，都有一个叫做__proto__的内置属性，用于指向创建它的函数对象的原型对象prototype。</p><p><strong>普通对象的__proto__</strong><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> o = &#123;<span class="attr">name</span>:<span class="string">"tsrot"</span>&#125;;</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(o.__proto__); <span class="comment">//Object&#123;&#125;</span></div><div class="line"><span class="built_in">console</span>.log(o.prototype); <span class="comment">//undefined</span></div><div class="line"><span class="built_in">console</span>.log(o.__proto__ === <span class="built_in">Object</span>.prototype);  <span class="comment">//true</span></div></pre></td></tr></table></figure></p><p><strong>构造对象的__proto__</strong><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Parent</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">this</span>.name = <span class="string">"i am parent"</span>;</div><div class="line">&#125;</div><div class="line">Parent.prototype = &#123;<span class="attr">age</span>:<span class="number">24</span>&#125;;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Child</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">this</span>.name = <span class="string">"i am child"</span>;</div><div class="line">&#125;</div><div class="line"></div><div class="line">Child.prototype = <span class="built_in">Object</span>.create(Parent.prototype);</div><div class="line">Child.prototype.constructor = Child;</div><div class="line"></div><div class="line"><span class="keyword">var</span> child = <span class="keyword">new</span> Child();</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(child.__proto__); <span class="comment">//Object&#123;&#125;</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(Child.prototype); <span class="comment">//Object&#123;&#125;</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(child.__proto__ === Child.prototype); <span class="comment">//true</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(Parent.prototype.__proto__ === <span class="built_in">Object</span>.prototype); <span class="comment">//true</span></div></pre></td></tr></table></figure></p><p><strong>数组的__proto__</strong><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>];</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(arr.__proto__);  <span class="comment">//[Symbol(Symbol.unscopables): Object]</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(<span class="built_in">Array</span>.prototype); <span class="comment">//[Symbol(Symbol.unscopables): Object]</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(arr.__proto__ === <span class="built_in">Array</span>.prototype); <span class="comment">//true</span></div></pre></td></tr></table></figure></p><p><strong>函数的__proto__</strong><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> fun = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> hello = <span class="string">"i am function"</span></div><div class="line">&#125;</div><div class="line"></div><div class="line">fun.prototype = &#123;<span class="attr">name</span>:<span class="string">"tsrot"</span>&#125;;</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(fun.prototype); <span class="comment">//Object &#123;name: "tsrot"&#125;</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(fun.__proto__); <span class="comment">//function()&#123;&#125;</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(fun.prototype === fun.__proto__); <span class="comment">//false</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(fun.__proto__ === <span class="built_in">Function</span>.prototype); <span class="comment">//true</span></div></pre></td></tr></table></figure></p><h3 id="constructor属性"><a href="#constructor属性" class="headerlink" title="constructor属性"></a>constructor属性</h3><p>原型对象prototype中都有个预定义的constructor属性，用来引用它的函数对象。这是一种循环引用：</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params">name</span>)</span>&#123;</div><div class="line"><span class="keyword">this</span>.name = name;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(Person.prototype.constructor === Person); <span class="comment">//true</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(<span class="built_in">Function</span>.prototype.constructor === <span class="built_in">Function</span>); <span class="comment">//true</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(<span class="built_in">Object</span>.prototype.constructor === <span class="built_in">Object</span>); <span class="comment">//true</span></div></pre></td></tr></table></figure><p>用构造函数创建的对象，它的constructor属性就是它的构造函数。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Person</span>(<span class="params">name</span>)</span>&#123;</div><div class="line"><span class="keyword">this</span>.name = name;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> person = <span class="keyword">new</span> Person();</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(person.constructor === Person); <span class="comment">//true</span></div></pre></td></tr></table></figure></p><h3 id="参考文章"><a href="#参考文章" class="headerlink" title="参考文章"></a>参考文章</h3><p>1、<a href="https://www.toptal.com/javascript/javascript-prototypes-scopes-and-performance-what-you-need-to-know" target="_blank" rel="external">JavaScript Prototype Chains</a><br>2、<a href="https://javascriptweblog.wordpress.com/2010/06/07/understanding-javascript-prototypes/" target="_blank" rel="external">Understanding JavaScript Prototypes</a><br>3、<a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Inheritance_and_the_prototype_chain" target="_blank" rel="external">继承与原型链</a></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;在JavaScript的使用过程中，我们经常会遇到prototype，可能了解一点，它是一个对象的原型，用来做原型继承的。这样去理解就有点不准确了，今天就让我们深入的去了解它。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="原型" scheme="http://blog.xieliqun.com/tags/%E5%8E%9F%E5%9E%8B/"/>
    
      <category term="原型链" scheme="http://blog.xieliqun.com/tags/%E5%8E%9F%E5%9E%8B%E9%93%BE/"/>
    
  </entry>
  
  <entry>
    <title>Arguments对象作用深度研究</title>
    <link href="http://blog.xieliqun.com/2016/08/14/arguments/"/>
    <id>http://blog.xieliqun.com/2016/08/14/arguments/</id>
    <published>2016-08-14T05:56:58.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>每个函数都会有一个Arguments对象实例arguments，它引用着函数的实参，可以用数组下标的方式”[]”引用arguments的元素。arguments.length为函数实参个数，arguments.callee引用函数自身。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><h3 id="Arguments对象介绍"><a href="#Arguments对象介绍" class="headerlink" title="Arguments对象介绍"></a>Arguments对象介绍</h3><p>Arguments对象是一个伪数组对象，它有length属性，可以arguments[i]来访问对象中的元素，但它不能用数组的一些方法，例如push，pop，slice等。</p><h4 id="Arguments的length属性"><a href="#Arguments的length属性" class="headerlink" title="Arguments的length属性"></a>Arguments的length属性</h4><p>Arguments的length属性，表示function函数实际所传参数的个数。函数名点length可以获取函数期望的传参个数。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">argTest</span>(<span class="params">a,b,c</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> t = <span class="built_in">arguments</span>.length; <span class="comment">//实际传参个数</span></div><div class="line"><span class="keyword">var</span> e = argTest.length;   <span class="comment">//期望传参个数</span></div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(t);</div><div class="line"><span class="built_in">console</span>.log(e);</div><div class="line">&#125;</div><div class="line"></div><div class="line">argTest(<span class="number">11</span>,<span class="number">12</span>);       <span class="comment">//t=2,e=3</span></div><div class="line">argTest(<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>);    <span class="comment">//t=3,e=3</span></div><div class="line">argTest(<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>,<span class="number">14</span>); <span class="comment">//t=4,e=3</span></div></pre></td></tr></table></figure><h4 id="Arguments的参数访问"><a href="#Arguments的参数访问" class="headerlink" title="Arguments的参数访问"></a>Arguments的参数访问</h4><p>Arguments对象的参数访问可以用arguments[i]来访问函数所传的参数。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">argTest</span>(<span class="params">a,b,c</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> arg = [];</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;<span class="built_in">arguments</span>.length;i++)&#123;</div><div class="line">arg.push(<span class="built_in">arguments</span>[i]);</div><div class="line">&#125;</div><div class="line"><span class="built_in">console</span>.log(arg);</div><div class="line">&#125;</div><div class="line"></div><div class="line">argTest(<span class="number">11</span>,<span class="number">12</span>);       <span class="comment">//[11, 12]</span></div><div class="line">argTest(<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>);    <span class="comment">//[11, 12, 13]</span></div><div class="line">argTest(<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>,<span class="number">14</span>); <span class="comment">//[11, 12, 13, 14]</span></div></pre></td></tr></table></figure><h4 id="Arguments的callee调用"><a href="#Arguments的callee调用" class="headerlink" title="Arguments的callee调用"></a>Arguments的callee调用</h4><p>Arguments的callee属性可以调用函数本身，当函数正在执行时才可调用，可以实现方法的递归调用。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">argTest</span>(<span class="params">a,b,c</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> e = <span class="built_in">arguments</span>.callee.toString();</div><div class="line"><span class="built_in">console</span>.log(e);</div><div class="line">&#125;</div><div class="line"></div><div class="line">argTest(); <span class="comment">//打印出函数本身</span></div></pre></td></tr></table></figure><h4 id="Function对象caller属性"><a href="#Function对象caller属性" class="headerlink" title="Function对象caller属性"></a>Function对象caller属性</h4><p>Function对象的caller属性可以指向当前函数的调用者，当调用者函数正在执行时才可调用，</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">callerTest</span>(<span class="params"></span>)</span>&#123;</div><div class="line"></div><div class="line"><span class="keyword">if</span>(callerTest.caller)&#123;</div><div class="line"><span class="keyword">var</span> caller = callerTest.caller.toString();</div><div class="line"><span class="built_in">console</span>.log(caller);</div><div class="line">&#125;<span class="keyword">else</span>&#123;</div><div class="line"><span class="built_in">console</span>.log(<span class="string">"no caller"</span>)</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">handler</span>(<span class="params"></span>)</span>&#123;</div><div class="line">callerTest();</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">handlerToHandler</span>(<span class="params"></span>)</span>&#123;</div><div class="line">handler();</div><div class="line">&#125;</div><div class="line"></div><div class="line">callerTest();        <span class="comment">//no caller</span></div><div class="line">handler();           <span class="comment">//返回调用者handler函数</span></div><div class="line">handlerToHandler();  <span class="comment">//返回调用者handler函数</span></div></pre></td></tr></table></figure><h3 id="Arguments的作用"><a href="#Arguments的作用" class="headerlink" title="Arguments的作用"></a>Arguments的作用</h3><h4 id="方法重载"><a href="#方法重载" class="headerlink" title="方法重载"></a>方法重载</h4><p>方法重载是指在一个类中定义多个同名的方法，但要求每个方法具有不同的参数的类型或参数的个数。<br>Javascript并没有重载函数的功能，但是Arguments对象能够模拟重载。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//普通方法实现方法重载</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params">a,b,c</span>)</span>&#123;</div><div class="line"><span class="keyword">if</span>(a &amp;&amp; b &amp;&amp; c)&#123;</div><div class="line"><span class="built_in">console</span>.log(a + b + c);</div><div class="line">&#125;<span class="keyword">else</span> <span class="keyword">if</span>(a &amp;&amp; b)&#123;</div><div class="line"><span class="built_in">console</span>.log(a + b);</div><div class="line">&#125;<span class="keyword">else</span>&#123;</div><div class="line"><span class="built_in">console</span>.log(a);</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">test();           <span class="comment">//undefined</span></div><div class="line">test(<span class="number">11</span>,<span class="number">12</span>);      <span class="comment">//23</span></div><div class="line">test(<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>)    <span class="comment">//36</span></div></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//Arguments对象实现方法重载</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> sum = <span class="number">0</span>;</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;<span class="built_in">arguments</span>.length;i++)&#123;</div><div class="line">sum += <span class="built_in">arguments</span>[i];</div><div class="line">&#125;</div><div class="line"><span class="built_in">console</span>.log(sum);</div><div class="line">&#125;</div><div class="line"></div><div class="line">test();          <span class="comment">//0</span></div><div class="line">test(<span class="number">11</span>,<span class="number">12</span>);     <span class="comment">//23</span></div><div class="line">test(<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>);  <span class="comment">//36</span></div></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//ES6实现方法重载</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params">...nums</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> sum = <span class="number">0</span>;</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;nums.length;i++)&#123;</div><div class="line">sum += nums[i];</div><div class="line">&#125;</div><div class="line"><span class="built_in">console</span>.log(sum);</div><div class="line">&#125;</div><div class="line"></div><div class="line">test();          <span class="comment">//0</span></div><div class="line">test(<span class="number">11</span>,<span class="number">12</span>);     <span class="comment">//23</span></div><div class="line">test(<span class="number">11</span>,<span class="number">12</span>,<span class="number">13</span>);  <span class="comment">//36</span></div></pre></td></tr></table></figure><h4 id="递归调用"><a href="#递归调用" class="headerlink" title="递归调用"></a>递归调用</h4><p>这样的好处就是可以实现匿名函数的递归调用。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//实现一个阶乘函数</span></div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">factorial</span>(<span class="params">n</span>)</span>&#123;</div><div class="line"><span class="keyword">if</span>(n == <span class="number">1</span>)&#123;</div><div class="line"><span class="keyword">return</span> <span class="number">1</span>;</div><div class="line">&#125;<span class="keyword">else</span>&#123;</div><div class="line">n * <span class="built_in">arguments</span>.callee(n<span class="number">-1</span>);</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line">factorial(<span class="number">1</span>); <span class="comment">//1</span></div><div class="line">factorial(<span class="number">5</span>); <span class="comment">//120</span></div></pre></td></tr></table></figure><h4 id="不定参问题"><a href="#不定参问题" class="headerlink" title="不定参问题"></a>不定参问题</h4><p>比如说，我想判断你传给我的一些数字的大小，取出最大的那个</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">max</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> maxNum = <span class="built_in">Number</span>.NEGATIVE_INFINITY;;</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;<span class="built_in">arguments</span>.length;i++)&#123;</div><div class="line"><span class="keyword">if</span>(<span class="built_in">arguments</span>[i]&gt; maxNum)&#123;</div><div class="line">maxNum = <span class="built_in">arguments</span>[i];</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line"><span class="keyword">return</span> maxNum;</div><div class="line">&#125;</div><div class="line"></div><div class="line">max(<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">11</span>,<span class="number">4</span>,<span class="number">10</span>); <span class="comment">//11</span></div><div class="line">max(<span class="number">2</span>,<span class="number">-10</span>,<span class="number">22</span>,<span class="number">11</span>);   <span class="comment">//22</span></div></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;每个函数都会有一个Arguments对象实例arguments，它引用着函数的实参，可以用数组下标的方式”[]”引用arguments的元素。arguments.length为函数实参个数，arguments.callee引用函数自身。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="Arguments" scheme="http://blog.xieliqun.com/tags/Arguments/"/>
    
  </entry>
  
  <entry>
    <title>事件绑定、事件监听、事件委托</title>
    <link href="http://blog.xieliqun.com/2016/08/12/event-delegate/"/>
    <id>http://blog.xieliqun.com/2016/08/12/event-delegate/</id>
    <published>2016-08-12T04:37:52.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>在JavaScript的学习中，我们经常会遇到JavaScript的事件机制，例如，事件绑定、事件监听、事件委托（事件代理）等。这些名词是什么意思呢，有什么作用呢？<br><a id="more"></a></excerpt></p><the rest="" of="" contents="" |="" 余下全文=""><h3 id="事件绑定"><a href="#事件绑定" class="headerlink" title="事件绑定"></a>事件绑定</h3><p>要想让 JavaScript 对用户的操作作出响应，首先要对 DOM 元素绑定事件处理函数。所谓事件处理函数，就是处理用户操作的函数，不同的操作对应不同的名称。</p><p>在JavaScript中，有三种常用的绑定事件的方法：</p><ul><li>在DOM元素中直接绑定；</li><li>在JavaScript代码中绑定；</li><li>绑定事件监听函数。</li></ul><h4 id="在DOM中直接绑定事件"><a href="#在DOM中直接绑定事件" class="headerlink" title="在DOM中直接绑定事件"></a>在DOM中直接绑定事件</h4><p>我们可以在DOM元素上绑定onclick、onmouseover、onmouseout、onmousedown、onmouseup、ondblclick、onkeydown、onkeypress、onkeyup等。好多不一一列出了。如果想知道更多事件类型请查看，<a href="http://www.runoob.com/jsref/dom-obj-event.html" target="_blank" rel="external">DOM事件</a>。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> onclick=<span class="string">"hello()"</span>&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello world!"</span>);</div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure><h4 id="在JavaScript代码中绑定事件"><a href="#在JavaScript代码中绑定事件" class="headerlink" title="在JavaScript代码中绑定事件"></a>在JavaScript代码中绑定事件</h4><p>在JavaScript代码中（即<code>script</code>标签内）绑定事件可以使JavaScript代码与HTML标签分离，文档结构清晰，便于管理和开发。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> id=<span class="string">"btn"</span>&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="built_in">document</span>.getElementById(<span class="string">"btn"</span>).onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello world!"</span>);</div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure><h4 id="使用事件监听绑定事件"><a href="#使用事件监听绑定事件" class="headerlink" title="使用事件监听绑定事件"></a>使用事件监听绑定事件</h4><p>绑定事件的另一种方法是用 addEventListener() 或 attachEvent() 来绑定事件监听函数。下面详细介绍，事件监听。</p><h3 id="事件监听"><a href="#事件监听" class="headerlink" title="事件监听"></a>事件监听</h3><p>关于事件监听，W3C规范中定义了3个事件阶段，依次是捕获阶段、目标阶段、冒泡阶段。</p><p>起初Netscape制定了JavaScript的一套事件驱动机制（即事件捕获）。随即IE也推出了自己的一套事件驱动机制（即事件冒泡）。最后W3C规范了两种事件机制，分为捕获阶段、目标阶段、冒泡阶段。IE8以前IE一直坚持自己的事件机制（前端人员一直头痛的兼容性问题），IE9以后IE也支持了W3C规范。</p><h4 id="W3C规范"><a href="#W3C规范" class="headerlink" title="W3C规范"></a>W3C规范</h4><p>语法：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">element.addEventListener(event, <span class="function"><span class="keyword">function</span>, <span class="title">useCapture</span>)</span></div></pre></td></tr></table></figure></p><p>event : （必需）事件名，支持所有<a href="http://www.runoob.com/jsref/dom-obj-event.html" target="_blank" rel="external">DOM事件</a>。<br>function：（必需）指定要事件触发时执行的函数。<br>useCapture：（可选）指定事件是否在捕获或冒泡阶段执行。true，捕获。false，冒泡。默认false。</p><p>注：IE8以下不支持。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> id=<span class="string">"btn1"</span>&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="built_in">document</span>.getElementById(<span class="string">"btn1"</span>).addEventListener(<span class="string">"click"</span>,hello);</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello world!"</span>);</div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure></p><h4 id="IE标准"><a href="#IE标准" class="headerlink" title="IE标准"></a>IE标准</h4><p>语法：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">element.attachEvent(event, <span class="function"><span class="keyword">function</span>)</span></div></pre></td></tr></table></figure></p><p>event：（必需）事件类型。需加“on“，例如：onclick。<br>function：（必需）指定要事件触发时执行的函数。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> id=<span class="string">"btn2"</span>&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="built_in">document</span>.getElementById(<span class="string">"btn2"</span>).attachEvent(<span class="string">"onclick"</span>,hello);</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello world!"</span>);</div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure><h4 id="事件监听的优点"><a href="#事件监听的优点" class="headerlink" title="事件监听的优点"></a>事件监听的优点</h4><p>1、可以绑定多个事件。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> id=<span class="string">"btn3"</span>&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> btn3 = <span class="built_in">document</span>.getElementById(<span class="string">"btn3"</span>);</div><div class="line">btn3.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello 1"</span>); <span class="comment">//不执行</span></div><div class="line">&#125;</div><div class="line">btn3.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello 2"</span>); <span class="comment">//执行</span></div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure></p><p>常规的事件绑定只执行最后绑定的事件。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> id=<span class="string">"btn4"</span>&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> btn4 = <span class="built_in">document</span>.getElementById(<span class="string">"btn4"</span>);</div><div class="line">btn4.addEventListener(<span class="string">"click"</span>,hello1);</div><div class="line">btn4.addEventListener(<span class="string">"click"</span>,hello2);</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello1</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello 1"</span>);</div><div class="line">&#125;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello2</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello 2"</span>);</div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure><p>两个事件都执行了。</p><p>2、可以解除相应的绑定<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> id=<span class="string">"btn5"</span>&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> btn5 = <span class="built_in">document</span>.getElementById(<span class="string">"btn5"</span>);</div><div class="line">btn5.addEventListener(<span class="string">"click"</span>,hello1);<span class="comment">//执行了</span></div><div class="line">btn5.addEventListener(<span class="string">"click"</span>,hello2);<span class="comment">//不执行</span></div><div class="line">btn5.removeEventListener(<span class="string">"click"</span>,hello2);</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello1</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello 1"</span>);</div><div class="line">&#125;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello2</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello 2"</span>);</div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure></p><h4 id="封装事件监听"><a href="#封装事件监听" class="headerlink" title="封装事件监听"></a>封装事件监听</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> id=<span class="string">"btn5"</span>&gt;</div><div class="line"></div><div class="line"><span class="comment">//绑定监听事件</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">addEventHandler</span>(<span class="params">target,type,fn</span>)</span>&#123;</div><div class="line"><span class="keyword">if</span>(target.addEventListener)&#123;</div><div class="line">target.addEventListener(type,fn);</div><div class="line">&#125;<span class="keyword">else</span>&#123;</div><div class="line">target.attachEvent(<span class="string">"on"</span>+type,fn);</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="comment">//移除监听事件</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">removeEventHandler</span>(<span class="params">target,type,fn</span>)</span>&#123;</div><div class="line"><span class="keyword">if</span>(target.removeEventListener)&#123;</div><div class="line">target.removeEventListener(type,fn);</div><div class="line">&#125;<span class="keyword">else</span>&#123;</div><div class="line">target.detachEvent(<span class="string">"on"</span>+type,fn);</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="comment">//测试</span></div><div class="line"><span class="keyword">var</span> btn5 = <span class="built_in">document</span>.getElementById(<span class="string">"btn5"</span>);</div><div class="line">addEventHandler(btn5,<span class="string">"click"</span>,hello1);<span class="comment">//添加事件hello1</span></div><div class="line">addEventHandler(btn5,<span class="string">"click"</span>,hello2);<span class="comment">//添加事件hello2</span></div><div class="line">removeEventHandler(btn5,<span class="string">"click"</span>,hello1);<span class="comment">//移除事件hello1</span></div></pre></td></tr></table></figure><h3 id="事件委托"><a href="#事件委托" class="headerlink" title="事件委托"></a>事件委托</h3><p>事件委托就是利用冒泡的原理，把事件加到父元素或祖先元素上，触发执行效果。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> id=<span class="string">"btn6"</span>&gt;</div><div class="line"></div><div class="line"><span class="keyword">var</span> btn6 = <span class="built_in">document</span>.getElementById(<span class="string">"btn6"</span>);</div><div class="line"><span class="built_in">document</span>.onclick = <span class="function"><span class="keyword">function</span>(<span class="params">event</span>)</span>&#123;</div><div class="line">event = event || <span class="built_in">window</span>.event;</div><div class="line"><span class="keyword">var</span> target = event.target || event.srcElement;</div><div class="line"><span class="keyword">if</span>(target == btn6)&#123;</div><div class="line">alert(btn5.value);</div><div class="line">&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure><p>上面只是个例子，代码尽可能的简化了。在实际的代码中 我们可能用到jQuery的live()、delegate()、bind()、on()等。</p><h4 id="事件委托优点"><a href="#事件委托优点" class="headerlink" title="事件委托优点"></a>事件委托优点</h4><p>1、提高JavaScript性能。事件委托可以显著的提高事件的处理速度，减少内存的占用。<a href="http://www.diguage.com/archives/71.html" target="_blank" rel="external">实例分析JavaScript中的事件委托和事件绑定</a>，这篇文章写得还不错。</p><p><strong>传统写法</strong></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div></pre></td><td class="code"><pre><div class="line">&lt;ul id=<span class="string">"list"</span>&gt;</div><div class="line">  &lt;li id=<span class="string">"item1"</span> &gt;item1&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">  &lt;li id="item2" &gt;item2&lt;/</span>li&gt;</div><div class="line">  &lt;li id=<span class="string">"item3"</span> &gt;item3&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;/u</span>l&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> item1 = <span class="built_in">document</span>.getElementById(<span class="string">"item1"</span>);</div><div class="line"><span class="keyword">var</span> item2 = <span class="built_in">document</span>.getElementById(<span class="string">"item2"</span>);</div><div class="line"><span class="keyword">var</span> item3 = <span class="built_in">document</span>.getElementById(<span class="string">"item3"</span>);</div><div class="line"></div><div class="line">item1.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello item1"</span>);</div><div class="line">&#125;</div><div class="line">item2.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello item2"</span>);</div><div class="line">&#125;</div><div class="line">item3.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(<span class="string">"hello item3"</span>);</div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure><p><strong>事件委托</strong><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line">&lt;ul id=<span class="string">"list"</span>&gt;</div><div class="line">  &lt;li id=<span class="string">"item1"</span> &gt;item1&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">  &lt;li id="item2" &gt;item2&lt;/</span>li&gt;</div><div class="line">  &lt;li id=<span class="string">"item3"</span> &gt;item3&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;/u</span>l&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> item1 = <span class="built_in">document</span>.getElementById(<span class="string">"item1"</span>);</div><div class="line"><span class="keyword">var</span> item2 = <span class="built_in">document</span>.getElementById(<span class="string">"item2"</span>);</div><div class="line"><span class="keyword">var</span> item3 = <span class="built_in">document</span>.getElementById(<span class="string">"item3"</span>);</div><div class="line"></div><div class="line"><span class="built_in">document</span>.addEventListener(<span class="string">"click"</span>,<span class="function"><span class="keyword">function</span>(<span class="params">event</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> target = event.target;</div><div class="line"><span class="keyword">if</span>(target == item1)&#123;</div><div class="line">alert(<span class="string">"hello item1"</span>);</div><div class="line">&#125;<span class="keyword">else</span> <span class="keyword">if</span>(target == item2)&#123;</div><div class="line">alert(<span class="string">"hello item2"</span>);</div><div class="line">&#125;<span class="keyword">else</span> <span class="keyword">if</span>(target == item3)&#123;</div><div class="line">alert(<span class="string">"hello item3"</span>);</div><div class="line">&#125;</div><div class="line">&#125;)</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure></p><p>2、动态的添加DOM元素，不需要因为元素的改动而修改事件绑定。</p><p><strong>传统写法</strong><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div></pre></td><td class="code"><pre><div class="line">&lt;ul id=<span class="string">"list"</span>&gt;</div><div class="line">  &lt;li id=<span class="string">"item1"</span> &gt;item1&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">  &lt;li id="item2" &gt;item2&lt;/</span>li&gt;</div><div class="line">  &lt;li id=<span class="string">"item3"</span> &gt;item3&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;/u</span>l&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> list = <span class="built_in">document</span>.getElementById(<span class="string">"list"</span>);</div><div class="line"></div><div class="line"><span class="keyword">var</span> item = list.getElementsByTagName(<span class="string">"li"</span>);</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;item.length;i++)&#123;</div><div class="line">(<span class="function"><span class="keyword">function</span>(<span class="params">i</span>)</span>&#123;</div><div class="line">item[i].onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(item[i].innerHTML);</div><div class="line">&#125;</div><div class="line">&#125;)(i)</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> node=<span class="built_in">document</span>.createElement(<span class="string">"li"</span>);</div><div class="line"><span class="keyword">var</span> textnode=<span class="built_in">document</span>.createTextNode(<span class="string">"item4"</span>);</div><div class="line">node.appendChild(textnode);</div><div class="line">list.appendChild(node);</div><div class="line"></div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure></p><p>点击item1到item3都有事件响应，但是点击item4时，没有事件响应。说明传统的事件绑定无法对动态添加的元素而动态的添加事件。</p><p><strong>事件委托</strong><br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line">&lt;ul id=<span class="string">"list"</span>&gt;</div><div class="line">  &lt;li id=<span class="string">"item1"</span> &gt;item1&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">  &lt;li id="item2" &gt;item2&lt;/</span>li&gt;</div><div class="line">  &lt;li id=<span class="string">"item3"</span> &gt;item3&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;/u</span>l&gt;</div><div class="line"></div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> list = <span class="built_in">document</span>.getElementById(<span class="string">"list"</span>);</div><div class="line"></div><div class="line"><span class="built_in">document</span>.addEventListener(<span class="string">"click"</span>,<span class="function"><span class="keyword">function</span>(<span class="params">event</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> target = event.target;</div><div class="line"><span class="keyword">if</span>(target.nodeName == <span class="string">"LI"</span>)&#123;</div><div class="line">alert(target.innerHTML);</div><div class="line">&#125;</div><div class="line">&#125;)</div><div class="line"></div><div class="line"><span class="keyword">var</span> node=<span class="built_in">document</span>.createElement(<span class="string">"li"</span>);</div><div class="line"><span class="keyword">var</span> textnode=<span class="built_in">document</span>.createTextNode(<span class="string">"item4"</span>);</div><div class="line">node.appendChild(textnode);</div><div class="line">list.appendChild(node);</div><div class="line"></div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure></p><p>当点击item4时，item4有事件响应。说明事件委托可以为新添加的DOM元素动态的添加事件。</p></the>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;在JavaScript的学习中，我们经常会遇到JavaScript的事件机制，例如，事件绑定、事件监听、事件委托（事件代理）等。这些名词是什么意思呢，有什么作用呢？&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="事件绑定" scheme="http://blog.xieliqun.com/tags/%E4%BA%8B%E4%BB%B6%E7%BB%91%E5%AE%9A/"/>
    
      <category term="事件监听" scheme="http://blog.xieliqun.com/tags/%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC/"/>
    
      <category term="事件委托" scheme="http://blog.xieliqun.com/tags/%E4%BA%8B%E4%BB%B6%E5%A7%94%E6%89%98/"/>
    
  </entry>
  
  <entry>
    <title>JS中的call、apply、bind方法详解</title>
    <link href="http://blog.xieliqun.com/2016/08/11/call-apply-bind/"/>
    <id>http://blog.xieliqun.com/2016/08/11/call-apply-bind/</id>
    <published>2016-08-10T17:45:37.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>call()、apply()、bind()都是函数对象的一个方法，它们的作用都是改变函数的调用对象。它的使用极大的简化了代码的调用。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><h3 id="一、方法定义"><a href="#一、方法定义" class="headerlink" title="一、方法定义"></a>一、方法定义</h3><h4 id="call方法"><a href="#call方法" class="headerlink" title="call方法"></a>call方法</h4><p>语法：<code>call([thisObj[,arg1[, arg2[,   [,.argN]]]]])</code><br>定义：调用一个对象的一个方法，以另一个对象替换当前对象。<br>说明：call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数，那么 Global 对象被用作 thisObj。<br>arg1 … argN为被调用方法的传参。</p><h4 id="apply方法"><a href="#apply方法" class="headerlink" title="apply方法"></a>apply方法</h4><p>语法：<code>apply([thisObj[,argArray]])</code><br>定义：应用某一对象的一个方法，用另一个对象替换当前对象。<br>说明：apply的第一个参数thisObj和call方法的一样，第二个参数argArray为一个传参数组。thisObj如果未传，那么 Global 对象被用作 thisObj。</p><h4 id="bind方法"><a href="#bind方法" class="headerlink" title="bind方法"></a>bind方法</h4><p>在ECMAScript5中扩展了叫bind的方法（IE6,7,8不支持）<br>语法：<code>bind([thisObj[,arg1[, arg2[,   [,.argN]]]]])</code><br>定义：应用某一对象的一个方法，用另一个对象替换当前对象。<br>说明：bind的thisObj参数也和call方法一样，thisObj如果未传，那么 Global 对象被用作 thisObj。arg1 … argN可传可不传。如果不传，可以在调用的时候再传。如果传了，调用的时候则可以不传，调用的时候如果你还是传了，则不生效。例如：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> person = &#123;</div><div class="line">    name:<span class="string">"tsrot"</span>,</div><div class="line">    age:<span class="number">24</span>,</div><div class="line">    sayHello:<span class="function"><span class="keyword">function</span>(<span class="params">age</span>)</span>&#123;</div><div class="line">        <span class="built_in">console</span>.log(<span class="keyword">this</span>.name);</div><div class="line">        <span class="built_in">console</span>.log(age);</div><div class="line">    &#125;</div><div class="line">&#125;;</div><div class="line"><span class="keyword">var</span> son = &#123;</div><div class="line">name:<span class="string">"xieliqun"</span></div><div class="line">&#125;;</div><div class="line"><span class="keyword">var</span> boundFunc = person.sayHello.bind(son);</div><div class="line">boundFunc(<span class="number">25</span>); <span class="comment">// xieliqun  25</span></div></pre></td></tr></table></figure></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> boundFunc = person.sayHello.bind(son,<span class="number">25</span>);</div><div class="line">boundFunc(); <span class="comment">// xieliqun  25</span></div></pre></td></tr></table></figure><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> boundFunc = person.sayHello.bind(son,<span class="number">25</span>);</div><div class="line">boundFunc(<span class="number">30</span>); <span class="comment">// xieliqun  25</span></div></pre></td></tr></table></figure><h3 id="二、call、apply、bind的区别"><a href="#二、call、apply、bind的区别" class="headerlink" title="二、call、apply、bind的区别"></a>二、call、apply、bind的区别</h3><p>1、call的arg传参需一个一个传，apply则直接传一个数组。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">hello</span>(<span class="params">name,age</span>)</span>&#123;</div><div class="line"><span class="built_in">console</span>.log(name);</div><div class="line"><span class="built_in">console</span>.log(age);</div><div class="line">&#125;</div><div class="line">hello.call(<span class="keyword">this</span>,<span class="string">"tsrot"</span>,<span class="number">24</span>);</div><div class="line">hello.apply(<span class="keyword">this</span>,[<span class="string">"tsrot"</span>,<span class="number">24</span>]);</div></pre></td></tr></table></figure></p><p>2、call和apply直接执行函数，而bind需要再一次调用。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> obj = &#123;</div><div class="line">    x: <span class="number">81</span>,</div><div class="line">&#125;;</div><div class="line"></div><div class="line"><span class="keyword">var</span> foo = &#123;</div><div class="line">    getX: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line">        <span class="keyword">return</span> <span class="keyword">this</span>.x;</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(foo.getX.bind(obj)());  <span class="comment">//81</span></div><div class="line"><span class="built_in">console</span>.log(foo.getX.call(obj));    <span class="comment">//81</span></div><div class="line"><span class="built_in">console</span>.log(foo.getX.apply(obj));   <span class="comment">//81</span></div></pre></td></tr></table></figure></p><h3 id="三、运用场景"><a href="#三、运用场景" class="headerlink" title="三、运用场景"></a>三、运用场景</h3><h4 id="实现继承"><a href="#实现继承" class="headerlink" title="实现继承"></a>实现继承</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Animal</span>(<span class="params">name</span>) </span>&#123;</div><div class="line">  <span class="keyword">this</span>.name = name;</div><div class="line">  <span class="keyword">this</span>.showName = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="keyword">this</span>.name);</div><div class="line">  &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Cat</span>(<span class="params">name</span>) </span>&#123;</div><div class="line">  Animal.call(<span class="keyword">this</span>, name); <span class="comment">//Cat继承了Animal的showName方法</span></div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">var</span> cat = <span class="keyword">new</span> Cat(<span class="string">'Black Cat'</span>);</div><div class="line">cat.showName(); <span class="comment">//Black Cat</span></div></pre></td></tr></table></figure><h4 id="数组追加"><a href="#数组追加" class="headerlink" title="数组追加"></a>数组追加</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> array1 = [<span class="number">1</span> , <span class="number">2</span> , <span class="number">3</span>, <span class="number">5</span>];</div><div class="line"><span class="keyword">var</span> array2 = [<span class="string">"xie"</span> , <span class="string">"li"</span> , <span class="string">"qun"</span> , <span class="string">"tsrot"</span>];</div><div class="line"><span class="built_in">Array</span>.prototype.push.apply(array1, array2);</div><div class="line"><span class="built_in">console</span>.log(array1);<span class="comment">//[1, 2, 3, 5, "xie", "li", "qun", "tsrot"]</span></div></pre></td></tr></table></figure><h4 id="获取数组中的最大值和最小值"><a href="#获取数组中的最大值和最小值" class="headerlink" title="获取数组中的最大值和最小值"></a>获取数组中的最大值和最小值</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> num = [<span class="number">1</span>,<span class="number">3</span>,<span class="number">5</span>,<span class="number">7</span>,<span class="number">2</span>,<span class="number">-10</span>,<span class="number">11</span>];</div><div class="line"><span class="keyword">var</span> maxNum = <span class="built_in">Math</span>.max.apply(<span class="built_in">Math</span>, num);</div><div class="line"><span class="keyword">var</span> minNum = <span class="built_in">Math</span>.min.apply(<span class="built_in">Math</span>, num);</div><div class="line"><span class="built_in">console</span>.log(maxNum); <span class="comment">//11</span></div><div class="line"><span class="built_in">console</span>.log(minNum); <span class="comment">//-10</span></div></pre></td></tr></table></figure><h4 id="将伪数组转化为数组"><a href="#将伪数组转化为数组" class="headerlink" title="将伪数组转化为数组"></a>将伪数组转化为数组</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> fakeArr = &#123;<span class="number">0</span>:<span class="string">'a'</span>,<span class="number">1</span>:<span class="string">'b'</span>,<span class="attr">length</span>:<span class="number">2</span>&#125;;</div><div class="line"><span class="keyword">var</span> arr1 = <span class="built_in">Array</span>.prototype.slice.call(fakeArr);</div><div class="line"><span class="built_in">console</span>.log(arr1[<span class="number">0</span>]); <span class="comment">//a</span></div><div class="line"><span class="keyword">var</span> arr2 = [].slice.call(fakeArr);</div><div class="line"><span class="built_in">console</span>.log(arr2[<span class="number">0</span>]); <span class="comment">//a</span></div><div class="line"></div><div class="line">arr1.push(<span class="string">"c"</span>);</div><div class="line"><span class="built_in">console</span>.log(arr1); <span class="comment">//["a", "b", "c"]</span></div></pre></td></tr></table></figure><h4 id="保存this变量"><a href="#保存this变量" class="headerlink" title="保存this变量"></a>保存this变量</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// 正常情况下使用变量保存 this 值</span></div><div class="line"><span class="keyword">var</span> foo = &#123;</div><div class="line">    bar : <span class="number">1</span>,</div><div class="line">    eventBind: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">        <span class="keyword">var</span> _this = <span class="keyword">this</span> ;</div><div class="line">        $(<span class="string">'.someClass'</span>).on(<span class="string">'click'</span>,<span class="function"><span class="keyword">function</span>(<span class="params">event</span>) </span>&#123;</div><div class="line">            <span class="comment">/* Act on the event */</span></div><div class="line">            <span class="built_in">console</span>.log(_this.bar);     <span class="comment">//1</span></div><div class="line">        &#125;);</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="comment">// 使用 bind 进行函数绑定</span></div><div class="line"><span class="keyword">var</span> foo = &#123;</div><div class="line">    bar : <span class="number">1</span>,</div><div class="line">    eventBind: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">        $(<span class="string">'.someClass'</span>).on(<span class="string">'click'</span>,<span class="function"><span class="keyword">function</span>(<span class="params">event</span>) </span>&#123;</div><div class="line">            <span class="comment">/* Act on the event */</span></div><div class="line">            <span class="built_in">console</span>.log(<span class="keyword">this</span>.bar);      <span class="comment">//1</span></div><div class="line">        &#125;.bind(<span class="keyword">this</span>));</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;call()、apply()、bind()都是函数对象的一个方法，它们的作用都是改变函数的调用对象。它的使用极大的简化了代码的调用。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="call" scheme="http://blog.xieliqun.com/tags/call/"/>
    
      <category term="apply" scheme="http://blog.xieliqun.com/tags/apply/"/>
    
      <category term="bind" scheme="http://blog.xieliqun.com/tags/bind/"/>
    
  </entry>
  
  <entry>
    <title>AJAX工作原理</title>
    <link href="http://blog.xieliqun.com/2016/08/09/ajax/"/>
    <id>http://blog.xieliqun.com/2016/08/09/ajax/</id>
    <published>2016-08-08T16:22:04.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换，AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下，对网页的某部分进行更新。<br><a id="more"></a></excerpt></p><h2 id=""><a href="#" class="headerlink" title=""></a><the rest="" of="" contents="" |="" 余下全文=""></the></h2><h3 id="一、ajax所包含的技术"><a href="#一、ajax所包含的技术" class="headerlink" title="一、ajax所包含的技术"></a>一、ajax所包含的技术</h3><p> 大家都知道ajax并非一种新的技术，而是几种原有技术的结合体。它由下列技术组合而成。</p><ul><li>使用CSS和XHTML来表示。</li><li>使用DOM模型来交互和动态显示。</li><li>使用XMLHttpRequest来和服务器进行异步通信。</li><li>使用javascript来绑定和调用。</li></ul><p>在上面几中技术中，除了XmlHttpRequest对象以外，其它所有的技术都是基于web标准并且已经得到了广泛使用的，XMLHttpRequest虽然目前还没有被W3C所采纳，但是它已经是一个事实的标准，因为目前几乎所有的主流浏览器都支持它。</p><h3 id="二、怎样创建ajax"><a href="#二、怎样创建ajax" class="headerlink" title="二、怎样创建ajax"></a>二、怎样创建ajax</h3><p>Ajax的原理简单来说通过XmlHttpRequest对象来向服务器发异步请求，从服务器获得数据，然后用javascript来操作DOM而更新页面。这其中最关键的一步就是从服务器获得请求数据。原生创建ajax可分为以下四步。</p><h4 id="1、创建XMLHttpRequest对象"><a href="#1、创建XMLHttpRequest对象" class="headerlink" title="1、创建XMLHttpRequest对象"></a>1、创建XMLHttpRequest对象</h4><p>所有现代浏览器（IE7+、Firefox、Chrome、Safari 以及 Opera）均内建 XMLHttpRequest 对象。<br>创建 XMLHttpRequest 对象的语法：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> xhr = <span class="keyword">new</span> XMLHttpRequest();</div></pre></td></tr></table></figure></p><p>老版本的 Internet Explorer （IE5 和 IE6）使用 ActiveX 对象：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> xhr = <span class="keyword">new</span> ActiveXObject(<span class="string">"Microsoft.XMLHTTP"</span>);</div></pre></td></tr></table></figure></p><p>为了应对所有的现代浏览器，包括 IE5 和 IE6，请检查浏览器是否支持 XMLHttpRequest 对象。如果支持，则创建 XMLHttpRequest 对象。如果不支持，则创建 ActiveXObject ：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> xhr;</div><div class="line"><span class="keyword">if</span>(XMLHttpRequest)&#123;</div><div class="line">xhr = <span class="keyword">new</span> XMLHttpRequest();</div><div class="line">&#125;<span class="keyword">else</span>&#123;</div><div class="line">xhr = <span class="keyword">new</span> ActiveXObject(<span class="string">"Microsoft.XMLHTTP"</span>);</div><div class="line">&#125;</div></pre></td></tr></table></figure></p><h4 id="2、准备请求"><a href="#2、准备请求" class="headerlink" title="2、准备请求"></a>2、准备请求</h4><p>初始化该XMLHttpRequest对象，接受三个参数：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">xhr.open(method,url,<span class="keyword">async</span>);</div></pre></td></tr></table></figure></p><p>第一个参数表示请求类型的字符串，其值可以是GET或者POST。<br>GET请求：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">xhr.open(<span class="string">"GET"</span>,demo.php?name=tsrot&amp;age=<span class="number">24</span>,<span class="literal">true</span>);</div></pre></td></tr></table></figure></p><p>POST请求：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">xhr.open(<span class="string">"POST"</span>,demo.php,<span class="literal">true</span>);</div></pre></td></tr></table></figure></p><p>第二个参数是要作为请求发送目标的URL。<br>第三个参数是true或false，表示请求是以异步还是同步的模式发出。（默认为true，一般不建议为false）</p><ul><li>false：同步模式发出的请求会暂停所有javascript代码的执行，知道服务器获得响应为止，如果浏览器在连接网络时或者在下载文件时出了故障，页面就会一直挂起。</li><li>true：异步模式发出的请求，请求对象收发数据的同时，浏览器可以继续加载页面，执行其他javascript代码</li></ul><h4 id="3、发送请求"><a href="#3、发送请求" class="headerlink" title="3、发送请求"></a>3、发送请求</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">xhr.send();</div></pre></td></tr></table></figure><p>一般情况下，使用Ajax提交的参数多是些简单的字符串，可以直接使用GET方法将要提交的参数写到open方法的url参数中，此时send方法的参数为null或为空。</p><p>GET请求：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">xhr.open(<span class="string">"GET"</span>,demo.php?name=tsrot&amp;age=<span class="number">24</span>,<span class="literal">true</span>);</div><div class="line">xhr.send(<span class="literal">null</span>);</div></pre></td></tr></table></figure></p><p>POST请求：<br>如果需要像 HTML 表单那样 POST 数据，请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">xhr.open(<span class="string">"POST"</span>,demo.php,<span class="literal">true</span>);</div><div class="line">xhr.setRequestHeder(<span class="string">"Content-Type"</span>,<span class="string">"application/x-www-form-urlencoded;charset=UTF-8"</span>);</div><div class="line">xhr.send(<span class="string">"name="</span>+userName+<span class="string">"&amp;age="</span>+userAge);</div></pre></td></tr></table></figure></p><h4 id="4、处理响应"><a href="#4、处理响应" class="headerlink" title="4、处理响应"></a>4、处理响应</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">xhr.onreadystatechange = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">if</span>(xhr.readyState == <span class="number">4</span> &amp;&amp; xhr.status == <span class="number">200</span>)&#123;</div><div class="line"><span class="built_in">console</span>.log(xhr.responseText);</div><div class="line">&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure><p>onreadystatechange 事件：<br>当请求被发送到服务器时，我们需要执行一些基于响应的任务。每当 readyState 改变时，就会触发 onreadystatechange 事件。</p><p>readyState属性：<br>0：已经创建对象，但还没有调用open()方法。<br>1：已经调用open()方法，但还没有发送请求。<br>2：请求已经发送，标题和状态已经收到，并可用。<br>3：接收到来自服务器的响应。<br>4：接收完请求数据，表示已经完成请求。</p><p>status属性：<br>200:”OK”<br>404: 未找到页面</p><p>responseText：获得字符串形式的响应数据<br>responseXML：获得 XML 形式的响应数据<br>返回值一般为json字符串，可以用JSON.parse(xhr.responseText)转化为JSON对象。</p><h4 id="5、完整例子"><a href="#5、完整例子" class="headerlink" title="5、完整例子"></a>5、完整例子</h4><p>demo.html<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> xhr;</div><div class="line"><span class="keyword">if</span>(XMLHttpRequest)&#123;</div><div class="line">xhr = <span class="keyword">new</span> XMLHttpRequest();</div><div class="line">&#125;<span class="keyword">else</span>&#123;</div><div class="line">xhr = <span class="keyword">new</span> ActiveXObject(<span class="string">"Microsoft.XMLHTTP"</span>);</div><div class="line">&#125;;</div><div class="line"></div><div class="line">xhr.open(<span class="string">"GET"</span>,<span class="string">"./data.json"</span>,<span class="literal">true</span>);</div><div class="line">xhr.send();</div><div class="line"></div><div class="line">xhr.onreadystatechange = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">if</span>(xhr.readyState == <span class="number">4</span> &amp;&amp; xhr.status == <span class="number">200</span>)&#123;</div><div class="line"><span class="built_in">console</span>.log(<span class="built_in">JSON</span>.parse(xhr.responseText).name);</div><div class="line">&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p><p>data.json<br><figure class="highlight json"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">&#123;</div><div class="line"><span class="attr">"name"</span>:<span class="string">"tsrot"</span>,</div><div class="line"><span class="attr">"age"</span>:<span class="number">24</span></div><div class="line">&#125;</div></pre></td></tr></table></figure></p><h3 id="三、ajax应用场景"><a href="#三、ajax应用场景" class="headerlink" title="三、ajax应用场景"></a>三、ajax应用场景</h3><ul><li>场景 1. 数据验证</li><li>场景 2. 按需取数据</li><li>场景 3. 自动更新页面</li></ul><h3 id="四、ajax优缺点"><a href="#四、ajax优缺点" class="headerlink" title="四、ajax优缺点"></a>四、ajax优缺点</h3><p>优点：<br>1、页面无刷新，用户体验好。<br>2、异步通信，更加快的响应能力。<br>3、减少冗余请求，减轻了服务器负担<br>4、基于标准化的并被广泛支持的技术，不需要下载插件或者小程序。</p><p>缺点：<br>1、ajax干掉了back按钮，即对浏览器后退机制的破坏。<br>2、存在一定的安全问题。<br>3、对搜索引擎的支持比较弱。<br>4、破坏了程序的异常机制。<br>5、无法用URL直接访问。</p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;AJAX 是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换，AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下，对网页的某部分进行更新。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="ajax" scheme="http://blog.xieliqun.com/tags/ajax/"/>
    
  </entry>
  
  <entry>
    <title>JavaScript闭包（closure）</title>
    <link href="http://blog.xieliqun.com/2016/08/07/javascript-closure/"/>
    <id>http://blog.xieliqun.com/2016/08/07/javascript-closure/</id>
    <published>2016-08-07T01:32:10.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>JavaScript变量分为全局变量和局部变量。Javascript语言的特殊之处，就在于函数内部可以直接读取全局变量，而在函数外部自然无法读取函数内的局部变量。当你需要在函数外调用函数内的局部变量时，此时就要用到一些方法。这个过程就是闭包。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><p>###一、JavaScript为什么会有闭包这种东西<br>JavaScript没有像其它后端语言一样可以直接定义一个变量可供其它外部函数调用的关键字或者方法。于是就产生了闭包这种东西。举个例子：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//内部函数可以访问外部变量</span></div><div class="line"><span class="keyword">var</span> name = <span class="string">"tsrot"</span>;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">f1</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="built_in">console</span>.log(name);</div><div class="line">&#125;</div><div class="line">f1();   <span class="comment">//tsrot</span></div></pre></td></tr></table></figure></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//函数外部无法访问函数内部的局部变量</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">f2</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> name = <span class="string">"tsrot"</span>; <span class="comment">//注意:不用var定义的变量，将会默认为全局变量</span></div><div class="line">&#125;</div><div class="line"><span class="built_in">console</span>.log(name); <span class="comment">//error undefined</span></div></pre></td></tr></table></figure><p>如果是java，一个类的私有属性，可以通过公共的方法来获取，比如：<br><figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Person</span></span>&#123;</div><div class="line">    <span class="keyword">private</span> String name;</div><div class="line">    <span class="function"><span class="keyword">public</span> String <span class="title">getName</span><span class="params">()</span></span>&#123;</div><div class="line">       <span class="keyword">return</span> name;</div><div class="line">    &#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure></p><h3 id="二、闭包的概念"><a href="#二、闭包的概念" class="headerlink" title="二、闭包的概念"></a>二、闭包的概念</h3><p>闭包，官方对闭包的解释是：一个拥有许多变量和绑定了这些变量的环境的表达式（通常是一个函数），因而这些变量也是该表达式的一部分。闭包的特点：</p><ul><li>作为一个函数变量的一个引用，当函数返回时，其处于激活状态。</li><li>一个闭包就是当一个函数返回时，一个没有释放资源的栈区。</li></ul><p>我的理解就是：让函数外部能调用函数内部变量的一个过程就是闭包。举个例子：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">f1</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> name1 = <span class="string">"tsrot"</span>;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">f2</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">return</span> name1;</div><div class="line">&#125;</div><div class="line"><span class="keyword">return</span> f2;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> fun = f1();    <span class="comment">//此时就访问到了name1的值</span></div><div class="line"><span class="built_in">console</span>.log(fun()) <span class="comment">//tsrot</span></div></pre></td></tr></table></figure></p><p>###三、闭包的用途<br>闭包可以用在许多地方。它的最大用处有两个，一个是前面提到的可以读取函数内部的变量，另一个就是让这些变量的值始终保持在内存中。举个例子：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">f1</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> n = <span class="number">0</span>;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">f2</span>(<span class="params"></span>)</span>&#123;</div><div class="line">n++;</div><div class="line"><span class="built_in">console</span>.log(n);</div><div class="line">&#125;</div><div class="line"><span class="keyword">return</span> f2; <span class="comment">//注意此时应该写f2而不是f2()</span></div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> fun = f1();</div><div class="line">fun();  <span class="comment">//1</span></div><div class="line">fun();  <span class="comment">//2  此时n就保存在了内存中</span></div></pre></td></tr></table></figure></p><h3 id="四、闭包的写法"><a href="#四、闭包的写法" class="headerlink" title="四、闭包的写法"></a>四、闭包的写法</h3><h4 id="1、原型调用写法"><a href="#1、原型调用写法" class="headerlink" title="1、原型调用写法"></a>1、原型调用写法</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//在函数内部添加属性，然后在外部调用</span></div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Circle</span>(<span class="params">r</span>) </span>&#123;</div><div class="line"><span class="keyword">this</span>.r = r;</div><div class="line">&#125;</div><div class="line">Circle.PI = <span class="number">3.14159</span>;</div><div class="line">Circle.prototype.area = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line"><span class="keyword">return</span> Circle.PI * <span class="keyword">this</span>.r * <span class="keyword">this</span>.r;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> c = <span class="keyword">new</span> Circle(<span class="number">1.0</span>);</div><div class="line"><span class="built_in">console</span>.log(c.area());</div></pre></td></tr></table></figure><h4 id="2、函数赋值调用写法"><a href="#2、函数赋值调用写法" class="headerlink" title="2、函数赋值调用写法"></a>2、函数赋值调用写法</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> Circle = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</div><div class="line">   <span class="keyword">var</span> obj = <span class="keyword">new</span> <span class="built_in">Object</span>();</div><div class="line">   obj.PI = <span class="number">3.14159</span>;</div><div class="line">   obj.area = <span class="function"><span class="keyword">function</span>(<span class="params">r</span>) </span>&#123;</div><div class="line">       <span class="keyword">return</span> <span class="keyword">this</span>.PI * r * r;</div><div class="line">   &#125;</div><div class="line">   <span class="keyword">return</span> obj;</div><div class="line">&#125;;</div><div class="line"><span class="keyword">var</span> c = <span class="keyword">new</span> Circle();</div><div class="line"><span class="built_in">console</span>.log(c.area(<span class="number">1.0</span>));</div></pre></td></tr></table></figure><h4 id="3、对象赋值调用写法（常用写法）"><a href="#3、对象赋值调用写法（常用写法）" class="headerlink" title="3、对象赋值调用写法（常用写法）"></a>3、对象赋值调用写法（常用写法）</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> Circle = <span class="keyword">new</span> <span class="built_in">Object</span>();</div><div class="line">Circle.PI = <span class="number">3.14159</span>;</div><div class="line">Circle.area = <span class="function"><span class="keyword">function</span>(<span class="params">r</span>) </span>&#123;</div><div class="line">       <span class="keyword">return</span> <span class="keyword">this</span>.PI * r * r;</div><div class="line">&#125;;</div><div class="line">consol.log(Circle.area(<span class="number">1.0</span>));</div></pre></td></tr></table></figure><h4 id="4、声明对象调用写法（比较好的一种写法）"><a href="#4、声明对象调用写法（比较好的一种写法）" class="headerlink" title="4、声明对象调用写法（比较好的一种写法）"></a>4、声明对象调用写法（比较好的一种写法）</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> Circle=&#123;</div><div class="line">PI : <span class="number">3.14159</span>,</div><div class="line">area : <span class="function"><span class="keyword">function</span>(<span class="params">r</span>)</span>&#123;</div><div class="line">         <span class="keyword">return</span> <span class="keyword">this</span>.PI * r * r;</div><div class="line">        &#125;</div><div class="line">&#125;;</div><div class="line"><span class="built_in">console</span>.log(Circle.area(<span class="number">1.0</span>))</div></pre></td></tr></table></figure><h4 id="5、Function对象调用写法"><a href="#5、Function对象调用写法" class="headerlink" title="5、Function对象调用写法"></a>5、Function对象调用写法</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line"><span class="comment">//比较少见的一种写法</span></div><div class="line"><span class="keyword">var</span> Circle = <span class="keyword">new</span> <span class="built_in">Function</span>(<span class="string">"this.PI = 3.14159;this.area = function( r ) &#123;return r*r*this.PI;&#125;"</span>);</div><div class="line"><span class="keyword">var</span> c = <span class="keyword">new</span> Circle();</div><div class="line"><span class="built_in">console</span>.log(c.area(<span class="number">1.0</span>));</div></pre></td></tr></table></figure><h4 id="6、匿名函数调用写法（常用写法）"><a href="#6、匿名函数调用写法（常用写法）" class="headerlink" title="6、匿名函数调用写法（常用写法）"></a>6、匿名函数调用写法（常用写法）</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">(<span class="function"><span class="keyword">function</span>(<span class="params">r</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> PI = <span class="number">3.14159</span>;</div><div class="line"><span class="keyword">var</span> area = PI * r * r;</div><div class="line"><span class="built_in">console</span>.log(area);</div><div class="line">&#125;)(<span class="number">1.0</span>)</div></pre></td></tr></table></figure><h4 id="7、函数返回值写法（常用写法）"><a href="#7、函数返回值写法（常用写法）" class="headerlink" title="7、函数返回值写法（常用写法）"></a>7、函数返回值写法（常用写法）</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">Circle</span>(<span class="params">r</span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> PI = <span class="number">3.14159</span>;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">area</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">return</span> PI * r * r;</div><div class="line">&#125;</div><div class="line"><span class="keyword">return</span> area();</div><div class="line">&#125;</div><div class="line"><span class="built_in">console</span>.log(Circle(<span class="number">1.0</span>));</div></pre></td></tr></table></figure><h3 id="五、思考"><a href="#五、思考" class="headerlink" title="五、思考"></a>五、思考</h3><p>思考1：修改下面函数使之输出数组内元素？<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>];</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;arr.length;i++)&#123;</div><div class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="built_in">console</span>.log(arr[i]);</div><div class="line">&#125;,<span class="number">1000</span>);</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line">test();</div></pre></td></tr></table></figure></p><p>思考2：修改下面代码使之输出它想表达的结果<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div></pre></td><td class="code"><pre><div class="line">&lt;!DOCTYPE html&gt;</div><div class="line">&lt;html lang=<span class="string">"en"</span>&gt;</div><div class="line">&lt;head&gt;</div><div class="line">&lt;meta charset=<span class="string">"UTF-8"</span>&gt;</div><div class="line">&lt;title&gt;Document&lt;<span class="regexp">/title&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>head&gt;</div><div class="line">&lt;body&gt;</div><div class="line">&lt;ul id=<span class="string">"list"</span>&gt;</div><div class="line">&lt;li&gt;<span class="number">1</span>&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;li&gt;2&lt;/</span>li&gt;</div><div class="line">&lt;li&gt;<span class="number">3</span>&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;li&gt;4&lt;/</span>li&gt;</div><div class="line">&lt;li&gt;<span class="number">5</span>&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;/u</span>l&gt;</div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> list = <span class="built_in">document</span>.getElementById(<span class="string">'list'</span>);</div><div class="line"><span class="keyword">var</span> li = list.getElementsByTagName(<span class="string">'li'</span>);</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;li.length;i++)&#123;</div><div class="line">li[i].onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(li[i].innerHTML); <span class="comment">//这里报错</span></div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>body&gt;</div><div class="line">&lt;<span class="regexp">/html&gt;</span></div></pre></td></tr></table></figure></p><p>答案1<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="keyword">var</span> arr = [<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>,<span class="number">5</span>]</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;<span class="number">5</span>;i++)&#123;</div><div class="line">(<span class="function"><span class="keyword">function</span>(<span class="params">i</span>)</span>&#123;</div><div class="line">setTimeout(<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line"><span class="built_in">console</span>.log(arr[i]);</div><div class="line">&#125;,<span class="number">1000</span>);</div><div class="line">&#125;)(i)</div><div class="line">&#125;</div><div class="line">&#125;</div><div class="line">test();</div></pre></td></tr></table></figure></p><p>答案2</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div></pre></td><td class="code"><pre><div class="line">&lt;!DOCTYPE html&gt;</div><div class="line">&lt;html lang=<span class="string">"en"</span>&gt;</div><div class="line">&lt;head&gt;</div><div class="line">&lt;meta charset=<span class="string">"UTF-8"</span>&gt;</div><div class="line">&lt;title&gt;Document&lt;<span class="regexp">/title&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>head&gt;</div><div class="line">&lt;body&gt;</div><div class="line">&lt;ul id=<span class="string">"list"</span>&gt;</div><div class="line">&lt;li&gt;<span class="number">1</span>&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;li&gt;2&lt;/</span>li&gt;</div><div class="line">&lt;li&gt;<span class="number">3</span>&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;li&gt;4&lt;/</span>li&gt;</div><div class="line">&lt;li&gt;<span class="number">5</span>&lt;<span class="regexp">/li&gt;</span></div><div class="line"><span class="regexp">&lt;/u</span>l&gt;</div><div class="line">&lt;script&gt;</div><div class="line"><span class="keyword">var</span> list = <span class="built_in">document</span>.getElementById(<span class="string">'list'</span>);</div><div class="line"><span class="keyword">var</span> li = list.getElementsByTagName(<span class="string">'li'</span>);</div><div class="line"><span class="keyword">for</span>(<span class="keyword">var</span> i=<span class="number">0</span>;i&lt;li.length;i++)&#123;</div><div class="line">(<span class="function"><span class="keyword">function</span>(<span class="params">i</span>)</span>&#123;</div><div class="line">li[i].onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">alert(li[i].innerHTML);</div><div class="line">&#125;</div><div class="line">&#125;)(i)</div><div class="line">&#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div><div class="line"><span class="regexp">&lt;/</span>body&gt;</div><div class="line">&lt;<span class="regexp">/html&gt;</span></div></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;JavaScript变量分为全局变量和局部变量。Javascript语言的特殊之处，就在于函数内部可以直接读取全局变量，而在函数外部自然无法读取函数内的局部变量。当你需要在函数外调用函数内的局部变量时，此时就要用到一些方法。这个过程就是闭包。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="闭包" scheme="http://blog.xieliqun.com/tags/%E9%97%AD%E5%8C%85/"/>
    
  </entry>
  
  <entry>
    <title>javascript重点和难点</title>
    <link href="http://blog.xieliqun.com/2016/07/31/javascript%E9%87%8D%E7%82%B9%E5%92%8C%E9%9A%BE%E7%82%B9/"/>
    <id>http://blog.xieliqun.com/2016/07/31/javascript重点和难点/</id>
    <published>2016-07-30T17:15:34.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>JavaScript 是一种脚本语言，支持函数式编程、闭包、基于原型的继承等高级功能。JavaScript一开始看起来感觉会很容易入门，但是随着使用的深入，你会发现 JavaScript其实很难掌握，有些基本概念让人匪夷所思。<br>以下是我总结的一些JavaScript学习的重点和难点。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><h4 id="1、this指向"><a href="#1、this指向" class="headerlink" title="1、this指向"></a>1、<a href="http://blog.xieliqun.com/2016/07/30/javscript-basics/">this指向</a></h4><h4 id="2、闭包"><a href="#2、闭包" class="headerlink" title="2、闭包"></a>2、<a href="http://blog.xieliqun.com/2016/08/07/javascript-closure/">闭包</a></h4><h4 id="3、ajax"><a href="#3、ajax" class="headerlink" title="3、ajax"></a>3、<a href="http://blog.xieliqun.com/2016/08/08/ajax/">ajax</a></h4><h4 id="4、call和apply"><a href="#4、call和apply" class="headerlink" title="4、call和apply"></a>4、<a href="http://blog.xieliqun.com/2016/08/10/call-apply-bind/">call和apply</a></h4><h4 id="5、事件绑定、事件监听、事件委托"><a href="#5、事件绑定、事件监听、事件委托" class="headerlink" title="5、事件绑定、事件监听、事件委托"></a>5、<a href="http://blog.xieliqun.com/2016/08/12/event-delegate/">事件绑定、事件监听、事件委托</a></h4><h4 id="6、异步编程"><a href="#6、异步编程" class="headerlink" title="6、异步编程"></a>6、异步编程</h4><h4 id="7、原型和原型链"><a href="#7、原型和原型链" class="headerlink" title="7、原型和原型链"></a>7、<a href="http://blog.xieliqun.com/2016/08/20/prototype/">原型和原型链</a></h4><h4 id="8、继承"><a href="#8、继承" class="headerlink" title="8、继承"></a>8、<a href="http://blog.xieliqun.com/2016/03/24/JS%E7%BB%A7%E6%89%BF%E7%9A%84%E5%87%A0%E7%A7%8D%E6%96%B9%E6%96%B9%E6%B3%95/">继承</a></h4><h4 id="9、DOM与BOM"><a href="#9、DOM与BOM" class="headerlink" title="9、DOM与BOM"></a>9、DOM与BOM</h4><h4 id="10、跨域：window-name、postMessage、document-domain、JSONP"><a href="#10、跨域：window-name、postMessage、document-domain、JSONP" class="headerlink" title="10、跨域：window.name、postMessage、document.domain、JSONP"></a>10、跨域：<a href="http://blog.xieliqun.com/2016/08/25/windowName-cross-domain/">window.name</a>、<a href="http://blog.xieliqun.com/2016/08/25/postMessage-cross-domain/">postMessage</a>、<a href="#">document.domain</a>、<a href="#">JSONP</a></h4><h4 id="11、浏览器调试"><a href="#11、浏览器调试" class="headerlink" title="11、浏览器调试"></a>11、浏览器调试</h4>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;JavaScript 是一种脚本语言，支持函数式编程、闭包、基于原型的继承等高级功能。JavaScript一开始看起来感觉会很容易入门，但是随着使用的深入，你会发现 JavaScript其实很难掌握，有些基本概念让人匪夷所思。&lt;br&gt;以下是我总结的一些JavaScript学习的重点和难点。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="个人笔记" scheme="http://blog.xieliqun.com/tags/%E4%B8%AA%E4%BA%BA%E7%AC%94%E8%AE%B0/"/>
    
  </entry>
  
  <entry>
    <title>javscript中this指向</title>
    <link href="http://blog.xieliqun.com/2016/07/31/javscript-basics/"/>
    <id>http://blog.xieliqun.com/2016/07/31/javscript-basics/</id>
    <published>2016-07-30T17:11:04.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>对于JavaScript初学者来说，this指针的指向问题一直是很混乱的问题。在不同的场景下，this会化身不同的对象。有一种观点认为，只有正确掌握了 JavaScript 中的 this 关键字，才算是迈入了 JavaScript 这门语言的门槛。在主流的面向对象的语言中（例如Java,C#等)，this 含义是明确且具体的，即指向当前对象。一般在编译期绑定。而 JavaScript 中this 在运行期进行绑定的，这是JavaScript 中this 关键字具备多重含义的本质原因。<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""><br>随着函数使用场合的不同，this的值会发生变化。但是有一个总的原则，那就是this指的是，<strong>调用函数的那个对象</strong>。</the></p><hr><h2 id="1、-指向window的隐式指向"><a href="#1、-指向window的隐式指向" class="headerlink" title="1、    指向window的隐式指向"></a>1、    指向window的隐式指向</h2><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="keyword">this</span>.nama = <span class="string">"tsrot"</span>;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">"hello "</span> + <span class="keyword">this</span>.name);</div><div class="line">&#125;</div><div class="line">sayHello()       <span class="comment">//hello tsrot</span></div></pre></td></tr></table></figure><p>此时的变量name相当于window.name，因为调用sayHello函数的对象为window，相当于window.sayHello()。和下面两种情况是一样的：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> name = <span class="string">"tsrot"</span>;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">"hello "</span> + <span class="keyword">this</span>.name);</div><div class="line">&#125;</div><div class="line">sayHello();        <span class="comment">//hello tsrot</span></div></pre></td></tr></table></figure></p><p>下面的name相当于在window下赋值了两次，谁后面执行就取谁。如果把var name = “xieliqun”放到sayHello（）后面，此时输出的就是 hello xieliqun。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> name = <span class="string">"xieliqun"</span>;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="keyword">this</span>.name = <span class="string">"tsrot"</span>;</div><div class="line">&#125;</div><div class="line">sayHello();</div><div class="line"><span class="built_in">console</span>.log(<span class="string">"hello "</span> + <span class="keyword">this</span>.name); <span class="comment">//hello tsrot</span></div></pre></td></tr></table></figure></p><p><em>注：当函数在DOM上调用时，未传入this，此时，this也指向window。当传入this时，this指向当前DOM input</em>，例如下面情况：<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> onclick=<span class="string">"sayHello()"</span>&gt;</div><div class="line">&lt;script&gt;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">"hello "</span> + <span class="keyword">this</span>.tagName);   <span class="comment">//hello undefined</span></div><div class="line">    &#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">&lt;input type=<span class="string">"button"</span> value=<span class="string">"click me"</span> onclick=<span class="string">"sayHello(this.tagName)"</span>&gt;</div><div class="line">&lt;script&gt;</div><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params">tagName</span>)</span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">"hello "</span> + tagName);   <span class="comment">//hello INPUT</span></div><div class="line">    &#125;</div><div class="line">&lt;<span class="regexp">/script&gt;</span></div></pre></td></tr></table></figure><hr><h2 id="2、-指向当前对象的显式调用"><a href="#2、-指向当前对象的显式调用" class="headerlink" title="2、    指向当前对象的显式调用"></a>2、    指向当前对象的显式调用</h2><h3 id="（1）、作为对象方法的调用"><a href="#（1）、作为对象方法的调用" class="headerlink" title="（1）、作为对象方法的调用"></a>（1）、作为对象方法的调用</h3><p>函数还可以作为某个对象的方法调用，这时this就指这个上级对象。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">"hello "</span> + <span class="keyword">this</span>.name);</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> o = &#123;&#125;;</div><div class="line">o.name = <span class="string">"tsrot"</span>;</div><div class="line">o.hello = sayHello;</div><div class="line">o.hello();  <span class="comment">//hello tsrot</span></div></pre></td></tr></table></figure></p><h3 id="（2）、作为构造函数调用"><a href="#（2）、作为构造函数调用" class="headerlink" title="（2）、作为构造函数调用"></a>（2）、作为构造函数调用</h3><p>所谓构造函数，就是通过这个函数生成一个新对象（object）。这时，this就指这个新对象。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="keyword">this</span>.name = <span class="string">"tsrot"</span>;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> o = <span class="keyword">new</span> sayHello();</div><div class="line"><span class="built_in">console</span>.log(<span class="string">"hello "</span> + o.name);  <span class="comment">//hello tsrot</span></div></pre></td></tr></table></figure></p><hr><h2 id="3、-指向当前对象的隐式调用"><a href="#3、-指向当前对象的隐式调用" class="headerlink" title="3、    指向当前对象的隐式调用"></a>3、    指向当前对象的隐式调用</h2><h3 id="（1）-call、apply调用"><a href="#（1）-call、apply调用" class="headerlink" title="（1）    call、apply调用"></a>（1）    call、apply调用</h3><p>call（）、apply()都是函数对象的一个方法，它们的作用是改变函数的调用对象，它们的第一个参数就表示改变后的调用这个函数的对象。因此，this指的就是这第一个参数。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">sayHello</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="built_in">console</span>.log(<span class="string">"hello "</span> + <span class="keyword">this</span>.name;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> o = &#123;&#125;;</div><div class="line">o.name = <span class="string">"tsrot"</span>;</div><div class="line">o.hello = sayHello;</div><div class="line">o.hello.apply();   <span class="comment">//hello</span></div></pre></td></tr></table></figure></p><p>apply()的参数为空时，默认调用全局对象。因此，这时的运行结果为0，证明this指的是全局对象。<br>如果把最后一行代码修改为<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// o.hello.apply();    //hello</span></div><div class="line">o.hello.apply();      <span class="comment">//hello tsrot</span></div></pre></td></tr></table></figure></p><p>此时this就指向对象o了。</p><h3 id="（2）-原生Function方法bind（）调用"><a href="#（2）-原生Function方法bind（）调用" class="headerlink" title="（2）    原生Function方法bind（）调用"></a>（2）    原生Function方法bind（）调用</h3><p>很多人不知道原生js也有bind（）方法，一直以为bind（）的方法只有jQuery有，我也是最近看别人博客知道的。其实原生的bind和jQuery的bind是不同的，原生的bind相当于apply和call。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> person = &#123;</div><div class="line">    name:<span class="string">"tsrot"</span>,</div><div class="line">    sayHello:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">        <span class="built_in">console</span>.log(<span class="string">"你好，我是"</span>+<span class="keyword">this</span>.name);</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> boundFunc = person.sayHello.bind(person,person.sayHello);</div><div class="line">setTimeout(boundFunc,<span class="number">5000</span>);   <span class="comment">//5秒后输出 你好，我是tsrot</span></div></pre></td></tr></table></figure></p><p>下图代码中person.sayHello,相当于在window.person.sayHello，所以this指向window。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> person = &#123;</div><div class="line">    name:<span class="string">"tsrot"</span>,</div><div class="line">    sayHello:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">        <span class="built_in">console</span>.log(<span class="string">"你好，我是"</span>+<span class="keyword">this</span>.name);</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"><span class="comment">//var boundFunc = person.sayHello.bind(person,person.sayHello);</span></div><div class="line">setTimeout(person.sayHello,<span class="number">5000</span>);   <span class="comment">//5秒后输出 你好，我是</span></div></pre></td></tr></table></figure></p><p>用apply和call调用时，函数将立即执行<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> person = &#123;</div><div class="line">    name:<span class="string">"tsrot"</span>,</div><div class="line">    sayHello:<span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</div><div class="line">        <span class="built_in">console</span>.log(<span class="string">"你好，我是"</span>+<span class="keyword">this</span>.name);</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> boundFunc = person.sayHello.apply(person,person.sayHello);</div><div class="line">setTimeout(boundFunc,<span class="number">5000</span>);   <span class="comment">//立即输出 你好，我是tsrot</span></div></pre></td></tr></table></figure></p><hr><h2 id="4、-当this在构造函数有return时"><a href="#4、-当this在构造函数有return时" class="headerlink" title="4、    当this在构造函数有return时"></a>4、    当this在构造函数有return时</h2><p>如果返回值是一个对象，那么this指向的就是那个返回的对象，如果返回值不是一个对象那么this还是指向函数的实例。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="keyword">this</span>.name = <span class="string">"tsrot"</span>;</div><div class="line">    <span class="keyword">return</span> &#123;&#125;;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> o = <span class="keyword">new</span> fn();</div><div class="line"><span class="built_in">console</span>.log(o.name);  <span class="comment">//undefined</span></div></pre></td></tr></table></figure></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="keyword">this</span>.name = <span class="string">"tsrot"</span>;</div><div class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> o = <span class="keyword">new</span> fn();</div><div class="line"><span class="built_in">console</span>.log(o.name);  <span class="comment">//undefined</span></div></pre></td></tr></table></figure><p>当return null和undefined时<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="keyword">this</span>.name = <span class="string">"tsrot"</span>;</div><div class="line">    <span class="keyword">return</span> <span class="literal">null</span>;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> o = <span class="keyword">new</span> fn();</div><div class="line"><span class="built_in">console</span>.log(o.name);  <span class="comment">//tsrot</span></div></pre></td></tr></table></figure></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">function</span> <span class="title">fn</span>(<span class="params"></span>)</span>&#123;</div><div class="line">    <span class="keyword">this</span>.name = <span class="string">"tsrot"</span>;</div><div class="line">    <span class="keyword">return</span> <span class="literal">undefined</span>;</div><div class="line">&#125;</div><div class="line"><span class="keyword">var</span> o = <span class="keyword">new</span> fn();</div><div class="line"><span class="built_in">console</span>.log(o.name);  <span class="comment">//tsrot</span></div></pre></td></tr></table></figure>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;对于JavaScript初学者来说，this指针的指向问题一直是很混乱的问题。在不同的场景下，this会化身不同的对象。有一种观点认为，只有正确掌握了 JavaScript 中的 this 关键字，才算是迈入了 JavaScript 这门语言的门槛。在主流的面向对象的语言中（例如Java,C#等)，this 含义是明确且具体的，即指向当前对象。一般在编译期绑定。而 JavaScript 中this 在运行期进行绑定的，这是JavaScript 中this 关键字具备多重含义的本质原因。&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript" scheme="http://blog.xieliqun.com/categories/JavaScript/"/>
    
    
      <category term="this指向" scheme="http://blog.xieliqun.com/tags/this%E6%8C%87%E5%90%91/"/>
    
  </entry>
  
  <entry>
    <title>我的sublime插件</title>
    <link href="http://blog.xieliqun.com/2016/07/24/%E6%88%91%E7%9A%84sublime%E6%8F%92%E4%BB%B6/"/>
    <id>http://blog.xieliqun.com/2016/07/24/我的sublime插件/</id>
    <published>2016-07-24T02:54:26.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>备份一下我的sublime插件<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""></the></p><h4 id="1、AdvancedNewFile-快速新建文件"><a href="#1、AdvancedNewFile-快速新建文件" class="headerlink" title="1、AdvancedNewFile   (快速新建文件)"></a>1、AdvancedNewFile   (快速新建文件)</h4><h4 id="2、AngularJS"><a href="#2、AngularJS" class="headerlink" title="2、AngularJS"></a>2、AngularJS</h4><h4 id="3、Emmet"><a href="#3、Emmet" class="headerlink" title="3、Emmet"></a>3、Emmet</h4><h4 id="4、Git"><a href="#4、Git" class="headerlink" title="4、Git"></a>4、Git</h4><h4 id="5、JsFormat"><a href="#5、JsFormat" class="headerlink" title="5、JsFormat"></a>5、JsFormat</h4><h4 id="6、Nodejs"><a href="#6、Nodejs" class="headerlink" title="6、Nodejs"></a>6、Nodejs</h4><h4 id="7、MarkdownEditing"><a href="#7、MarkdownEditing" class="headerlink" title="7、MarkdownEditing"></a>7、MarkdownEditing</h4><h4 id="8、Markdown-Preview"><a href="#8、Markdown-Preview" class="headerlink" title="8、Markdown Preview"></a>8、Markdown Preview</h4><h4 id="9、JsFormat"><a href="#9、JsFormat" class="headerlink" title="9、JsFormat"></a>9、JsFormat</h4>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;备份一下我的sublime插件&lt;br&gt;
    
    </summary>
    
      <category term="IDE" scheme="http://blog.xieliqun.com/categories/IDE/"/>
    
    
      <category term="sublime插件" scheme="http://blog.xieliqun.com/tags/sublime%E6%8F%92%E4%BB%B6/"/>
    
  </entry>
  
  <entry>
    <title>ionic初学者文档</title>
    <link href="http://blog.xieliqun.com/2016/07/17/ionic%E5%88%9D%E5%AD%A6%E8%80%85%E6%96%87%E6%A1%A3/"/>
    <id>http://blog.xieliqun.com/2016/07/17/ionic初学者文档/</id>
    <published>2016-07-17T04:07:06.000Z</published>
    <updated>2017-10-01T07:04:53.000Z</updated>
    
    <content type="html"><![CDATA[<p><excerpt in="" index="" |="" 首页摘要=""><br>本以为按照官网的getting started 就能很快的生成一个WEB APP，看来我是想多了，里<br>面的坑只有经历过的人才知道，这真是坑死人不偿命啊！本着极客精神，经过一天时间，终<br>于把getting started 跑通了，接下来就简单多了。（注：1、先安装翻墙软件吧，否则过程好<br>久（推荐xx-net，github 上自己搜）。2、没有极客精神的人慎入）<br><a id="more"></a></excerpt></p><p><the rest="" of="" contents="" |="" 余下全文=""><br>下面我简单介绍一下我的入坑经历：<br>1、这步还算顺利（前提是你安装了nodeJS，过程可能有点慢，看网络环境和人品了。如果<br>长时间停留在某个地方，Ctrl+C 暂停它，再运行一次）<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ npm install -g cordova ionic</div></pre></td></tr></table></figure></the></p><p>2、这步也还算顺利，就是有点慢。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ ionic start myApp tabs</div></pre></td></tr></table></figure></p><p>如果你仅仅作为一个前端开发者，走到这步就可以在browser 运行起来了，但作为一个极<br>客，怎能止于这步。<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">cd</span> myApp</div><div class="line">$ ionic serve</div></pre></td></tr></table></figure></p><p>3、接下来就进入大坑了<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">$ <span class="built_in">cd</span> myApp</div><div class="line">$ ionic platform add android //这里是个大坑，先安装Android SDK</div><div class="line">$ ionic build android $ ionic <span class="built_in">emulate</span> android</div></pre></td></tr></table></figure></p><p>4、接下来就是漫长且苦逼的填坑经历了。<br>…………………………………………………………………</p><h3 id="接下来看我的github的吧，懒得写了！！！"><a href="#接下来看我的github的吧，懒得写了！！！" class="headerlink" title="接下来看我的github的吧，懒得写了！！！"></a>接下来看我的github的吧，懒得写了！！！</h3><p>github地址：<a href="https://github.com/tsrot/ionic-environment-configuration" target="_blank" rel="external">ionic初学者文档</a><br>或者你可以直接clone<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">git <span class="built_in">clone</span> https://github.com/tsrot/ionic-environment-configuration.git</div></pre></td></tr></table></figure></p>]]></content>
    
    <summary type="html">
    
      &lt;p&gt;&lt;excerpt in=&quot;&quot; index=&quot;&quot; |=&quot;&quot; 首页摘要=&quot;&quot;&gt;&lt;br&gt;本以为按照官网的getting started 就能很快的生成一个WEB APP，看来我是想多了，里&lt;br&gt;面的坑只有经历过的人才知道，这真是坑死人不偿命啊！本着极客精神，经过一天时间，终&lt;br&gt;于把getting started 跑通了，接下来就简单多了。（注：1、先安装翻墙软件吧，否则过程好&lt;br&gt;久（推荐xx-net，github 上自己搜）。2、没有极客精神的人慎入）&lt;br&gt;
    
    </summary>
    
      <category term="JavaScript框架" scheme="http://blog.xieliqun.com/categories/JavaScript%E6%A1%86%E6%9E%B6/"/>
    
    
      <category term="移动端" scheme="http://blog.xieliqun.com/tags/%E7%A7%BB%E5%8A%A8%E7%AB%AF/"/>
    
      <category term="ionic" scheme="http://blog.xieliqun.com/tags/ionic/"/>
    
  </entry>
  
</feed>
