博主在js上已经花费了很长时间,不禁深深地被其轻巧而强大的功能,以及优雅灵活的写法所折服,一直没找到机会来总结一下,正好把学习的东西做一个汇总
题外话
我始终认为,学习编程最好的方式就是去写,甭管写的怎样,也要去练习。
当初学完了数组,我记得自己是先把里面的每一个方法都敲了一遍,然后反复思考,通过这些方法,我能够做些什么?
很多语法我一开始也是很不理解的,然而在不断地运用过程中,慢慢地就开始明白过来了。只要抓住一个大方向,然后不断地练,就一定能深入理解!
正如国外一个有名的数学家所言,只有抓住了主树干,枝叶方面的细节便会奇迹般地丰富起来。
很多初学者,包括当年的我自己,总是觉得这个也要学,那个也要学,不敢直接去找工作,总想着全部学完了才行。可是呢,怎样算是个头呢,技术这东西日新月异。css3来了,一股脑儿跑去学css3,后来各种框架如雨后春笋般破土而出,ext.js,easy-ui,bootstrap,等等,面对各种各样的新框架,真的感觉时间不够。
其实,现在我个人感觉真不必这样,要知道,所有的js框架都是以js为源头,当自己js的功底足够牢固,那么就一切OK。我之前认识的一个朋友,从来没接触过bootstrap,后来公司要用,看了两三天直接就上手,用bootstrap来开发项目了。
js + css是根,真是如此的。
否则,你永远会觉得自己在学习,却不知道这样的目的是什么。所以,不管三七二十一,如果你现在还是一个处于迷茫求职阶段的毕业生,或者是刚培训完,那么,不用慌,先找一份工作干起来再说,在工作中慢慢积累。
不要害怕,觉得自己好多不懂,会不会有问题,真没关系的,不要企图把所有技术学完了再去找工作。
哈,闲话不多说,开始记录。
1.字符串相关
1.1 format方法
在各种编程语言中,字符串的format方法是比较常见的,以下通过js扩展的方式,实现了js版本的format方法。目前貌似还没有浏览器支持这一个方法。
if(!String.prototype.format ){ String.prototype.format = function() { var e = arguments; return this.replace(/{(\d+)}/g,function(t, n) { return typeof e[n] != "undefined" ? e[n] : t; }) }; }
例子:
1. var template = "今天的天气很{0},大家一起去{1}!"; 2. alert(template.format("晴朗","郊游"));
效果:
2.数组相关
1.2 forEach(callback,context) 操作数组中的每一个元素
ie9以上的浏览器,以及其他非IE浏览器都支持这一方法。
以下是兼容性的扩展写法:
/** forEach除了接受一个必须的回调函数参数,还可以接受一个可选的上下文参数(改变回调函数里面的this指向)(第2个参数)。 */ if (!Array.prototype.forEach && typeof Array.prototype.forEach !== "function") { Array.prototype.forEach = function(callback, context) { // 遍历数组,在每一项上调用回调函数,这里使用原生方法验证数组。 if (Object.prototype.toString.call(this) === "[object Array]") { var i,len; //遍历该数组所有的元素 for (i = 0, len = this.length; i < len; i++) { if (typeof callback === "function" && Object.prototype.hasOwnProperty.call(this, i)) { if (callback.call(context, this[i], i, this) === false) { break; // or return; } } } } }; }
例子:
var drinks = ['雪碧','可乐','脉动','红牛','农夫山泉']; var context = { str1 : '【', str2 : '】' }; drinks.forEach(function(item){ console.log(this.str1 + item + this.str2); },context);
效果:
这个方法在各大浏览器都得到了较好的支持。
1.3 indexOf(searchvalue,fromindex) 查询数组中某一个值的下标
ie9以上的浏览器,以及其他非IE浏览器都支持这一方法。以下是兼容性的扩展写法:
//获取某元素在数组中第一次出现的下标 if (!Array.prototype.indexOf) { Array.prototype.indexOf = function(searchElement, fromIndex) { var k; // 1. Let O be the result of calling ToObject passing // the this value as the argument. if (this == null) { throw new TypeError('"this" is null or not defined'); } var O = Object(this); // 2. Let lenValue be the result of calling the Get // internal method of O with the argument "length". // 3. Let len be ToUint32(lenValue). var len = O.length >>> 0; // 4. If len is 0, return -1. if (len === 0) { return -1; } // 5. If argument fromIndex was passed let n be // ToInteger(fromIndex); else let n be 0. var n = +fromIndex || 0; if (Math.abs(n) === Infinity) { n = 0; } // 6. If n >= len, return -1. if (n >= len) { return -1; } // 7. If n >= 0, then Let k be n. // 8. Else, n<0, Let k be len - abs(n). // If k is less than 0, then let k be 0. k = Math.max(n >= 0 ? n : len - Math.abs(n), 0); // 9. Repeat, while k < len while (k < len) { // a. Let Pk be ToString(k). // This is implicit for LHS operands of the in operator // b. Let kPresent be the result of calling the // HasProperty internal method of O with argument Pk. // This step can be combined with c // c. If kPresent is true, then // i. Let elementK be the result of calling the Get // internal method of O with the argument ToString(k). // ii. Let same be the result of applying the // Strict Equality Comparison Algorithm to // searchElement and elementK. // iii. If same is true, return k. if (k in O && O[k] === searchElement) { return k; } k++; } return -1; }; }
例子:
1. var index = drinks.indexOf('雪碧'); 2. alert(index);//0
类似的还有lastIndexOf,用于获取数组中某个元素最后一次出现的位置。如果数组没有这个元素,则返回-1。顺便贴上该方法的实现:
//获取某元素在数组中最后一次出现的下标 if (!Array.prototype.lastIndexOf) { Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/) { 'use strict'; if (this === void 0 || this === null) { throw new TypeError(); } var n, k, t = Object(this), len = t.length >>> 0; if (len === 0) { return -1; } n = len - 1; if (arguments.length > 1) { n = Number(arguments[1]); if (n != n) { n = 0; } else if (n != 0 && n != (1 / 0) && n != -(1 / 0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } } for (k = n >= 0 ? Math.min(n, len - 1) : len - Math.abs(n); k >= 0; k--) { if (k in t && t[k] === searchElement) { return k; } } return -1; }; }
过这两个方法,我们可以来做一些有意思的事情了。
比如,判断一个对象是否为数组?
IE9 以上的浏览器,已经支持通过Array.isArray()来验证一个对象是否为数组了。
比如:
1. var result = Array.isArray([]); 2. alert(typeof []);//object 3. alert(result); //true
那么,如果我们自己来实现,又该如何做呢?下面给出一个简单思路,简单模拟一下这个过程:
//首先,让我们来看一看数组的构造器是咋样的? console.log([].constructor.toString()); /* 打印出来是这样的: function Array() { [native code] } */
于是乎。。。
var Array = function(){ } Array.isArray = function(obj){ return obj.constructor.toString().indexOf('Array') != -1; } var result = Array.isArray([]); alert(result); //true
虽然取巧了点,不过目的确实达到了。
数组封装
通过数组的一些基本方法,我们可以开始自己模拟一下java中的ArrayList了,话不多说,贴上代码
//模拟ArrayList function ArrayList(){ var arr = []; //用于保存数据的数组 var length = 0; //数组的长度,默认为0 /** * 判断是否为空 */ this.isEmpty = function(){ return length == 0; } /** * 获取列表长度 */ this.size = function(){ return length; } /** * 判断对象中是否包含给定对象 */ this.contains = function(obj){ if(arr.indexOf(obj) != -1){ return true; } return false; } /** * 新增 */ this.add = function(obj){ length = length + 1; arr.push(obj); } /** * 删除 * 参数1 obj : 需要删除的元素 * 参数2 deleteAll: 是否全部删除,否则默认删除第一个匹配项 */ this.remove = function(obj,deleteAll){ var len = arr.length; for(var i = 0 ;i < len ;i++){ if(arr[i] == obj){ arr.splice(i,1); length = length - 1; if(!deleteAll){ break; } } } } /** * 根据索引获取对应的元素 */ this.get = function(index){ if(index > length - 1){ return null; } return arr[index]; } /** * 获取列表数组 */ this.toArray = function(){ return arr; } /** * 获取某一个元素的角标 * 如果只出现一次,就返回一个数字,如果大于一次,就返回数组 */ this.indexOf = function(obj){ var rstArr = []; var count = 0; for(var i = 0 ;i < length ;i++){ if(obj == arr[i]){ rstArr[count++] = i; } } if(count == 1){ return rstArr[0]; } return rstArr; } this.toString = function(){ return arr.toString(); } } //测试代码 var list = new ArrayList(); list.add('张三'); list.add('李四'); list.add('王五'); list.add('赵六'); list.add('王五'); console.log(list.size()); console.log(list.toString()); console.log(list.contains('张三')); list.remove('王五',true); //null,undefined,'' console.log(list.toString()); console.log(list.get(0)); console.log(list.get(1)); console.log(list.get(2)); console.log(list.size()); console.log(list.toArray()); list.add('张三'); list.add('张三'); console.log(list.toArray()); console.log(list.indexOf('张三')); console.log(list.indexOf('赵六'));
运行结果:
本章结束 ...