JiM-W

keep Moving


  • 首页

  • 分类

  • 关于

  • 归档

  • 标签

Canvas

发表于 2016-09-28 | 分类于 javascript

Canvas

1 Canvas对象的大多数功能都是通过CanvasRenderingContext2D对象获得的,该对象通过canvas对象的getContext(contextID),只支持传递2d

1
2
3
4
5
6
<canvas id="myCanvas" width="200" height="100"></canvas>
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var cxt=c.getContext("2d");//getContext() 方法返回一个用于在画布上绘图的环境。
//getContext("2d") 对象是内建的 HTML5 对象,拥有多种绘制路径、矩形、圆形、字符以及添加图像的方法。
</script>

2 CanvasRenderingContext2D 对象的属性

  • fillStyle 用来指定填充路径所围成的区域的当前颜色、模式或者渐变; fill( ) 方法调用后才能生效
  • strokeStyle 用来指定画笔绘制的路径的颜色、模式或者渐变;stroke( )方法调用后才能生效
  • lineCap 指定线条末端如何绘制,合法值是 “butt” “round” “square”
  • lineJoin 指定两条线 如何连接,合法值是”round” “bevel” “miter”
  • lineWidth 注意是数值类型的属性值 指定绘制线条的画笔的宽度 cxt.lineWidth = 40;(大于1 即可),**以所画的路径为基准,宽度向两边扩展增加,就像钢笔写字一个道理;
  • shadowBlur 属性指定羽化阴影的程度。默认值是 0。阴影效果得到 safari 的支持,但是并没有得到 FireFox 1.5 或 Opera 9 的支持。
  • shadowColor 属性 把阴影的颜色指定为一个 CSS 字符串或 Web 样式字符串,并且可以包含一个 alpha 部分来表示透明度。默认值是 black。阴影效果得到 Safari 的支持,但是并没有得到 FireFox 1.5 或 Opera 9 的支持
  • shadowOffsetX, shadowOffsetY 属性 指定阴影的水平偏移和垂直偏移。较大的值使得阴影化的对象似乎漂浮在背景的较高位置上。默认值是 0。阴影效果得到 Safari 的支持,但是并没有得到 FireFox 1.5 或 Opera 9 的支持。

3 CanvasRenderingContext2D 对象的方法

上述的属性都是作用在绘制的线条或者线条围成的区域中 ,那么生成线条和生成填充的命令(方法也就是核心的实现);当然咯,最根本的你还得有路径,路径的绘制也是根本,表急;

  • stroke() 方法用来绘制当前路径;

  • strokeRect() 方法用来以strokeStyle 和 lineWidth 属性指定,矩形边角的形状由 lineJoin 属性指定绘制一个矩形

    有独立路径,不影响其他路径;好像已经调用了beginPath()一样,**不改变当前位置**;  
    
  • fill( ) 方法用来填充绘制的路径形成的区域(即使该区域没有闭合)

    使用 fillStyle 属性所指定的颜色、渐变和模式来填充**当前路径** 。这一路径的每一条**子路径** 都单独填充。任何未闭合的子路径都被填充,就好像已经对他么调用了 [closePath() 方法](met_canvasrenderingcontext2d_closepath.asp)一样
    
  • fillRect( ) 方法用 fillStyle 属性所指定的颜色、渐变和模式来填充指定的矩形。

    有独立路径,不影响其他路径;好像已经调用了beginPath()一样,**不改变当前位置**;
    
  • clearRect( ) 方法清除所定义的矩形区域;

1
2
3
4
5
cxt.fill();//只要路径可以形成闭合空间,就会被填充
//填充一条路径并不会清除该路径。你可以在调用 fill() 之后再次调用 stroke(),而不需要重新定义该路径。
cxt.stroke();
cxt.fillRect(x,y,width,height);
cxt.strokeRect(x,y,width,height);

4 用CanvasRenderingContext2D 对象的方法绘制路径

4.1 当前位置的概念的理解,每次线条绘制完毕,包括绘制直线,圆形,矩形等,当前位置 都会发生变化

4.2 如何理解路径,就是没有调用beginPath()之前进行绘制路线的方法,所绘制的路线都是当前路径,当前路径内的包括直线,圆形,矩形以及曲线都会被stroke()方法和fill()绘制成框或者添加填充;调用beginPath()之后绘制的路径,然后在stroke()和fill()渲染了路径不会将之前的路径重新渲染;

4.3 绘制一条子路径:

  • 绘制直线确定起始位置: cxt.moveTo(x,y) 将当前位置设置移动到该位置(x,y),并且不产生线条,

    moveTo() 方法设置当前位置并开始一条新的子路径;

  • 绘制直线,进行直线延伸: cxt.lineTo(x,y) 绘制直线完成之后,设置(x,y)为当前位置;

  • 绘制矩形cxt . rect(x,y,width,height); x,y 矩形的左上角的坐标。为当前路径(画布)添加一条矩形子路径。绘制完成之后当前位置 是矩形左上角;?当前位置是 (0,0)。

  • 绘制圆形 cxt . arc(x,y,radius,startAngle,endAngle,counterclockwise) 为一个画布的当前子路径 添加一条弧。

    • x,y 代表圆心坐标,

    • angle的取值问题:90deg = 100grad = 0.25turn ≈ 1.570796326794897rad,

      沿着圆指定弧的开始点和结束点的一个角度。这个角度用弧度 来衡量。
      沿着 X 轴正半轴的方向的角度为 0,角度 沿着逆时针 方向而增加。

    • counterclockwise true false 逆时针 ture 顺时针 false

    • 绘制过程:

      1 这个方法的前 5 个参数指定了圆周的一个起始点和结束点 。

      2 调用这个方法会在当前点和弧的起点 之间添加一条直线。

      3 接下来,沿着弧的起始点和结束点 之间添加弧(根据true或者false判断逆时针还是顺时针画弧)

      4 最后将 弧的终点 设置为 当前位置

    • 在绘制圆形的时候,为了避免一些莫名其妙的填充效果,尽量将当前点移到圆心处;

4.4 如果想要对一个新的路径渲染不同于上一条子路径的边框和填充,那么可以新建一条子路径,并且重新渲染和填充就可以获取不一样子路径样式

  • 当前路径 : 画布的一项强大功能是,它能够从基本的绘图操作来构建图形,然后,绘制这些图形的框架(勾勒它们)或者给这些图形的内容涂色(填充它们)。累计起来的操作统一叫做当前路径。一个画布只保持一条当前路径。
  • 子路径: 每次使用beginPath()方法之后,就开辟了一条新的子路径;
  • beginPath() 方法在一个画布中开始子路径的一个新的集合。 重新渲染为不同的样式;丢弃任何当前定义的路径并且开始一条新的路径。它把当前的点设置为 (0,0)。

    当一个画布的环境第一次创建,beginPath() 方法会被显式地调用;

    每次stroke对应一个beginPath;

  • closePath( ) 将当前子路径闭合;如果画布的子路径是打开的,closePath() 通过添加一条线条连接当前点和子路径起始点 来关闭它。

    如果子路径已经闭合了,这个方法不做任何事情。

    一旦子路径闭合,就不能再为其添加更多的直线或曲线了。要继续向该路径添加,需要通过调用 moveTo() 开始一条新的子路径。

4.5 路径绘制完毕之后 ,必须调用cxt.stroke() 或者cxt.fill()进行渲染才能显示;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<canvas id="myCanvas" height="400px" width="400px" style="border:solid red 1px"></canvas>
<script>
//以下在chorm开发者工具设置断点查看下变化过程
var myCanvas = document.getElementById("myCanvas");
var cxt = myCanvas.getContext('2d');
//console.log(cxt);
cxt.beginPath();
cxt.lineWidth = 5;
cxt.fillStyle = "red";
cxt.rect(200,200,50,50);//将当前位置设置为(0,0)
cxt.stroke();
cxt.fill();
cxt.beginPath();//看下没有这行代码和有这行代码的区别,分析beginPath()的作用
cxt.lineWidth = 10;
cxt.fillStyle = "green";
cxt.rect(100,100,50,50);
cxt.stroke();
cxt.fill();
//lineWidth宽度向两边扩展,fill颜色填充以路径为基准,所以会出现边框变细的错觉
</script>
</body>
</html>

5 用CanvasRenderingContext2D 对象的方法填充文本

5.1 绘制文本的方法:

  • cxt.fillText(text,x,y,maxWidth) cxt.strokeText(text,x,y,maxWidth) 绘制文本 ; 不改变当前位置;

  • cxt.measureText(txt) 该方法可以测试文本的大小,返回一个对象 TextMetrics{width : }

    x y 是开始绘制文本的坐标

  • cxt.measureText(txt).width ;可以获取文本的大小

5.2 改变文本的属性:

  • cxt.textBaseline = “alphabetic|top|hanging|middle|ideographic|bottom”; 以绘制的文本的y坐标为基准;默认。文本基线是普通的字母基线。
  • cxt.textAlign = =”center|end|left|right|start”; 以绘制文本坐标x为基准 默认start
  • fillText()或 strokeText() 方法在画布上定位文本时,将使用指定的 textBaseline和textAlign 值。

6 用CanvasRenderingContext2D 对象的方法绘制图像

7 用CanvasRenderingContext2D 对象的方法,改变坐标系统

  • cxt.translate(dx,dy) 该方法可以改变画布原始的原点坐标,后期所绘制的路径都是以这个改变后的坐标为原点,坐标轴的执行不变;x轴向右为正方向,y轴向下为正方向

  • cxt.rotate(angle) rotate() 方法通过指定一个角度,使得任意后续绘图在画布中都显示为旋转的。它并没有旋转 元素本身。注意,这个角度是用弧度指定的。如需把角度转换为弧度,请乘以 Math.PI 并除以 180。

    旋转的量,用弧度表示。正值表示顺时针方向旋转,负值表示逆时针方向旋转;

  • 每次牵涉到旋转,要考虑两点,第一旋转的中心,第二旋转的角度,这里旋转的角度通过angle赋值,旋转的中心是当前坐标系统的坐标原点,也就是说,如果通过translate(dx,dy)改变了坐标原点,那么旋转的中心就是改变后的坐标原点;

    • 旋转之后在画 的路径都是以旋转后的为基准,对于旋转之前的路径没有影响;
  • cxt.scale(sx,sy) scale() 方法为画布的当前变换矩阵添加一个缩放变换。缩放通过独立的水平和垂直缩放因子来完成。例如,传递一个值 2.0 和 0.5 将会导致绘图路径宽度变为原来的两倍,而高度变为原来的 1/2。指定一个负的 sx 值,会导致 X 坐标沿 Y 轴对折,而指定一个负的 sy 会导致 Y 坐标沿着 X 轴对折。

8 save( ) 和 restore( ) 方法

  • save( ) 一个画布的图形状态包含了 CanvasRenderingContext2D 对象的所有属性(除了只读的画布属性以外)。它还包含了一个变换矩阵,该矩阵是调用 rotate( )、scale( ) 和 translate( ) 的结果。另外,它包含了剪切路径,该路径通过 clip( ) 方法指定。可是要注意,当前路径和当前位置并非图形状态的一部分,并且不会由这个方法保存。
  • restore( ) 回复上一个save( )状态时候的画布所保存的属性,包括变换的矩阵结果;

AngularModule

发表于 2016-09-27 | 分类于 javascript

1 定义:A module is a collection of configuration and run blocks which get applied to the application during the bootstrap process. In its simplest form the module consists of a collection of two kinds of blocks

angular.module(‘myApp’,[ ]) 用来创建一个模块 angular.module(‘myApp’) 用来引用一个模块(该模块必须已经声明)

1
2
3
4
5
6
7
8
9
<body ng-app = 'myApp'>
<script>
var myApp = angular.module("myApp",[]);
var myApp2 = angular.module("myApp");
console.log(myApp);
console.log(myApp2);
console.log(myApp === myApp2);//true
</script>
</body>

2 AngularJS分两个阶段运行你的应用 – config阶段和run阶段。config阶段是你设置任何的provider的阶段。它也是你设置任何的指令,控制器,过滤器以及其它东西的阶段。在run阶段,AngularJS会编译你的DOM并启动你的应用

2.1 Configuration Blocks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//语法糖,这个是我们平常的写法,很简洁,其实是下一段代码的语法糖
angular.module('myModule', []).
value('a', 123).
factory('a', function() { return 123; }).
directive('directiveName', ...).
filter('filterName', ...).
controller('MainController',function($scope){
});
// is same as
angular.module('myModule', []).
config(function($provide, $compileProvider, $filterProvider) {
$provide.value('a', 123);
$provide.factory('a', function() { return 123; });
$compileProvider.directive('directiveName', ...);
$filterProvider.register('filterName', ...);
$controllerProvider.register('MainController', function($scope) {
});
});
});

需要注意的一点是:在config阶段,只有provider能被注入(只有两个例外是\$provide和$injector)。

3 Run Blocks

Run blocks are the closest thing in AngularJS to the main method. A run block is the code which needs to run to kickstart the application. It is executed after all of the services have been configured and the injector has been created. Run blocks typically contain code which is hard to unit-test, and for this reason should be declared in isolated modules, so that they can be ignored in the unit-tests.

template

发表于 2016-09-27 | 分类于 javascript

table 表格操作,如何将这些后台传过来的数据动态的添加到table表格里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<table border = 1></table>
<script>
var data = [{
id : 1,
name : '西游记',
author : '吴承恩',
price : '40',
desc : '佛教与道教的斗争'
},{
id : 2,
name : '水浒传',
author : '施耐庵',
price : '30',
desc : '草寇与政府的斗争'
},{
id : 3,
name : '红楼梦',
author : '曹雪芹',
price : '60',
desc : '封建社会的缩影'
},{
id : 4,
name : '三国演义',
author : '罗贯中',
price : '30',
desc : '一个杀伐纷争的年代'
}];
</script>
</body>
</html>
//一般传过来的是JSON数据,然后需要进行转化,JSON.stringify(data)方法转化为对象

1 动态创建表格

1.1 innerHTML 数组和字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<script>
//--------------------------------------------------
//通过字符串,这种方法有一个很大的弊端,就是字符串的不可变性,导致每次都会重新给字符串分配内存空间,特别耗费内存
var table = document.querySelector("table");
var str = "";
for(var i = 0 ; i < data.length ; i++){
var item = data[i];
console.dir(item);
str += '<tr>' +
'<td>'+item['id']+'</td>' +
'<td>'+item['name']+'</td>' +
'<td>'+item['author']+'</td>' +
'<td>'+item['price']+'</td>' +
'<td>'+item['desc']+'</td>' +
'</tr>'
}
table.innerHTML = str ;
//-----------------------------------------------------
var table = document.querySelector("table");
var arr = [];
for(var i = 0 ; i < data.length ; i++){
var item = data[i];
console.dir(item);
arr.push(
'<tr>' +
'<td>'+item['id']+'</td>' +
'<td>'+item['name']+'</td>' +
'<td>'+item['author']+'</td>' +
'<td>'+item['price']+'</td>' +
'<td>'+item['desc']+'</td>' +
'</tr>'
)
}
var html = arr.join("");
table.innerHTML = html ;
//---------------------------------------------------------------
</script>

1.2 模板引擎创建,传入数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script src="template-native.js"></script>
<script>
// 模板引擎的使用,第一步,改变script标签的type属性 = text/html 或者text/template,编写模板
// 第二步,调用模板,传入数据和模板的id
</script>
<script type="text/template" id="tempalteId">
<% for(var i = 0 ;i < list.length; i++){ %>
<tr>
<td> `<%=list[i].id%>` </td>
<td> `<%=list[i].name%>` </td>
<td> `<%=list[i].author%> `</td>
<td> `<%=list[i].price%> `</td>
<td>`<%=list[i].desc%>`</td>
</tr>
<% } %>
</script>
<script>
var tepData = { list: data } //这个位置要传入对象形式的数据
var html = template("tempalteId",tepData); //注意第一个参数传入的是id ,引号勿忘
var table = document.querySelector("table")
table.innerHTML = html;
</script>

Git Cmd Command Enhence Memory

发表于 2016-09-27 | 分类于 git

Bash 命令

  • $ cd ../ 可以进入上层目录
  • $ cd ./目录名 可以进入下层目录
  • $ cd mkdir 创建一个目录
  • $ touch + 文件名 可以创建某个文件 \$ touch index / index.js / index.html etc
  • $ cat + 文件名可以查看文件内容,工作区的文件内容;\$ cat index / index.js /index.html etc
  • $ echo + content + > 文件
    • $ echo hello you > index.html //会清空之前的内容
    • $ echo good bye >> index.html //新添加内容,不会
  • $ cat index.html 可以查看文件
  • $ less index.html 全屏查看文件
  • $ tail -f 可以实时监看文件后面几行的内容变化
  • q 全屏查看之后可以通过q退出
  • $ rm index.html (remove)可以删除文件
  • $ vi index.html 可以打开文件,直接进行编辑
  • tab键可以自动补全
  • | 管道操作符
  • ​

VI 命令模式

  • $ vi index.html 进入命令模式
  • 之后
  • a A i I o O s可以进入编辑模式,可以直接编辑文件,esc可以退出编辑模式
  • 退出(ESC)编辑模式之后进入命令模式,以下操作都在命令模式
  • ZZ 可以直接保存并退出当前文件
  • dd 可以直接删除当前行,还在命令模式
  • 大写S 可以直接删除当前光标所在行,并直接进入编辑模式
  • 大写C 可以直接删除当前光标后面的所有的字符,然后直接进入编辑模式
  • x 可以直接删除当前光标的后面一个字符串
  • gg 将光标移动到文件首部
  • p 直接复制一整行
  • u 后退上次编辑
  • h j k l 左下上右移动
  • : 0 定位光标至行首
  • : $ 定位光标至行尾
  • : q ! 可以直接退出命令模式
  • : wq 可以直接退出命令模式

Git 命令

工作区 ——>git add 将工作区的文件添加到 暂存区—— > git commit 将暂存区的文件添加到 分支

git 版本库(工作区有一个.git文件夹)管理的是所在目录的文件的修改, 而不是文件,也就是说,

当 文件修改 1 —— git add 将文件修改1提交到暂存区——再接着 文件修改2 —— git commit 提交到分支,这个时候提交的只有修改1 ,修改2 并未被提交到分支;

git add 命令实际上做的工作是提交的文件的修改到暂存区,不是提交的文件本身,这个对于git版本库管理工具理解至关重要;

git status 可以随时查看 工作区 暂存区 以及分支的状态

工作区文件的状态:未跟踪 untracked 已暂存staged 已提交 committed 已修改 modefied

  • $ git 用于检测是否安装了了git\

  • $ mkdir learngit (Make Directory) //创建一个新的目录

  • \$ cd learngit (Change Directory) //进入一个目录

  • $ pwd(Print Working Directory) //打印当前工作目录

  • $ git init 命令可以将该目录变成git可以管理的仓库,初始化git仓库(initial:初始化)

  • 创建一个文件 比如 “readme.txt” 创建文件之后,如果没有add命令,那么文件属于为被跟踪状态

  • $ git add readme.txt 将创建的文件添加到仓库,或者将文件的修改提交到暂存区

  • $ git commit -m “ 文件说明” 将添加的文件的修改提交到仓库(commit:提交)

  • $ git status 命令可以让我们时刻掌握仓库当前的状态,上面的命令告诉我们,readme.txt被修改过了,但还没有准备提交的修改。但是我们无法知道什么内容被修改了

  • $ git diff 可以查看那些内容被修改了,被修改的一列最前面会有 + 号(difference:不同)

  • $ git add readme.txt 再次添加给仓库,不要commit提交

  • $ git add -A 表示将文件全部提交到仓库暂存区

  • $ git add * 表示将工作区全部文件提交到暂存区

  • $ git rm –cached readme.txt 将提交到缓存区的文件移除

  • $ git status 查看下状态

  • $ git commit -m “文档说明” commit之后会在git仓库object文件夹下新建一个文件夹,保存了commit的信息

    版本退回

  • $ git log 可以获取文档被修改的过程

  • $ git log –pretty=oneline 可以让显示更加优雅

  • $ git reset –hard HEAD^ 其中 ^ 代表回退到上一个版本,^^ 代表回退到倒数第二个版本,HEAD~100 回退到地一百个版本。工作区 暂存区 本地仓库都会改变

  • $ git reset hard 4444 如果我们退回以后后悔了,又想回去怎么办?可以回到某个特定的版本,只需要知道某个版本号即可,部分内容,系统会自动去匹配

  • $ git reset soft 只会改变历史HEAD指向

  • $ git reflog 可以查看历史命令

  • $ git ls (list) 查看当前目录下的内容和 \$ ll 命令功能类似

  • $ git branch 可以查看当前分支

    branch     List, create, or delete branches
    
  • $ git branch myMaster 可以添加一个myMaster分支

  • $ git branch 可以查看分支,有了新增的分支

  • $ git checkout myMaster 可以切换到该分支

    checkout   Switch branches or restore working tree files
    
  • $ git checkout -b myMaster 等价于 \$ git branch myMaster \$git checkout myMaster

  • $ git branch -d 删除分支

  • $ git branch -d myMaster ;

  • $ git clone + 地址 可以直接从github上下载文件

  • $ git push 可以将本地文件推送到服务器

  • $ git stash 可以保存当前的工作内容

创建共享仓库

  • $ git init –bare 创建共享仓库
  • $ git push 远程仓库的地址 本地分支:远程分支
  • $ git push 远程仓库的地址 本地分支
  • $ git pull 远程仓库的地址 远程分支 : 本地分支
  • $ git pull 远程仓库的地址 远程分支
  • $ git clone 远程仓库的地址 文件名称
  • $ git fecth 从远程仓库获取分支内容,但是不会合并分支
  • $ git merge 然后可以通过git merge进行合并

分支操作

  • git branch myMaster 新建分支
  • git branch -r 查看远程分支
  • git branch -a 查看所有分支
  • git branch -d 删除本地分支
  • git push origin : 分支名称 删除远程仓库分支

    ​

jQuery核心

发表于 2016-09-24 | 分类于 jQuery

1 核心 $(“selector”):这个函数接收一个包含 CSS 选择器的字符串,然后用这个字符串去匹配一组元素。注意:如果选择器字符串含有变量 的话需要进行字符串拼接。

1
2
3
4
5
6
7
8
9
10
11
12
<div class="bd">
<ul>
<li class="current">我是体育模块</li>
<li>我是娱乐模块</li>
<li>我是新闻模块</li>
<li>我是综合模块</li>
</ul>
</div>
如果index是以变量的形式存在的话,那么,第一行代码获取对应索引位置的li元素是无法获取的,第二行字符串的拼接才是正确的写法。
var index = 2 ;
$(".bd li:eq(index)").prop("class","current");//错误写法
$(".bd li:eq("+index+")").prop("class","current");

2 jquery中 get() 和 index() 如何区分DOM对象和jquery对象的区分

  • get()方法:这能够让你选择一个实际的DOM 元素并且对他直接操作,而不是通过 jQuery 函数,也就是说此时将jquery对象转化成了DOM对象;

jqueryObj.get():如果不传参数index,那么将返回匹配到的所有对象组成的DOM元素集合;

jqueryObj.get(index):如果传入index参数,那么将返回匹配到元素集合中的第几个DOM元素,其中index代表索引值;

注意返回值是DOM元素,不能用jquery方法 ;get(index)方法中的index索引值是从0 开始的;

  • index()方法:如果不传参数,那么返回值是当前jquery对象在其同辈元素中的索引值(从0 开始)

遍历对象的属性

发表于 2016-09-22 | 分类于 javascript

遍历对象的属性

1
2
3
4
5
6
7
8
9
10
var obj = Object.create({foo:0},{
bar1:{
value:1//descriptor默认值 enumerable fasle configurable false writable false
},
bar2:{
value:2,
enumerable:true
}
});
console.log(obj);//Object {bar2: 2, bar1: 1}

for in 可以遍历属性和原型属性 中可以枚举的 ,包括原型上的属性

1
2
3
for(var key in obj){
console.log(key); // bar2 foo
}

Object.keys(obj) 返回所有可以枚举的属性组成的数组,不包括原型上的属性

1
2
console.log(Object.keys(obj));//["bar2"]

Object.getOwnPropertyNames(obj) 返回可以枚举以及不可枚举的属性组成的数组,不包括原型上的属性

1
2
console.log(Object.getOwnPropertyNames(obj));//["bar1", "bar2"]

Object.assign()方法只能复制可以枚举的属性,不能复制不可枚举以及原型上的属性

1
2
console.log(Object.assign({},obj));//Object {bar2: 2}

JSON.stringify(obj) 只能将对象可枚举的属性转化

1
2
console.log(JSON.stringify(obj));//'{"bar2":2}'
console.log(typeof JSON.stringify(obj));//string

Object API submit

发表于 2016-09-22 | 分类于 javascript

Object内置对象 API

1 Object.getPrototypeOf( obj ) ,返回obj对象的构造函数的prototype属性(也就是obj对象的 proto 属性对象),每个构造函数都有一个prototype属性

1
2
3
4
5
6
7
8
function Test (){};
var test = new Test();
console.log(Object.getPrototypeOf(test));
console.log(Object.getPrototypeOf(test) === Test.prototype);//true
//-------------------------------------------------------------------------
var obj = new Object ();
console.log(Object.getPrototypeOf(obj));
console.log(Object.getPrototypeOf(obj) == Object.prototype);//true

2 isPrototypeOf( )

3 设置对象的原型属性 proto

3.1 Object.create( proto , prop ) 用来设置对象的 proto 的属性的指向;返回一个创建的对象;prop和Object.defineProperties(obj ,prop) 里面的prop格式一致,如下栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var obj = Object.create({ foo: 1 }, { // foo is on obj's prototype chain.
bar: {
value: 2 // bar is a non-enumerable property.
},
baz: {
value: 3,
enumerable: true // baz is an own enumerable property.
}
});
var copy = Object.assign({}, obj);
console.log(copy); // { baz: 3 }
console.log(obj);

obj结构如下

1
2
3
4
5
Object baz: 3
bar: 2
__proto__: Object
foo: 1
__proto__: Object

3.2 Object.setPrototypeOf(obj,prototype) prototype参数必须是一个对象或者null,否则会抛出异常,用来设置对象的 proto 的属性的指向,返回obj对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
function Test(){
this.age = 18;
}
var test = new Test();
// console.dir(Test);
// console.log(Test.prototype);
var obj1 = Object.create(Test.prototype,{
'name':{
writable:true,
value:'JiM'
}
});
console.log(obj1);
console.log(obj1.__proto__ === Test.prototype );
var obj1 = Object.create(Object.prototype,{
'name1':{
writable:true,
value:'JiM1'
}
});
console.log(obj1);
console.log(obj1.__proto__ === Object.prototype );
var obj1 = Object.create(Array.prototype,{
'name2':{
writable:true,
value:'JiM2'
}
});
console.log(obj1);
console.log(obj1.__proto__ === Array.prototype );
var obj1 = Object.create(null,{
'name3':{
writable:true,
value:'JiM3'
}
});
console.log(obj1);
console.log(obj1.__proto__ === null );//false
console.log(obj1.__proto__ == null );//true
var o = {foo:"bar"}
var obj1 = Object.create(o,{
'name4':{
writable:true,
value:'JiM4'
}
});
console.log(obj1);
console.log(obj1.__proto__ === o );//true
var obj1 = Object.create(Test,{
'name5':{
writable:true,
value:'JiM5'
}
});
console.log(obj1);
console.log(obj1.__proto__ === Test);
//proto 设置obj1的__proto__ 指向,必须是一个对象或者null否则会抛出异常; prop 设置 obj1 的属性值
1
2
3
4
5
var obj = {name:"JHOn"};
console.log(obj);
// Object.setPrototypeOf(obj,null);
Object.setPrototypeOf(obj,Array.prototype);

4 Object.getOwnPropertyNames(obj )该函数可以将对象中可枚举以及不可枚举的key值都列举出来,返回一个key组成的数组

The object whose enumerable and non-enumerable own properties are to be returned.

An array of strings that correspond to the properties found directly upon the given object.

5 Object.keys(obj) 该方法返回obj对象的所有可枚举的属性的键值组成的数组,不可枚举的属性键不会返回

1
2
3
4
5
6
7
8
9
10
11
12
13
var obj = {name:"Jhon",age:12,gender:"man"};
Object.defineProperty(obj,"email",{
value:"Gemail",
enumerable:false //设置email为false不可枚举,便于检测
})
for(var key in obj ){ //遍历对象自身的和继承(__proto__上的属性)的可枚举的属性
console.log(key); //name age email
}
//以下两种方法只遍历对象的原生属性,不会遍历对象的原型__proto__上的属性
var arr = Object.getOwnPropertyNames(obj);
console.log(arr); //["name", "age", "gender", "email"]
var arr1 = Object.keys(obj);
console.log(arr1);//["name", "age", "gender"]

需要注意的一点,如果数组中有一项为undefined的话,我们需要理解Object.keys()底层的实现,其实是封装了for-in循环,以及判断是否有某个属性Object.prototype.hasOwnProperty() 方法.for-in循环用来获取对象或者数组的键名.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
if (!Object.keys) {
Object.keys = (function() {
'use strict';
var hasOwnProperty = Object.prototype.hasOwnProperty,
hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
dontEnums = [
'toString',
'toLocaleString',
'valueOf',
'hasOwnProperty',
'isPrototypeOf',
'propertyIsEnumerable',
'constructor'
],
dontEnumsLength = dontEnums.length;
return function(obj) {
if (typeof obj !== 'function' && (typeof obj !== 'object' || obj === null)) {
throw new TypeError('Object.keys called on non-object');
}
var result = [], prop, i;
for (prop in obj) {
if (hasOwnProperty.call(obj, prop)) {
result.push(prop);
}
}
if (hasDontEnumBug) {
for (i = 0; i < dontEnumsLength; i++) {
if (hasOwnProperty.call(obj, dontEnums[i])) {
result.push(dontEnums[i]);
}
}
}
return result;
};
}());
}

所以对于没有定义的某一项数组元素,Object.keys() 方法的输出如下,这点需要注意下

1
2
3
let Arr = ['a',,'c']
let sparseKeys = Object.keys(Arr)
console.log(sparseKeys) //["0","2"]

XMIHttpRequestLevel2FormData

发表于 2016-09-22 | 分类于 ajax

1 首先来看下声明是FormData (查看MDN官方文档)

XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的[send()方法来异步的提交这个”表单”.比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件.

2 看下之前上传文件的限制

3 用这个新特性上传文件的优势

HTML5 Storage

发表于 2016-09-21 | 分类于 HTML5 storage

HTML5 Storage

1 localStorage 存储数据没有时间限制,一周,一个月之后都可以使用

2 sessionStorage 存储数据只是针对一个session进行,当用户关闭当前网页的时候,数据随即也被清除;

3 当点击开发者工具里面的 clear storage的时候,localStorage会被删除,但是,sessionStorage不会被删除,只要浏览器窗口不被关闭,那么sessionStorage本地存储就不会被删除;

如何判断浏览器是否支持HTML5这个新的API,如果window.loaclStorage window.sessinoStorage 存在,那么证明浏览器支持该对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="button" value="按钮"/>
<script src="jquery-1.12.2.js"></script>
<script>
$("input:button").click(function(){
if(window.localStorage){ //object转化为布尔为true
console.log(typeof window.localStorage);//object
console.log(window.localStorage);
}
if(window.sessionStorage){
console.log(typeof window.sessionStorage);//object
console.log(window.sessionStorage);
}
});
</script>
</body>
</html>

3 本地存储 localStorage sessionStorage 对象常用方法如下

1
2
3
4
5
6
7
3.1 获取localStorage对象或者sessionStorage对象里面的key值
getItem(key) localStorage.key sessionStorage.key
3.2 增加localStorage对象或者sessionStorage对象里面的key值
setItem(key,value) localStorage.key = "value" sessionStorage.key = "value"
3.3 removeItem(key) 删除localStorage对象或者sessionStorage对象里面的key值
3.4 clear() 清空localStorage对象或者sessionStorage对象里面的所有存储值
3.5 key(num) 可以得到localStorage对象的键值,对应的num参数必须存在.
1
2
3
4
5
localStorage.name = "jim";//设置localStorage 对象 name 值
sessionStorage.name2='wmg';//设置sessionStorage对象 name值
localStorage.setItem("age",12);//设置 localStorage 对象age值
loaclStorage.getItem("age");//获取localStorage 对象里面的 age值
localStorage.clear();//清除localStorage 对象里面所有的值

4 详说二者的不同

  • loaclStorage 本地存储数据不会被销毁,除非用户主动删除,存储容量大 5M,对于基本的字符串的存储足够了;
  • sessionStorage 本地存储数据很特别,引入了一个”浏览器窗口”的概念,sessionStorage是在一个同源 的同窗口 中始终存在的数据,
  • 浏览器窗口没有被关闭,那么就一直存在,即使刷新了页面 或者 进入同源另外一个页面,仍然存在
  • 浏览器窗口被关闭 或者 再次独立的打开同样的这个页面,两个窗口的sessionStorage并不通用
  • 简单解释来说就是:sessionStorage是仅仅存在于当前”浏览器窗口的”本地存储对象,”当前浏览器窗口”不关闭,则一直存在,关闭则自动销毁;

大家可以看下这个栗子 综合考虑下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>LocalStorage</title>
<script src="jquery-1.12.2.js"></script>
<script type="text/javascript">
function clickCounter() {
if (typeof (Storage) !== "undefined") {
if (sessionStorage.clickcount) {
sessionStorage.clickcount = Number(sessionStorage.clickcount) + 1;
}
else {
sessionStorage.clickcount = 1;
}
$('#result').html('');
$('#result').append('<p>' + sessionStorage.clickcount + '</p>');
}
else {
$('#result').text('抱歉您的浏览器不支持本地存储');
}
}
function clickCounter2() {
if (typeof (Storage) !== "undefined") {
if (localStorage.clickcount) {
localStorage.clickcount = Number(localStorage.clickcount) + 1;
}
else {
localStorage.clickcount = 1;
}
$('#result2').html('');
$('#result2').append('<p>' + localStorage.clickcount + '</p>');
}
else {
$('#result2').text('抱歉您的浏览器不支持本地存储');
}
}
</script>
</head>
<body>
<div>
<p>
<button onclick="clickCounter()" type="button">sessionStorage查看单击次数</button>
</p>
<div id="result"></div>
<p>单击按钮查看统计次数</p>
</div>
<div>
<p>
<button onclick="clickCounter2()" type="button">localStorage查看单击次数</button>
</p>
<div id="result2"></div>
<p>单击按钮查看统计次数</p>
</div>
</body>
</html>

underscore template js

发表于 2016-09-19 | 分类于 nodejs

一 underscore_template.js模板引擎的使用

1 语法

1
2
3
4
5
6
7
8
9
10
<script type="text/template">
_.template模板函数只能解析3种模板标签(这比Smarty、JSTL要简单得多):
<% %>:用于包含JavaScript代码,这些代码将在渲染数据时被执行。
<%= %>:用于输出数据,可以是一个变量、某个对象的属性、或函数调用(将输出函数的返回值)。
<%- %>:用于输出数据,同时会将数据中包含的HTML字符转换为实体形式(例如它会将双引号转换为&quot;形式),用于避免XSS攻击。
</script>

2-0 template模板函数基础

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
_.template(templateString, [settings])
将 JavaScript 模板编译为可以用于页面呈现的函数, 对于通过JSON数据源生成复杂的HTML并呈现出来的操作非常有用。 模板函数可以使用 <%= … %>插入变量, 也可以用<% … %>执行任意的 JavaScript 代码。 如果您希望插入一个值, 并让其进行HTML转义,请使用<%- … %>。 当你要给模板函数赋值的时候,可以传递一个含有与模板对应属性的data对象 。 如果您要写一个一次性的, 您可以传对象 data 作为第二个参数给模板 template 来直接呈现, 这样页面会立即呈现而不是返回一个模板函数. 参数 settings 是一个哈希表包含任何可以覆盖的设置 _.templateSettings.
var compiled = _.template("hello: <%= name %>");
compiled({name: 'moe'});
=> "hello: moe"
var template = _.template("<b><%- value %></b>");
template({value: '<script>'});
=> "<b>&lt;script&gt;</b>"
您也可以在JavaScript代码中使用 print. 有时候这会比使用 <%= ... %> 更方便.
var compiled = _.template("<% print('Hello ' + epithet); %>");
compiled({epithet: "stooge"});
=> "Hello stooge"

2 -1模板解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!-- 用于显示渲染后的标签 -->
<ul id="element"></ul>
<!-- 定义模板,将模板内容放到一个script标签中 -->
<script type="text/template" id="tpl">
//注意type类型 "text/template"
<% for(var i = 0; i < list.length; i++) { %>
<% var item = list[i] %>
<li>
<span><%=item.firstName%> <%=item.lastName%></span>
<span><%-item.city%></span>
</li>
<% } %>
</script>
<script type="text/javascript" src="underscore/underscore-min.js"></script>
<script type="text/javascript">
// 获取渲染元素和模板内容
var element = $('#element'),
tpl = $('#tpl').html();
// 创建数据, 这些数据可能是你从服务器获取的
var data = {
list: [
{firstName: '<a href="#">Zhang</a>', lastName: 'San', city: 'Shanghai'},
{firstName: 'Li', lastName: 'Si', city: '<a href="#">Beijing</a>'},
{firstName: 'Wang', lastName: 'Wu', city: 'Guangzhou'},
{firstName: 'Zhao', lastName: 'Liu', city: 'Shenzhen'}
]
}
// 解析模板, 返回解析后的内容
var html = _.template(tpl, data);
//注意data 必须是javascript对象
// 将解析后的内容填充到渲染元素
element.html(html);
</script>

在本例中,我们将模板内容放到一个

1…101112…20
JiM-W

JiM-W

keep fighting!

195 日志
52 分类
90 标签
© 2017 JiM-W
由 Hexo 强力驱动
主题 - NexT.Pisces