Object-Oriented JavaScript笔记(三)

Object-Oriented JavaScript 笔记
Object-Oriented JavaScript笔记(一)
Object-Oriented JavaScript笔记(二)
Object-Oriented JavaScript笔记(三)
Object-Oriented JavaScript笔记(四)
Object-Oriented JavaScript笔记(五)
Object-Oriented JavaScript笔记(六)
Object-Oriented JavaScript笔记(七)

第四章 对象

对象
对象属性名需要引号括起来的情况有:
1.保留字2.包含空格或特殊字符3.以数字开头
Best Practice Tip: No quotes
1.使用点访问符访问方法和属性
2.在对象字面量中不要使用引号将属性括起来

构造函数
按照约定,构造函数首字母大写

不使用new操作符调用构造函数跟调用普通函数无异,此时this指针指向全局对象global object

JavaScript 是运行在宿主环境中的,其提供一个全局对象,所有的全局变量都是全局对象的属性。
在浏览器中,该全局对象是window,如
>>> var a = 1;
>>> window.a
1

instanceof操作符用于测试对象的构造函数
注:原书103页的h instanceof Object;得到false实际上是印刷错误, Object是基类

特例:
>>> Object.prototype instanceof Object;
false
>>> Object instanceof Object;
true
说明Object.prototype可能是内置类型
函数返回对象,可以用该特性来改变this指针
function Test = function(){ this.name = ‘Tom’;
return {‘name’:’Tony’};
}

传入函数的对象是按引用传递的,将对象赋值给其他变量也如此,这意味着只是变了别名,修改引用对象也会改变原对象。

指向同一对象的变量比较时才会返回true,即使比较两个对象包含相同的方法和属性得到的也是false。

内置对象

内置对象可以分为三组:
1.数据包装类的 — Object, Array, Function, Boolean, Number, and String
2.工具类的 — Math, Date, RegExp
3.异常类的 — Error

对象构造方法:
1.使用构造函数
var o = new Object();

2.使用字面量
var o = {};

简单对象valueOf方法返回的是自身
>>> var o = {};
>>> o.valueOf() === o
true

继承自Object的对象会带上
o.constructor
o.toString()
o.valueOf()

数组对象

数组对象构造方法:
1.使用构造函数
var a = new Array();

2.使用字面量
var a = [];

数组构造函数传入单个数字的话,定义的是数组的长度;但使用字面量方式不存在该问题。
>>> var a2 = new Array(5);
>>> a2
[undefined, undefined, undefined, undefined, undefined]

>>> var a = [5];
>>> a
[5]

数组的常用方法
1.pop 取出最后一个
2.push 插入元素到尾端
3.sort 对数组元素排序
4.join 将内容转换成字符串
5.slice 切片,不改变原对象
6.splice 切片(或替换),改变原对象

函数
Function构造函数实际上使用了eval来计算传入的字符串,尽量避免使用它。
>>> var second = new Function(‘a, b, c’, ‘d’, ‘return arguments;’);
>>> second(1,2,3,4);
[1, 2, 3, 4]

Function有一个length属性,用来返回函数的参数个数。

Function还有一个caller属性,它不是ECMA标准里面的,但浏览器都实现了它。

实例会可以调用构造函数prototype中属性和方法。

Function的toString方法返回其source code.

call和apply方法可以将对象自己的方法借给其它对象使用。

arguments是个类数组;arguments.callee指向自身。

arguments.callee可以帮助匿名函数调用自身(递归调用):

(function(count){
if (count < 5) {
console.log(count);
arguments.callee(++count);
}
})(1);

Boolean对象

Boolean对象几乎没有用。在不使用new操作符的情况下,它将非布尔值转换成布尔值,这于使用!!value是等效的。
>>> Boolean(‘test’) == !!’test’
true

Number对象

Number对象比较有趣一点,它有一些有意思的属性:
Number.MAX_VALUE
Number.MIN_VALUE
Number.POSITIVE_INFINITY
Number.NEGATIVE_INFINITY
Number.NaN

Number对象提供三个内置方法:toFixed() 小数点位数
toPrecision() 精度
toExponential() 科学计数法

Number对象的toString方法也是很有趣的,可以传入一个[2~36]之间的整数表示要转换的进制。
>>> (9).toString(2)
“1001”

String对象

原始的string和String对象是不同的
>>> var primitive = ‘Hello’;
>>> typeof primitive;
“string”

>>> var obj = new String(‘world’);
>>> typeof obj;
“object”

因而
>>> Boolean(“”)
false
>>> Boolean(new String(“”))
true

String对象带有一些有用的方法,string类型不带有这些方法和属性,但是在普通类型上调用这些方法的时候,JavaScript将其作为对象对待。

Math/Date

Math/Date/RegExp都是工具对象
Math不是构造函数,不能使用new操作符
Date有两个静态方法
Date.parse(‘Jan 1, 2008’)
Date.UTC(2008, 0, 1)

RegExp

RegExp正则表达式采用的是Perl 5语法
RegExp的几个属性global 全局
ignoreCase 大小写敏感
multiline 多行
lastIndex 开始位置
source 正则表达式

除lastIndex外其余都是只读。

异常
几种内置异常对象,都继承自Error
EvalError
RangeError
ReferenceError
SyntaxError
TypeError
URIError

抛出异常throw new Error(‘Custom Error’);
-EOF-

Object-Oriented JavaScript笔记(二)

Object-Oriented JavaScript 笔记
Object-Oriented JavaScript笔记(一)
Object-Oriented JavaScript笔记(二)
Object-Oriented JavaScript笔记(三)
Object-Oriented JavaScript笔记(四)
Object-Oriented JavaScript笔记(五)
Object-Oriented JavaScript笔记(六)
Object-Oriented JavaScript笔记(七)

第三章 函数

JavaScript会给定义了但是没有传值的参数赋值为undefined,若是参数多于定义的,会被忽略。

没有函数都会带有一个名为arguments的类数组变量,包含所有传入的参数信息。

JavaScript内置函数(Pre-defined Functions):
parseInt()
parseFloat()
isNaN()
isFinite()
encodeURI()
decodeURI()
encodeURIComponent()
decodeURIComponent()
eval()

使用parseInt时最好每次都明确指定第二个(基数)参数,如 parseInt(‘FF’, 16)

parseFloat只接受一个参数,并能够识别指数表示法,如 parseFloat(‘123e2’)

escape() 与 unescape() 已经被弃用,不应该再被使用。

alert并不是JavaScript的一部分,并且它会阻塞浏览器线程,在富ajax应用中不应该使用它。

未使用var 声明的变量会被分配到全局作用域
>>> var f = function(){test = 2;};
>>> test
ReferenceError: test is not defined
>>> f();
>>> test
2

函数中声明的局部变量与全局变量同名会覆盖同名全局变量,即使是先使用后声明。

var a = 123;
function f() {
console.log(a);
var a = 1;
console.log(a);
}
f();

匿名函数

不仅是字符串,一些常量写在代码中也是可以的

"test"; [1,2,3]; undefined; null; 1;

ECMAScript 5严格模式(Strict Mode)便是利用该特性

'use strict';

Lexical Scope 函数工作在定义时的作用域,而非执行作用域。它仅能访问自己的作用域和全局作用域。

>>> function f1(){var a = 1; f2();}
>>> function f2(){return a;}
>>> f1();
a is not defined

闭包Closure的常用场景
如:循环、get/set访问器、迭代器
-EOF-

[Mac OS X]Lion编译安装mod_python

期望情况是下载好mod_python后执行编译并安装就能够搞定。

$ ./configure –with-apxs=/usr/sbin/apxs
$ make
$ sudo make install

但是事实却不尽人意,在Mac OS X Lion可能会遇到下面这个错误:

connobject.c:142: error: request for member ‘next’ in something not a structure or union
apxs:Error: Command failed with rc=65536

说明connobject.c这个文件中142行有错误,我们找到并打开它

vim src/connobject.c

将142行处的

!(b == APR_BRIGADE_SENTINEL(b) ||

改为

!(b == APR_BRIGADE_SENTINEL(bb) ||

-EOF-

简单静态资源分发脚本

网站静态资源太多的情况下有时候我们需要分成多个域名来请求这些静态资源。
如原来我们使用的

http://static.ioio.name/upload/hello.jpg

改成随机的使用

http://s1.ioio.name/upload/hello.jpg
http://s2.ioio.name/upload/hello.jpg
http://s3.ioio.name/upload/hello.jpg

这时候我们需要将s1/s2/s3服务器上的文件跟源服务器static同步。以使得他们都是访问的static上同名文件的拷贝。

这里我写了一段简单的php脚本采用溯源的策略来更新这些文件,当s1/s2/s3服务器上不存在该文件的时候,就向源服务器(static)请求该文件,并且保存在本地cache一份以便后续的相同请求使用。

1.在s1/s2/s3服务器上添加名为cdn.php的文件,内容如下:

<?php
$path = $_GET["name"];
$filename = md5($path);
$file = "save/".$filename.".data";
if(file_exists($file)){
header('Content-type: '.mime_content_type($file));
echo file_get_contents($file);
}else{
$content = file_get_contents("http://source.ioio.name/upload/".$path);
file_put_contents($file,$content);
header('Content-type: '.mime_content_type($file));
echo $content;
}
?>

这段脚本会将读取到的文件存在本地的save文件夹里,需要save文件夹的读写权限。

2.配置.htaccess文件,添加一行记录:

RewriteRule ^upload/(.*)$ /cdn.php?name=$1 [L]

这样配置后s1/s2/s3就能按照static的路径规则访问到相同的文件了。在实际的生成环境,可能会需要更复杂的cache策略,这里就不深入讨论。
-EOF-

Object-Oriented JavaScript笔记(一)

Object-Oriented JavaScript 笔记
Object-Oriented JavaScript笔记(一)
Object-Oriented JavaScript笔记(二)
Object-Oriented JavaScript笔记(三)
Object-Oriented JavaScript笔记(四)
Object-Oriented JavaScript笔记(五)
Object-Oriented JavaScript笔记(六)
Object-Oriented JavaScript笔记(七)

第二章 基本数据类型、数组、循环和条件语句

变量是大小写敏感的

基本类型

基本类型(5类) Number、String、Boolean、Undefined、Null
除了基本类型外的,都是object,特例
>>> typeof null
“object”

Infinity是number类型的
>>> typeof Infinity
“number”

JS中最大的数是1.7976931348623157e+308 最小的分数是5e-324

非0数除以0得到Infinity,0除以0得到NaN
1/0 = Infinity
0/0 = NaN

Infinity 与非NaN运算值为Infinity
Infinity – 1 = Infinity

NaN 与任何number运算值为NaN

一个String与一个变量做除’+'(加)以外的运算,都会转换成做数学运算
>>> var s = ‘3’; s = 3 * s; typeof s;
“number”

>>> var s = ‘3’; s = 3 + s; typeof s;
“string”

两次逻辑非操作会做强制布尔转换。大部分情况都是为真,除非:
1.空字符串 ”
2.null
3.undefined
4.数 0
5.数 NaN
6.布尔值 false

利用惰性求值(Lazy Evaluation)做保护伞并不是处处受用
var mynumber = mynumber || 10;

如果预先定义的 mynumber =0 ,这里就不是我们所预料的了。

=== 值与类型比较
!== 不含类型转换的不等于比较

NaN不与任何值相等,包含其自身
>>> NaN == NaN
false

null值并不是由js环境给分配的,而是由代码给分配的
>>> var value = null;
>>> typeof value
“object”

undefined与null还是大差别虽然微小,但是不容忽视
>>> var i = 1 + undefined;
>>> i
NaN

>>> var i = 1 + null;
>>> i
1

这种差异发生在类型转换上
>>> var i = 1*undefined;
>>> i
NaN

>>> var i = 1*null;
>>> i
0

数组

数组新添加元素索引跟数组最大索引之间有空隙的话,会被undefined值填充
>>> var abc = [1];
>>> abc[3] = 5;
>>> abc
[1, undefined, undefined, 5]

删除数组中的元素并不会改变数组大小,仅将删除位置为undefined
>>> var a = [1, 2, 3];
>>> delete a[2];
>>> a
[1, 2, undefined]

可以使用数组下标的形式访问字符串
>>> var s = ‘one’;
>>> s[0]
“o”

循环和条件语句

通常情况下我们会把变量放if条件中做检查,但这样做并不一定妥当,变量可能存在但值为false
>>> var result = ”;>>> if (somevar){result = ‘yes’;}
somevar is not defined
>>> result;
“”
一种更好的方式
>>> if (typeof somevar !== “undefined”){result = ‘yes’;}
>>> result;
“”

default是可以放在switch里任意位置的,并不一定是最后

var a = 4;switch(a){
case 1:
console.log(1);
break;
default:
console.log('d');
break;
case 6:
console.log(5);
break;
};

-EOF-