ccrsky


  • 首页

  • 标签

  • 分类

  • 归档

  • 站点地图

sed常用操作命令

发表于 2017-04-26 | 分类于 linux |

SED命令

SED的英文全称是 Stream EDitor,它是一个简单而强大的文本解析转换工具。

原理

  1. 读一行到缓存区处理(模式空间)
  2. 执行sed命令
  3. 输出结果接着继续处理下一行(重复此流程直至结束)

用途

  • 文本替换
  • 选择性的输出文本文件
  • 从文本文件的某处开始编辑
  • 无交互式的对文本文件进行编辑等

命令格式

1
2
3
4
5
6
7
8
9
sed [option]  command files
option:
-e:指定要执行的命令,使用该参数,我们可以指定多个命令
-n:默认情况下,模式空间中的内容在处理完成后将会打印到标准输出,该选项用于阻止该行为
-f:指定包含要执行的命令的脚本文件(一行一个命令,类似多个-e)

command:行定位(或正则)+ sed命令 (命令使用单引号包裹)

sed -e '1d' -e '2d' -e '5d' demo.txt

在SED中使用的命令会作用于文本数据的所有行。如果只想将命令作用于特定的行或者某些行,则需要使用 “行寻址” 功能。

行寻址两种形式:
1
2
3
4
5
6
7
8
9
10
11
1.以数字形式表示的行区间
sed -n '3p' demo.txt

# 区间
sed -n '2,5 p' demo.txt

# $ 表示自后一行 ^ 标识开始
sed -n '3,$ p' demo.txt

2.以文本模式来过滤行
sed -n '/Alchemist/, 5 p' books.txt
操作符 + , ~

加号(+)操作符,它可以与逗号(,)操作符一起使用

1
2
# 从第二行开始下4行
sed -n '2,+4 p' demo.txt

使用波浪线操作符(~)指定地址范围,它使用M~N(步长)的形式,告诉SED应该处理M行开始的每N行。

1
2
# 50~5匹配行号5,10,15等
sed -n '5~5 p' demo.txt > a.txt

sed操作不影响源文件,可用重定向覆写源文件.

sed操作命令

打印命令 p

打印命令p通常和-n选项配合

1
2
3
4
5
# 打印1~10行
sed -n '1,10p' demo.txt

# 打印非10行
sed -n '10!p' demo.txt
插入命令 a/i
1
2
3
4
5
# 第五行后插入hello
sed -n '5a hello' demo.txt

# 第五行前插入hello
sed -n '5i hello' demo.txt
替代 c
1
2
# 第四行替换成hi
sed -n '4c hi' demo.txt
删除 d
1
2
3
4
5
# 删除第十行
sed -n '10d' demo.txt

# 删除空行
sed '^&d' demo.txt
替换 s
1
2
# false 替换成true
sed 's/false/true/g' demo.txt
执行多条命令 { ;}
1
2
# 多条命令使用{},命令间用分号分隔
sed -n '{p;n;p}' demo.txt
读取下一行到模式空间里去 n
1
2
# false 替换成true
sed 's/false/true/g' demo.txt

h: 将当前模式空间的内容保存到保存空间
H:将当前模式空间中的内容追加到 保持空间
g : 将保持空间复制到模式空间
G: 将保持空间附加到模式空间
x:用于交换模式空间和保持空间中的内容

跳转 b
1
2
# 类似goto跳转
sed -n 'h;n;H;x;s/\n/, /;/Paulo/!b Print; s/^/- /; :Print;p' demo.txt
创建分支 t
1
2
# 创建分支;只有当前置条件成功的时候,t 命令才会跳转到该标签
sed -n 'h;n;H;x; s/\n/, /; :Loop;/Paulo/s/^/-/; /----/!t Loop; p' demo.txt
替换字符 &
1
2
# & 为匹配的字符
sed 's/w/&123' demo.txt
大小写转化 \u \U \l \L
1
2
# & 为匹配的字符
sed 's/w/\u&123/' demo.txt
字符一对一转化 y
1
2
3
# [address]y/inchars/outchars/ 
# inchars中的第一个字符会被转换为outchars中的第一个字符,第二个字符会被转换成outchars中的第二个字符
$ echo "1 5 15 20" | sed 'y/151520/IVXVXX/'
显示隐藏字符命令 l
1
2
3
# [address1[,address2]]l [len] 
# 可显示 空格 tab,实现文本按照指定的宽度换行
sed -n 'l 25' books.txt
真正匹配引用 \x
1
2
3
# () () () ...  \1 \2 \3 ...用\x表示前面的括号内容
# 可显示 空格 tab,实现文本按照指定的宽度换行
sed -r 's/(^[a-z-_]+):x:([0-9]+):([0-9]+).*$/user:\1 uid:\2 gid:\3/' /etc/passwd罗列出用户名 uid gid
复制指定文件内容到匹配行 r
1
2
# 读取文件内容显示到指定行
sed -n '1r a.txt' b.txt
将匹配行写入到文件中 w
1
2
# 将demo.txt第一行写入到a.txt中
sed -n '1w a.txt' demo.txt
执行外部命令 e
1
2
# e 执行外部命令 比如 date
sed '3 e date' books.txt
排除命令 !
1
2
# 匹配Paulo的行不打印
sed -n '/Paulo/!p' books.txt
输出行号 =
1
2
# [address1[,address2]]=
sed '=' demo.txt
退出sed q
1
2
3
4
5
6
7
# 执行完第10行退出
sed -n '10q'

# q命令也支持提供一个value(作为程序的返回代码返回)

sed '/The Alchemist/ q 100' books.txt
echo $?
多行命令 P,D,N
1
2
3
4
5
6
# N:将数据流中的下一行加进来创建一个多行组来处理,N并不会清除、输出模式空间的内容,而是采用了追加模式
sed -n '10q'

# D:删除多行组中的一行,只删除模式空间中的第一行。该命令会删除到换行符(含 换行符)为止的所有字符

# P:打印多行组中的一行

参考:三十分钟学会SED

UTF-8 without BOM

发表于 2017-04-21 | 分类于 常见问题 |

今天遇到一个文件编码问题(非法字符\ufeff),导致代码异常;经过排查发现:文件编码是 UTF-8 + BOM,表现形式如下:

1
var a = '*{name:'test'}';

但是在编辑器(我用的sublime text)中看不到那个星号,在chrome源码显示面板中可以看到,于是设置文件编码sublime text : File > Set File Encoding to(或者保存utf-8编码),星号依然存在。

解决方案:
由于本机安装了Android studio,于是用AS打开该文件,设置编码文件为GBK ,然后设置为UTF-8(特殊字符会变成??去掉多余的?),即可去掉BOM。

在排除过程中也发现另外一个类似的问题:服务端json编码UTF-8 + BOM导致json解析报错。
解决方案:
设置服务端数据编码格式为UTF-8

linux进程资源信息

发表于 2017-04-17 | 分类于 linux |

Linux进程与资源管理

Linux最棒的地方在于它的多用户多任务环境,记录下多用户多任务相关的几个常用命令。

前后台进程及切换

有时候我们并不一定要在屏幕前工作,这时就需要使用到背景工作管理的一些指令,如 &,ctrl+z。

如果想让程序在背景下执行,可以使用 &,由于是背景,该程序的输入并不会显示在屏幕上。

语法格式: command &

1
2
3
4
5
# 程序进入背景执行
find / -name test &

# fg 将程序拉回屏幕前执行
fg

也可以通过 ctrl+z 将正在运行的工作丢到背景下,放在背景下的最大好处就是不会被 ctrl+c 指令中断。

如果出现某个时候需要暂时退出vim,但又不想保存退出,可 ctrl+z 暂时退出

1
2
3
4
5
# 程序进入背景执行
vim a.js

# 将vim放到背景中,并没有退出
ctrl+z

可使用 jobs 可以查看任务列表,配合 bg ,fg将程序拉回屏幕。

查看背景程序:jobs

1
2
3
4
5
6
# 查看背景程序
jobs
[1] + suspended vim a.js

# 恢复vim编辑
fg %1

fg & bg恢复背景进程

1
2
3
4
5
#number 为jobs中方括号中的编号
fg %number

#将背景程序中的程序由stopped变成running
bg %number

kill 杀掉背景程序中的程序

1
2
3
4
5
6
7
8
9
kill -signal %number
signal
-1 :重新读取参数配置(类似reload)
-2 :类似Ctrl+c中断工作
-9 :强制杀掉进程
-15 :停止一个工作(默认值)

#杀掉vim 进程
kill -9 %1

查看进程

ps 查看进程信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ps -aux
参数说明
a :显示所有程序
u :列出所有用户程序
x :列出所有tty程序

# 显示进程信息
ps -aux

USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
nali 2557 3.0 1.2 2832304 49180 ?? S 五04下午 4:54.94 /Applications/iTerm 2.app/Contents/MacOS/iTerm2
nali 920 1.6 0.8 2939412 34404 ?? S 四07下午 5:26.69 /Applications/QQ.app/Contents/MacOS/QQ

#干掉进程
kill -9 pid

另外一个显示进程的命令是 top 可动态显示。
查看内存使用:free
查看系统资源:sar

程序优先级

由于CPU资源有限,优先级高的程序会先获取CPU资源。

1
2
3
4
5
6
7
ps -l

UID PID PPID F CPU PRI NI SZ RSS WCHAN S ADDR TTY TIME CMD
501 9005 2557 4006 0 31 0 2507116 9148 - Ss 0 ttys001 0:00.07 /Applications/iTerm 2.app/Contents/MacOS/iTerm2 --server login

#PRI 代表程序优先级,越小越先被执行
NI 代表nice的值

PRI越小越优先被执行

PRI(new) = PRI(old) + nice

一般用户可用的nice值 0~19
root可用的nice值-20~19

调整程序的的优先级
nice [-n number] command

调整运行中程序的优先级
renice number PID

查看系统相关信息

uname 查看系统信息

1
2
3
4
5
6
uname 
参数信息:
-a :列出所有信息
-p :列出CPU信息
-r :列出核心版本信息
-n :列出版本信息

dmesg 查看启动一闪而过的信息

uptime 显示开机时间及负载相关信息

last 显示登录信息

hostname 显示主机名

who 查看当前系统上的用户(只列出用户名及登录时间)

w 查看当前系统上的用户(列出用户名及登录时间 + 源地址IP + 工作项 + ..)

whoami 显示当前登录用户名

ntpdate 网络校时

1
2
3
4
5
6
# 校时服务器 time.stdtime.gov.tw

# 执行校时命令
ntpdate time.stdtime.gov.tw

# 可配合crontab定时校时

tmux使用

发表于 2017-03-21 | 分类于 linux |

上篇讲到了 iTerm2的基本使用 ,iTerm2能够让我们迅速从不同的窗口中切换。通过 iTerm2 ,我们可以在不同窗口中愉快用 ssh 登录到远处服务器去操作,但由于临时断网或其他原因,远程连接就会中断,如想继续之前的工作,又得重头来过T_T ,但是iTerm2有个 tmux 的配合,再也不用担心异常中断了,它可以让我们迅速恢复到之前的现场环境。

tmux 窗格

tmux 是一个终端复用软件,它也有类似iTerm2的分屏功能。不仅如此,我们还可以通过tmux随时断开会话或者接入会话,接下一起来看下tmux 一些基本使用方法。

入门须知

  • server服务器:输入tmux命令时就开启了一个服务器,可以开启多个会话。
  • session: 管理多个window的会话
  • window: 一个window就是整个屏幕
  • pane: 一个window可以被横向或纵向分割为多个窗格

即一个session可包含多个窗口,一个窗口中可包含多个窗格。
一般情况下 tmux 中所有的快捷键都需要和前缀快捷键

+ b``` 来组合使用。
1
2
3
4
5


### 安装tmux
``` shell
brew install tmux

运行 tmux

开启了一个 tmux 的会话,默认会新建一个窗口和一个窗格,窗口左下角会有一些标识信息。

1
tmux

tmux默认窗口

会话常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#在正常终端模式下使用 tmux 建立会话并命名
tmux new -s abc

#休眠会话 返回主shell- 在正常终端模式下,使某个编号的会话强制休眠,编号用的是 tmux ls 命令时所列出的每一行的最前面的那个编号
tmux detach -t 编号
tmux detach -s 名称

#恢复会话
tmux attach -t 编号
## 也可简写成
tmux a -t 编号
tmux attach -s test

#重命名会话名称
tmux rename -t test dev

#关闭会话
tmux kill-session -t abc

# 完全退出,关闭所有的会话
tmux kill-server

窗口常用命令

假设当前默认前缀为 : Ctrl+b

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{前缀} c 创建新窗口

{前缀} n 选择下一个窗口

{前缀} p 选择前一个窗口

{前缀} l 最近一次活跃窗口之间进行切换

{前缀} 0~9 选择几号窗口

{前缀} , 重命名窗口

{前缀} . 更改窗口的编号,但只能更改成未使用的编号,所以要交换窗口的话,得更改多次进行交换

{前缀} & 关闭窗口

{前缀} w 以菜单方式显示及选择窗口

{前缀} f 在所有窗口中查找内容

窗格常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
{前缀} " 模向分隔面板

{前缀} % 纵向分隔面板

{前缀} o 跳到下一个分隔面板

{前缀} x 关闭面板

{前缀} ; 切换到最后一个使用的面板

{前缀} 上下键 上一个及下一个分隔面板

{前缀} 空格键 切换面板布局

其他

1
2
3
{前缀} t 显示时钟

{前缀} m 鼠标切换窗格

看到这里,尝试后是不是觉得很奇怪,自己打开的窗口,怎么和本页面第一张图不一样!不一样! 首先恭喜你已经掌握了tmux基本操作,接下来咱们看下tmux高级用法。

###高级配置
tmux 自定义配置参见 .tmux


tmux窗口左下角状态显示用到了Powerline及Powerline字体,接着咱们来美化下tmux窗口。

1.安装 Python

1
brew install python

2.下载 powerline

1
sudo pip install powerline-status

3.配置 Powerline 到终端

1
2
3
4
5
6
#查看安装路径
pip show powerline-status

#配置 .bash_profile 文件,添加以下行
. /Powerline安装路径/powerline/bindings/bash/powerline.sh
source .bash_profile

4.安装专用于 Powerline 的字体
然后在 iTerm 2的偏好设置里的Profile选项卡里把字体设置为以 Powerline 结尾的字体就大功告成了。

PS:如果满足不了你的操作体验,你还可以:
安装配色方案 solarized
安装zsh主题 agnoster-fcamblor

fabric快速入门

发表于 2016-02-14 | 分类于 python |

Fabric是一个Python库,用于简化使用SSH的应用程序部署或系统管理任务。

它提供的操作包括:执行本地或远程shell命令,上传/下载文件,以及其他辅助功能等。

安装

☞点我传送到fabric官网

安装fabric库

1
pip install fabric

依赖 Paramiko 、PyCrypto库

安装依赖

1
2
3
4
5
# 安装 pycrypto 密码库
pip install pycrypto

# 安装 pycrypto 依赖
pip install ecdsa

ps:【windows7 x64 ,python2.7 】Windows下pip安装包报错:Microsoft Visual C++ 9.0 is required Unable to find vcvarsall.bat ,可以安装Micorsoft Visual C++ Compiler for Python 2.7 。

fabric使用

新建py脚本:fabfile.py

1
2
3
4
5
def hello():
print("Hello world!")

def hi():
print("Hello world!")

执行fab命令:执行hello函数

1
fab hello

如果当前模块下没有fabfile.py文件,那么需要指定-f参数.

1
fab -f test.py hello

使用参数

1
2
def hello(name, value):
print("%s = %s!" % (name, value))

带参执行命令

1
fab hello:name=age,value=20

执行本地操作

1
2
3
4
5
from fabric.api import local, lcd

def lsfab():
  with lcd('~/tmp/fab'):
  local('ls')

执行远程操作

1
2
3
4
5
6
7
def setting_ci():
local('echo "add and commit settings in local"')

def update_setting_remote():
print "remote update"
with cd('~/temp'): #cd用于进入某个目录
run('ls -l | wc -l') #远程操作用run

多服务器操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env python
# encoding: utf-8

from fabric.api import *
env.roledefs = {
'testserver': ['user1@host1:port1',],
'productserver': ['user2@host2:port2', ]
}

@roles('testserver')
def task1():
run('ls -l | wc -l')

@roles('productserver')
def task2():
run('ls ~/temp/ | wc -l')

def do():
execute(task1)
execute(task2)

用不同颜色打印

1
2
3
4
5
6
from fabric.colors import *

def show():
print green('success')
print red('fail')
print yellow('yellow')

fabric 命令行工具

1
2
3
4
5
6
7
8
9
10
11
装饰器作用?
@task # 定义任务 @task(alias='dwm') fab --list
@parallel # 并行处理

命令行常用: fab --help
fab -l -- 显示可用的task(命令)
fab -H -- 指定host,支持多host逗号分开
fab -R -- 指定role,支持多个
fab -P -- 并发数,默认是串行
fab -w -- warn_only,默认是碰到异常直接abort退出
fab -f -- 指定入口文件,fab默认入口文件是:fabfile/fabfile.py

☞更多参考官网教程

javascript对象

发表于 2016-02-11 | 分类于 js |

创建对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 使用Object创建对象
var p = new Object();

p.name = 'jason';
p.sayName = function(){
alert(this.name);
}

//使用字面量的方式创建对象
var p = {
name:'jason',
sayName:function(){
alert(this.name);
}
}

属性类型

ECMAScript中有两种属性:数据属性,访问属性。

数据属性:是一个包含数据值的位置,有4个描述其行为的特性:

名称 值
configurable 表示能否通过delete删除属性而重新定义,默认true
enumerable 表示能否通过for-in循环返回属性,默认true
writable 表示能否修改属性的值,默认true
value 包含这个属性的属性值,默认undefined
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
/*修改属性的默认特性,使用Object.defineProperty(obj,propertyName,descriptor)方法
四个属性值:configurable、enumerable、writable、value
*/
var p = {};
Object.defineProperty(p,'name',{
writable:false,
enumerable:false,
configurable:false,
value:'chen'
});

p.name = 'jason'; // 非严格模式下,赋值会被忽略,严格模式,赋值会报错

/*定义多个属性使用Object.definePropertys()方法 */
Object.definePropertys(p, {
'name', {
writable: false,
enumerable: false,
configurable: false,
value: 'chen'
}, {
'age', {
writable: false,
enumerable: false,
configurable: false,
value: '18'
}
});

访问器属性:访问器属性不包含属性值,它们包含getter,setter函数(非必须)
该访问属性也有4个特性:

名称 值
configurable 表示能否通过delete删除属性而重新定义,默认true
enumerable 表示能否通过for-in循环返回属性,默认true
get 读取属性调用的函数,默认undefined
set 设置属性调用的函数,默认undefined
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
var book = {
_year:2016, // 私有属性常以 '_' 开头
edition:1
};


Object.defineProperty(book,'year',{
get:function(){
return this._year;
},
set:function(newValue){
this._year = newValue;
this.edition +=1;
}
});

使用访问器属性的常见方式即设置一个属性值会导致其他属性发生变化

另一种设置方式(遗弃的方法)
book.__defineGetter('year',function(){
return this._year;
});
book.__defineSetter('year',function(newValue){
this._year = newValue;
});

/* 读取属性的特性 Object.getOwePropertyDescriptor() 方法会返回描述对象 */
var descriptor = Object.getOwePropertyDescriptor(book,'year');

/* 返回 descriptor : {
value:'jason',
configurable:false
} */

创建对象的几种方式

工厂模式
1
2
3
4
5
6
7
8
9
10
11
function createGirlFried(name,job){
var o = new Object();
o.name = name;
o.job = job;
return o;
}

var girl1 = createGirlFried('shany','Dotor');
var girl1 = createGirlFried('kaer','Softwarn Engineer');

//没有解决对象识别的问题(对象的类型)

#####构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Person(name,job){
this.name = name;
this.job = job;
this.sayName = function(){
alert(this.name);
}
}

var p1 = new Person('zs','doctor');
var p2 = new Person('zs','doctor');

alert(p1.construtor == p2.construtor) // true
p1 instanceof Person // true
p1 instanceof Object // true

使用 new 操作符,调用构造函数创建对象,会经历以下4步

  1. 创建一个新对象
  2. 将构造函数的作用域赋给新对象(this 指向这个新对象)
  3. 执行构造函数中的代码(为这个对象添加新属性)
  4. 返回新对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//构造函数 当函数用
var p = Person('sy','你猜');
alert(window.name) // sy

// 构造函数的问题:不同示例上的同名函数是不相等的
function sayName (){
alert(this.name);
}

function Person(name,job){
this.name = name;
this.job = job;
this.sayName = sayName;
}
// 虽然函数一样,但污染了全局变量
原型模式

每个函数都有一个prototype属性,这是属性是一个指针,指向一个对象(即原型对象,包含共享的属性和方法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function Person(name,job){
this.name = name;
this.job = job;
}

Person.prototype.sayName = function(){
alert(this.name);
}

Person.prototype.name = 'susan';

var p1 = new Person('san','programmer');
p1._proto_ == Person.prototype // true

p1.name == san // true

虽然可以通过对象访问保存在原型中的值,却不能通过对象实例重写原型中的值,如果添加同名属性将屏蔽原型中的同名属性
如果依旧要访问原型的的同名属性,只能delete obj.propertyName (设置null undefined 无效)

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
Person.prototype.construtor == Person // true
Person.prototype.isPrototypeOf(Person) // true

检查一个属性是否是原型属性还是实例属性
hasOwnProperty('propName');
p1.hasOwnProperty('name') // true


// 遍历对象-两种方式使用in操作符( in / for in )
'name' in p1

for (var prop in p1) {
console.log(prop)
}

/* 使用for - in返回所有能通过对象访问的、 可枚举属性( 包含实例属 获取对象上所有可枚举的实例属性, 可使用ECMAScript5 的 Object.keys() 方法 Object.keys(p) 返回一个数组( 顺序和for - i 获取对象上所有可枚举的实例属性, 无论是否可枚举 Object.getOwePropertyNames() ps: construtor 是不可枚举的。*/

// 重写原型对象
Person.prototype = {
construtor: Person, // 虽说修正了 construtor 但此时的 construtor变成可枚举的,原生的construtor是不可枚举的
sayName: function() {
return this.name;
}
}

// 修复可枚举特性
Object.defineProperty(Person.prototype, 'construtor', {
enumerable: false
})

/* 原型的问题: 原型的最大问题是由其共享属性的本性导致的, 原型中的所有属性都是被实例共享, 这种共享对函数非常合适, 对包含基本数据类型的属性也说的过去, 然而对于引用问题就比较突出了 */

Person.prototype.friends = ['sam', 'shany'];
// friends 被所有实例共享, 修改某个实例会影响其他实例
组合使用构造函数和原型模式
1
2
3
4
5
6
7
function person(name) {
this.name = name;
this.friends = ['san'];
}
Person.prototype.sayName = function() {
alert(this.name);
}
动态原型模式
1
2
3
4
5
6
7
8
9
function person(name) {
this.name = name;
this.friends = ['san'];
if (typeof this.sayName != 'function') {
Person.prototype.sayName = function() {
alert(this.name);
}
}
}
寄生构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function Person(name, age) {
var o = Object();
o.name = name;
o.age = age;
return o;
}

var p = new Person('sam', 20);
// return 语句重写了构造函数的值

// 这个方式可在特殊情况下为对象创建构造函数

function MyArray() {
var arr = new Array();
arr.push.apply(arr, arguments);
arr.print = function() {
return this.join('-');
}
return arr;
}

var c = new MyArray('a1', 'a2');
alert(c.print());
稳妥构造函数
1
2
3
4
5
6
7
8
// 适合在一些安全的环境中, 没有公共属性, 其方法也不应用this

function Person(name, age) {
var o = new Object();
o.sayName = function() {
alert(name);
}
}
原型继承
1
2
3
4
5
6
7
8
function SuperType(name) {
this.name = name;
}

function SubType(name, age) {
SuperType.call(this, name)
this.age = age;
}
组合继承
1
2
3
4
5
6
7
8
// 常用的继承模式( 原型继承 父类方法无法继承过来)

function SubType(name, age) {
SuperType.call(this, name)
this.age = age;
}

SubType.prototype = new SuperType();
原型继承
1
2
3
4
5
6
7
8
9
10
// ECMAScript实现
function object(o) {
function F() {}
F.prototype = o;
return new F();
}

// ECMAScript中 Object.create(p,{
skill: 'js'
});
123
ccrsky

ccrsky

聚沙成塔,集腋成裘

26 日志
9 分类
16 标签
RSS
GitHub 知乎 微博
© 2020 ccrsky
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.4