JavaScript使用严格模式(Strict Mode)

2014-06-07 JavaScript

ECMAScript5中引入的严格模式,通过让JavaScript运行环境对一些开发过程中最常见和不易发现的错误做出和当前不同的处理,来让开发者拥有一个”更好”的JavaScript语言。很长一段时间内,由于只有Firefox支持严格模式,我曾对严格模式表示怀疑。但到了今天,所有主流的浏览器都在他们的最新版本中支持了严格模式(包括IE10,Opera12和Android4,IOS5)是时候开始使用严格模式了。

#严格模式能起到什么作用? 严格模式为JavaScript引入了很多变化,我把他们分为两类(明显的和细微的)。细微改进的目标是修复当前JavaScript中的一些细节问题,对于这些问题我不在这里进行深入介绍;如果你有兴趣,请阅读Dmitry Soshnikov撰写的精彩文档ECMA-262-5 in Detail Chapter 2 Strict Mode。 我在这里主要介绍严格模式引入的明显变化,那些在你使用严格模式前应该知道的概念和那些对你帮助最大的改变。

在开始学习具体特性前,请记住严格模式的一大目标是让你能更快更方便的调试。运行环境在发现问题时显性的抛出错误比默不做声的失败或怪异行事(未开启严格模式的JavaScript运行环境经常这样)要好。严格模式会抛出更多错误,但这是好事,因为这些错误会唤起你注意并修复很多以前很难被发现的潜在问题。

##去除with关键词 首先,严格模式中去除了with语句,包含with语句的代码在严格模式中会抛出异常。所以使用严格模式的第一步:确保你的代码中没有使用with。

// 在严格模式中以下JavaScript代码会抛出错误
with (location) {
    alert(href);
}

##防止意外为全局变量赋值 其次,局部变量在赋值前必须先进行申明。在启用严格模式之前,为一个未申明的局部变量复制时会自动创建一个同名全局变量。这是Javacript程序中最容易出现的错误之一, 在严格模式中尝试这么做时会有显性的异常抛出。

// 严格模式下会抛出异常
(function() {
    someUndeclaredVar = "foo";
}());

##函数中的this不再默认指向全局 严格模式中另一个重要的变化是函数中未被定义或为空( null or undefined)的this不在默认指向全局环境(global)。这会造成一些依赖函数中默认this行为的代码执行出错,例如:

window.color = "red";
function sayColor() {
    alert(this.color);
}
// 在strict模式中会报错, 如果不在严格模式中则提示 “red"
sayColor();
// 在strict模式中会报错, 如果不在严格模式中则提示 “red"
sayColor.call(null);

this在被赋值之前会一直保持为undefined,这意味着当一个构造函数在执行时,如果之前没有明确的new关键词,会抛出异常。

function Person(name) {
    this.name = name;
}
//在严格模式中会报错
var me = Person("Nicholas"); 在上面的代码中,Person构造函数运行时因为之前没有new,函数中的this会保留为undefined, 由于你不能为undefined设置属性,上面的代码会抛出错误。 在非strict模式环境中,没有被复制的this会默认指向window全局变量,运行的结果将是意外的为window全局变量设置name属性。

##防止重名 当编写大量代码时,对象属性和函数参数很容易一不小心被设置成一个重复的名字。严格模式在这种情况下会显性的抛出错误

//重复的变量名,在严格模式下会报错
function doSomething(value1, value2, value1) {
    //code
}

//重复的对象属性名,在严格模式下会报错:
var object = {
    foo: "bar",
    foo: "baz"
};

以上的代码在严格模式中都会被认为是语法错误而在执行前就让你能得到提示。

##安全的 eval() 虽然eval()语句最终没有被移除,但在严格模式中仍然对它进行了一些改进。最大的改变是在eval()中执行的变量和函数申明不会直接在当前作用域中创建相应变量或函数,例如:

(function() {
    eval("var x = 10;");
    // 非严格模式中,alert 10
    // 严格模式中则因x未被定义而抛出异常,
    alert(x);
}());

任何在eval()执行过程中创建的变量或者函数保留在eval()中。但你能明确的从eval()语句的返回值来获取eval()中的执行结果,例如:

(function() {
    var result = eval("var x = 10, y = 20; x + y");
    // 在strict或非strict模式中都能正确的运行余下的语句.(resulst为30)
    alert(result);
}());

##对只读属性修改时抛出异常 ECMAScript5中还引入为对象的特定属性设为只读,或让整个对象不可修改的能力。 但在非严格模式中,尝试修改一个只读属性只会默不做声的失败。 在你和一些浏览器原生API打交道过程中,你很可能遇到这种情况。严格模式会在这种情况下明确的抛出异常,提醒你修改这个属性是不被允许的。

var person = {};
Object.defineProperty(person, "name" {
    writable: false,
    value: "Nicholas"
});
// 在非严格模式时,沉默的失败,在严格模式则抛出异常.
person.name = "John"; 上面的例子中,name属性被设为只读,非严格模式中执行对name属性的修改不会引发报错,但修改不会成功。但严格模式则会明确的抛出异常。

NOTE: 强烈建议你在使用任何ECMAScript属性特性指定时开启严格模式。

##如何使用? 在现代浏览器中开启严格模式非常容易,只需要在JavaScript代码中出现以下指令即可

"use strict";

虽然看上去上面的代码仅仅只是未赋予某个变量的字符串,它实际上起到指示JavaScript引擎切换到严格模式的作用(不支持严格模式的浏览器会忽略以上代码,不会对后续的执行产生任何影响)。虽然你能把这个指令作用到全局或某个函数中,但这里还是要提醒,不要在全局环境下启用严格模式。

// 请不要这么使用
"use strict";
function doSomething() {
    // 这部分代码会运行于严格模式
}
function doSomethingElse() {
    // 这部分代码也会运行于严格模式
} 虽然上面的代码看起来不算一个大问题。但当你不负责维护页面中引入的全部代码时,这样使用strict模式会让你面临由于第三方代码没有为严格模式做好准备而引发的问题。 因此,最好把开启严格模式的指令作用于函数中,例如:

function doSomething() {
    "use strict";
    // 这个函数中的代码将会运行于严格模式
}
function doSomethingElse() {
    // 这个函数中代码不会运行于严格模式
}

如果你想让严格模式在不止一个函数中开启,请使用立即执行函数表达式

(immediately-invoked function expression ,IIFE):
(function() {
    "use strict";
    function doSomething() {
        // 这个函数运行于严格模式
    }
    function doSomethingElse() {
        // 这个函数同样运行于严格模式
    }
}());

#结论 我强烈建议你从现在开始就启用JavaScript严格模式,它能帮你发现代码中未曾注意到的错误。不要在全局环境中启用,但你能尽量多的使用IIFE(立即执行函数表达式)来把严格模式作用到多个函数范围内。一开始,你会遇到之前未曾碰到过的错误提示,这是正常的。当启用严格模式后,请确保在支持的浏览器中做了测试,以发现新的潜在问题。一定不要仅仅在代码中添加一行”use strict”就假定余下的代码能正常工作。最后,请在严格模式下开始编写更好的代码。

#注:

这里有各款浏览器对严格模式支持情况的一个汇总。

可以在这个页面对当前浏览器的严格模式支持度进行测试。

参考:


SVG Viewport和View Box

2014-06-03 SVG

SVG Viewport和View Box用来设置图像的可见部分的尺寸。

##Viewport(视口) Viewport:视口,视觉窗口,是SVG图像的可见区域。SVG图像逻辑上是能显示你想要的宽和高,但实际上同一时间仅图像的某一部分是可见的。该可见的区域被称为Viewport。

您可以通过<svg>元素的widthheight指定使用的Viewport宽度和高度的下面是一个例子:

<svg width="500" height="300"></svg>

这例子定义了一个Viewport,500个单位宽和300个单位高。

##坐标单位 如果你不指定任何内部宽度和高度属性的单位,单位都假定为像素。即,宽度500表示500个像素的宽度。

除了像素,还可以使用下面的单位:

单位 描述
em 默认字体大小 ,通常是一个字符高度
ex x字符的高度
px 像素
pt 点(一英寸的1/72)
pc 派卡(一英寸的1/6)
cm 厘米
mm 毫米
in 英寸

在<svg>元素里面设置单位只会影响的<svg>的大小(即Viewport)。在SVG图像中显示的SVG图形的大小由你对每个图形设置的单位决定。如果没有指定单位,各单位将默认为像素。

下面是一个例子:

<svg width="10cm" height="10cm">
    <rect x="50" y="100" width="50" height="50"
          style="stroke: #000000; fill: none;"/>
    <rect x="100" y="100" width="50mm" height="50mm"
          style="stroke: #000000; fill: none;" />
</svg>

该<svg>图像有其单位设置为厘米。两个<rect>元素都有自己的单位设置。一个使用像素(没有单位明确设定),另一个使用毫米。

这里是所得到的图象,右边的(单位毫米)大于左边(单位像素)。

##View Box 您可以重新在<svg>元素内部定义没有单位的坐标,通过viewBox属性来实现。下面是一个例子:

<svg width="500" height="200" viewBox="0 0 50 20" style="border: 1px solid #234567;">
    <rect x="20" y="10" width="10" height="5"
          style="stroke: #000000; fill:none;"/>
</svg>

此示例创建一个<svg>为500像素宽和200像素高,宽度元素的的viewBox属性包含四个坐标。这些坐标就定义了<svg>的viewBox属性。

在这种情况下,View Box跨度从0,0到50,20。这意味着,500 x 200像素 <svg>元素内部使用一个坐标系,它从0,0 到50,20。换言之,图形中使用的坐标,每1个单位,在<svg>对应于宽度500/50 = 10个像素,而在高200/20 = 10个像素。这就是为什么x轴为20及y轴为10的位置的矩形是真正位于(200,100),其宽度(10)和高度(5)对应于100个像素和50个像素。

另一种方式来解释它,viewBox属性的前两个坐标定义的是<svg>左上角的用户坐标,后两个坐标定义的是<svg>右下角的用户坐标。该<svg>内部的空间被解释为从左上角坐标到右下角坐标跨越。

这里是所得到的图象:

注意<rect>里面的所有坐标元素1个单位就代表10像素。

##preserveAspectRatio保持宽高比 如果Viewport和View Box不具有相同的宽高比(宽度与高度之比),您需要指定SVG显示器(例如浏览器)如何显示SVG图像。使用<svg>的preserveAspectRatio属性。

该preserveAspectRatio属性需要用空格分隔的两个值。第一个值将告诉您View Box如何在Viewport中对齐。这个值本身就是两部分组成。第二个值将告诉您宽高比如何将被保留(如果有的话)。

第一个值指定的对齐由两部分组成。第一部分指定的x对齐和第二部分指定的y对齐。这里是x轴和y取向的值的列表:

描述
xMin 对齐View Box最小x轴的值与Viewport的左边缘。
xMid 对齐View Box的x轴的中心与Viewport的中心x轴坐标。
xMax 对齐View Box最大x轴的值与Viewport的右边缘。
YMin 对齐View Box最小y轴的值与Viewport的顶部边缘。
YMid 对齐View Box的y轴的中心与Viewport的中心y轴坐标。
YMin 对齐View Box最大y轴的值与Viewport的底部边缘。

这里有两个例子:

xMaxYMax

xMidYMid

在preserveAspectRatio第二部分属性值可以采取三种不同的值:

描述
meet 保持宽高比和比例视图框,以适应内视口。
slice 保留宽高比,任何不适合Viewport宽高比的图像的会被切掉。
none 不保留宽高比。缩放图像以View Box充满完全适应Viewport。比例会被扭曲。

在第二部分preserveAspectRatio属性值附加到第一部分,以空格分隔。这里有两个例子:

preserveAspectRatio="xMidYMid meet"

preserveAspectRatio="xMinYMin slice"

下面的实施例都具有宽度为500,高度为75和的viewBox属性设为0 0 250 75。这意味着,沿x轴的每个坐标单元将对应于2个像素,而是沿着Y轴的每个坐标单位只对应1个像素。在x轴缩放比为500/250=2 ,y轴的缩放比为75/75=1。这可能会导致一个扭曲,但我们会在下面的例子查看如何设置各种preserveAspectRatio。

查看例子



SVG <marker>创建箭头

2014-05-29 SVG

SVG 中<line>并没有箭头,可以通过<marker>进行扩展。

先定义一个箭头

<defs>
    <marker id="markerArrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
        <path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
    </marker>
</defs>

其中orient="auto"设置箭头的方向为自动适应线条的方向。

而后,画line ,line的marker-end引用上面定义好的markerArrow即可

<line x1="0" y1="0" x2="100" y2="50"  stroke="red" stroke-width="1" marker-end="url(#markerArrow)"  />

也可以应用在path中, 效果如下:

完整代码如下:

<svg width="500" height="100">
<defs>
    <marker id="markerCircle" markerWidth="8" markerHeight="8" refx="5" refy="5">
        <circle cx="5" cy="5" r="3" style="stroke: none; fill:#000000;"/>
    </marker>

    <marker id="markerArrow" markerWidth="13" markerHeight="13" refx="2" refy="6" orient="auto">
        <path d="M2,2 L2,11 L10,6 L2,2" style="fill: #000000;" />
    </marker>
</defs>
<line x1="0" y1="0" x2="100" y2="50"  stroke="red" stroke-width="1" marker-end="url(#markerArrow)"  />
<path d="M100,10 L150,10 L150,60"
      style="stroke: #6666ff; stroke-width: 1px; fill: none;
                   marker-start: url(#markerCircle);
                   marker-mid:url(#arrow);
                   marker-end: url(#markerArrow) "
        />
</svg>

SVG实例之中国地图

2014-05-27 SVG

SVG 做地图具有可以任意比例放大缩小不失真的优点。本例基于d3.js的svg制作。

地图数据用GeoJSON存储。GeoJSON 是基于JSON 的、为Web 应用而编码地理数据的一个标准。实际上,GeoJSON 并不是另一种格式,而只是JSON 非常特定的一种使用方法。

网上有很多免费的GeoJSON下载,本例子中国地图GeoJSon 可以从本例源码 下载

###1.获取d3 在项目中引入即可, <script src="http://d3js.org/d3.v3.min.js"></script>

###2.创建svg var width = 960, height = 500; var svg = d3.select(“body”) .append(“svg”) .attr(“width”, width) .attr(“height”, height); ###3.创建投影(projection) var projection = d3.geo.mercator().translate([width / 2, height / 2]).center([105, 38]).scale(550);

###4.创建path var path = d3.geo.path().projection(projection);

###5. 解析json d3.json(“china.geo.json”, function(json) {

    svg.selectAll("path")
            .data(json.features)
            .enter()
            .append("path")
            .attr("d", path)
            .on('mouseover', function(data) {
                d3.select(this).attr('fill', 'rgba(2,2,139,0.61)');

                //创建显示tooltip用的矩形
                svg.append("rect")
                        .attr("id", "tooltip1")
                        .attr("x", 50)
                        .attr("y",50)
                        .attr("width",140)
                        .attr("height",130)
                        .attr("stroke","black")
                        .attr("fill","none")
                ;

                //创建显示tooltip文本
                svg.append("text")
                        .attr("id", "tooltip2")
                        .attr("x", 100)
                        .attr("y", 100)
                        .attr("text-anchor", "middle")
                        .attr("font-family", "sans-serif")
                        .attr("font-size", "11px")
                        .attr("font-weight", "bold")
                        .attr("fill", "black")
                        .text(data.properties.name);
            })
            .on('mouseout', function(data) {
                d3.select(this).attr('fill', 'rgba(128,124,139,0.61)');
                //Remove the tooltip
                d3.select("#tooltip1").remove();
                d3.select("#tooltip2").remove();
            })
            .attr('fill', 'rgba(128,124,139,0.61)')
            .attr('stroke', 'rgba(255,255,255,1)')
            .attr('stroke-width', 1)
    ;
});

演示效果:

完整源码下载

中国地图GeoJSON

查看例子


WebStorm配置svn共享、检出项目

2014-05-26 Web

##安装svn 1下载SlikSVN

2安装

我的是在D:\Program Files\SlikSvn目录下

3.在WebStorm中配置

file->settings->Version Contorl->subversion->with conmand line client 设置成你的D:\Program Files\SlikSvn\bin\svn.exe

##svn共享项目 1.share Project share Project

2.select target select target

3.验证 验证

4.确认 确认

##svn检出项目 1.选择项目 选择项目1

选择项目2

2.检出 检出1

检出2

##相关问题的解决 如果遇到如下错误 “Cannot load supported formats: Cannot run program ‘svn’: CreateProcess error=2, ” 错误 请回到最上面,进行“安装svn”这步骤


SVG实例之电力开关

2014-05-24 SVG

<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"  width="400" height="200" >
<script> 
function lineGClick(evt) {

var lineA = document.getElementById("lineA");
if( lineA.getAttribute("display")=="none"){

lineA.setAttribute("display","#000000");
line2.setAttribute("display","none");

}else{
lineA.setAttribute("display","none");
line2.setAttribute("display","#000000");
}
}
 </script>
<defs>
 <g id="lineG1" >
  <line id="line1" fill="none" stroke="#000000" stroke-width="4" x1="10" y1="10" x2="10" y2="40"/>
  <line id="lineA" fill="none" display="none" stroke="#000000" stroke-width="4" x1="10" y1="40" x2="10" y2="70"/>
  <line id="line2" fill="none" stroke="#000000" stroke-width="4" x1="10" y1="40" x2="35" y2="60"/>
  <line id="lineB" fill="none" stroke="#000000" stroke-width="4" x1="10" y1="70" x2="10" y2="100"/>
 </g>
</defs>
 
<text x="10" y="20" fill="red">一个SVG电力开关的例子。点击开关,进行状态转换</text>
<use x="10" y="30" xlink:href="#lineG1" onclick="lineGClick(evt)"/>
<a xlink:href="http://www.waylau.com" target="_blank">
<text x="10" y="180" fill="red">欢迎访问wwww.waylau.com</text>
  </a>
</svg>

效果:

解释:

defs标签定义了可以重复利用的组件

use引用了defs所定义的组件,其中onclick监听了鼠标点击事件


测试下几个网络相册

2014-05-23 Web

##1.百度相册外链分享

SQLServer.exe 优点:国内站,速度快,可以批量上传

缺点:右下角会有水印,很是不爽

##2.试下Photobucket 免费,无水印

 photo 4E9280547F514E0D5728A80A14E0A5E027684539F56E0_zpsc7c53c1a.jpg 优点:可以批量上传,可以照片分类,文件夹下可以再建文件夹 缺点:国外网站,网速比较慢

##3.POCO貌似也不错 POCO是您的图片生活记录和分享平台,在这里用图片记录您的生活、分享您的一切,在各兴趣社区以图会友、参加各种POCO线上线下活动。 POCO给你提供。。。。 1.跟图片有关的一切服务:发单图微博、发组图博文、发兴趣图片、建立免费可外链相册… 2.视觉图片达人必备的、互联网最创造力的个人空间 3.图片生活分享交流社区(摄影、美食、宠物、达物、旅游、手机拍客、模特….),您的优秀图片分享将有机会登上 POCO网站首页,并获得荣誉勋章 4.获得POCO优质生活体验(美食菜谱、餐厅搜索及优惠、旅游景点大全、相机图片欣赏等)

需要注意的是如果直接复制图片地址,无法正常显示的话,如下: 原地址:

将图片地址进行修改:

<img src="http://image16-c.poco.cn/mypoco/myphoto/20140523/11/17476175320140523113816047.png"/>

-c 去掉即可

<img src="http://image16.poco.cn/mypoco/myphoto/20140523/11/17476175320140523113816047.png"/> 修改地址后的图片 <img src="http://image16.poco.cn/mypoco/myphoto/20140523/11/17476175320140523113726012.png?280x280_130"/>

个人昵称水印

社区水印

缺点:只能单张图片上传

##4.七牛云存储 优点:国内站,稳定,全网加速,图片处理:

缺点:有流程和存储的限制。体验用户:储存空间1GB每月Put请求1万次每月下载流量1GB每月Get请求10万次创建1个空间仅支持富媒体上传. 如果注册为标准用户,还要提供身份,个人照片,貌似有点麻烦

##5.爱唯侦察出的图床http://99btgc01.info/

方便上传电影的封面,听站长说还算稳定。操作也简单,无需管理