第六章 数组
在JS中数组和对象实质都是对象,数组的属性是连续的整数。typeof(Array) = ‘object’
// 判断数组的方法
var is_array = function(value) {
return value && typeof value === 'object' && value.constructor === Array;
};
// 不足:识别不同的window或者frame失败
//改进方法
var is_array = function(value) {
return Object.prototype.toString.apply(value) === '[object Array]';
}
数组中的方法存放在 Array.prototype 中,对象 Object.prototype 可以被扩充,数组的原型方法也可以被扩充。
Array.method('reduce', fucntion(f, value){
for (let i = 0; i < this.length; i ++){
value = f(this[i], value);
}
return value;
});
// 给数组扩展方法:传入一个函数和初始值,对数组的每一项运行函数。下面是实际案例。
let data = [1, 2, 3, 4];
var add = function(a, b) {
retunr a + b;
}
var mult = function(a, b) {
retunr a * b;
}
var sum = data.reduce(add, 0);
// 将数组执行add方法,初始值是0
var prodect = data.reduce(mult, 1);
// 将数组执行mult方法,初始值是1
一个数组可以通过下标设置属性,同时可以直接使用点语法设置属性。可以说,array.length 就是类似的对象的点语法。
JS 数组没有多维数组,支持元素为数组的数组,这里我们构造一个矩阵。
Array.matrix = function(m, n, init) {
var mat = [];
for (var i = 0; i < m; i++) {
a = [];
for (var j = 0; j < n; j++) {
a[j] = initial;
}
mat[i] = a;
}
return mat;
}
var myMatrix = Array.matrix(4, 4, 0);
document.writeLn(myMatrix);
// 生成一个0填充的 4*4 的矩阵。
// 单位矩阵
Array.identity = function(n) {
let mat = Array.matrix(n, n, 0);
for (let i = 0; i < n; i++) {
mat[i][i] = 1;
}
return mat;
};
myMatrix = Array.identity(4);
document.writeln(myMatrix[3][3]);
第七章 正则表达式
正则表达式书写很复杂,后期维护相对复杂。写的时候最好是短小精悍。
var parse = /^(?:[A-Za-z]+)?(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
// 划分网址
第九章 方法
Array
Array.concat 将多个数组,变量组合成一个新的数组。这个数组会浅复制一个数组,并将其他元素或者数组插入到新数组后面。
Array.join(seperator) 将数组的不同元素连接成字符串,原理是将每一项转化成一个字符串,将这些字符串连接。
Array.pop() 移出数组中的最后一个元素并返回(类似于堆栈stack),如果是空数组,那么返回undefined。
Array.push(item1, item2)在数组最后添加一个元素,原始数组改变,返回值是新数组的长度。
Array.reverse() 数组前后翻转,原始数组变成新数组,返回值就是新数组。
Array.shift() 移出数组的第一个元素(空数组返回undefined)shift 比 pop 速度慢很多。
array.unshift 在第一位增加元素,返回值是新数组的长度
array.slice(a, b) 浅复制数组的一部分,前面试闭区间后面是开区间;如果只有一个参数,表示从这个参数复制到数组的末尾。=>复制旧数组中的一部分
Array.sort() 字符串排序:可以给字符串进行排序,不能直接给数组排序(首先将数组转化成字符串,对字符串进行比较,通常会出错);当然,可以在此基础上,增加一个数组排序或者对象排序的方法。
Array.splice(a, b, c) 删除数组的一部分:将数组的a位置,删除b个元素,加入c元素。(c可选参数)
var a = [1, 2, 3];
var b = [4, 5, 6];
var c = a.concat(b, true);
a.push(6,7); // 这里改变数组a, 不会影响新的数组c。因为已经产生了新的数组c。
console.log(c);
// [1,2,3,4,5,6,true]
Function
// function.apply 传递一个绑定到 this 上的对象和一个可选的数组作为参数。
Function.method('bind', function(that) {
// 返回一个函数。调用这个函数就是调用这个对象的一个方法
var method = this;
var slice = Array.prototype.slice;
var args = slice.apply(arguments, [1]);
return function() {
return method.apply(that,
args.concat(slice.apply(arguments, [0])));
};
});
let x = function() {
return this.value;
}.bind({ value: 666 });
alert(x());
数组的 call 和 apply :将一个对象的方法放在另一个对象上面,另一个对象可以使用这些方法。
Obj1.method1.call(Obj2, para1, para2); object 具有method1 方法,但是 object2 没有method1方法。所以这里Object2 借用object1 的method 方法,然后传入的参数是两个,进行继承。
Obj1.method2.apply(Obj2, [para1, para2]) apply 传入的参数是一个数组,其他的功能和效果类似。
详见 call.js 代码
Number
数值转化成不同字符串的几种方法
// toExponential() 转换成一个指数形式的字符串;
Math.PI.toExponential(2); // 3.14e+0
// toFixed 转化成一个十进制数的字符串,参数是小数点后的位数
Math.PI.toFixed(5); // 3.14159
// toPrecision 转化成一个十进制的字符串,参数是数字的精度
Math.PI.toPrecision(3); // 3.14
// toString(16) 转化成一个字符串,参数是转换的进制,默认是10
Math.PI.toSting();
Object
object.hasOwnProperty 这个方法可以监测对象的属性,但是原型链中的同名属性不会检查;
var a = {isLoading: true};
a.hasOwnProperty('isLoading') => true
var b = Object.create(a);
// 创建一个新对象b,其中的__proto__ 就是a, b对象可以访问a对象原型链上的方法和属性
b.hasOwnProperty('isLoading') => false
console.log(b.isLoading) => true
RegExp 正则表达式
exec
匹配字符串的最强大最慢的方法。如果匹配正则表达式,就返回一个数组,数组不同的项就是分组捕获的文本。如果匹配失败,就会返回 null。如果全局检索g,查找不会从这个字符串的开始位置,而是从regexp.lastIndex 开始。如果进行另一次查询,需要将 regexp.lastIndex 重置为0。
// 将HTML文本分解成标签和文本
var text = '<html><body bgcolor=linen><p>' + '</p></body></html>';
var tags = /[^<>]+|<(\/?)([A-Za-z]+)([^<>*])>/g;
var a, i ;
while ((a = tags.exec(text))) {
for (i = 0; i < a.length; i++) {
console.log((i + a[i]).entityify());
}
}
test
匹配正则表达式最简答的方法,如果正则表达式匹配字符串,返回的是布尔值,不能使用全局的g标识。
var b = /&.+/.test('Tom & beans');
RegExp.method('test', function(string) {
return this.exec(string) !== null;
});
string
字符串的方法是最常用的方法
string.charAt(position); // 返回字符串中某个位置的字符,如果位置超过长度或者是负数,那么返回一个空字符串
string.charCodeAt(pos); // return 字符码位 if(pos > string.length) return NaN
string.concat('a', 'b'); //通常直接加号链接字符串即可
string.indexOf('test', 10); // 从位置10开始检错,查询test字符串,返回第一个匹配字符的位置,找不到返回-1
string.lastIndexOF('test', 3); // 从末尾开始查找
string.match(regexp) //让字符串和一个正则表达式进行匹配,依据g标识来决定怎样进行分配。如果没有g, string.match(regexp) 和 regexp.exec(string) 结果相同。如果regexp具有g标识,那么返回一个匹配的数组。
string.replace('search', 'replace'); // 如果标明g,就是替换第一个匹配的字符。
string.search(regexp); // 类似于indexOf 传入的参数是正则表达式,返回第一个匹配字符的首字符位置(没有position参数)
var text = 'hello world "anynone" tall';
var position = text.search(/["']/);
string.slice(start, end); // 复制string的一部分构造一个新的字符串。如果是负数,就从后面开始;默认end是string.length.
string.split(seperator, limit); // 将字符串按照分隔符分割成片段,并创建一个字符串数组。limit表示分割片段的数量。分隔符可以使字符串或者是正则表达式。如果分隔符是空字符,返回单字符的数组。
var ip = '192.168.0.1';
var b = ip.slice('.'); // ['192', '168', '0', '1']
string.toLowerCase();
string.toUpperCase();
string.fromCharCode(char...); //根据数字编码创建一个字符串
截取一个字符串的方法:最好使用slice, 不要使用substring 因为后者无法使用负数;
第九章 代码风格
JS 对代码格式要求不要,容错性很高,这样可能造成bug。多写一个大括号可能避免if的作用范围。写合适的注释并及时更新注释(代码会更新,注释也需要更新)。详细的代码风格可以参考《代码整洁之道》这本书。
第十章 优美的特性
函数是顶级对象
函数具有词法作用域的闭包(lambda)
基于原型继承的动态对象
对象是无类别的。一个对象可以通过普通的赋值增加一个新成员属性;一个对象可以从另一个对象继承成员属性。
对象字面量和数组字面量
便捷的创建对象和数组(来源于JSON)