l //判断一个字符串中出现次数最多的字符,统计这个次数
//将字符串的字符保存在一个hash table中,key是字符,value是这个字符出现的次数
var str = 'fhsjdhfkhfkjdshfk';
var obj = {};
for(var i=0, len=str.length; i<len; i++) {
var key = str[i]; //出现的字符作为键值
if (!obj[key]) {
obj[key] = 1; //第一次出现
}else {
obj[key]++; //再次出现的字符
}
}
//遍历获得的table hash,获取value最大的key和value
var max = -1;
var max_key = null;
for (var key in obj) {
if (max < obj[key]) {
max = obj[key];
max_key = key;
}
}
for (var key in obj) {
debug(key+'=>'+obj[key]);
}
//----------------------------------
debug('max:'+max+' max_key:'+max_key);
l 求一个字符串的字节长度
//假设:一个英文字符占用一个字节,一个中文字符占用两个字节
function countStringBytes(str) {
var len = str.length; //字符个数
var bytes = len; //字符长度
for (var i=0; i<len; i++) {
if (str.charCodeAt(i)>255)
bytes ++;
}
return bytes;
}
l 去掉数组中重复的元素
Array.prototype.unique = function() {
var res = []; //消重后的数组
var o = {};
var len = this.length;
for (var i=0; i<len; i++) {
var elem = this[i];
//当elem属性不存在时,返回undefined.添加!变成true
if (!o[elem]) {
o[elem] = 1;
res.push(elem);
}
}
return res;
}
var arr = [1,13,5,2,3,4,3,2,5];
debug(arr.unique());
var a = undefined;
debug(!a); //true
//删除重复的数组元素
Array.prototype.distinct = function() {
var elems = {};
for(var i=0; i<this.length; i++) {
var elem = this[i];
if(!elems[elem]) {
elems[elem] = 1;
}else {
this.splice(i, 1); //在原数组上删除元素
i--;
}
}
};
var arr = [1, 2, 1, 3, 2, 1];
arr.distinct();
console.log(arr);
l 检查一个变量是String类型
function isString(str) {
return ((typeof str == 'string') || (str instanceof String));
}
l 点击页面中的任意标签,alert该标签的名称(处理兼容性)
document.onclick = function(event) {
var event = window.event || event;
var target = event.target || event.srcElement;
debug(target.tagName);
}
var url = 'http://www.baidu.com?key0=0&key1=1&key2= 2';
l 去掉字符串两边的空格
String.prototype.trim = function() {
return this.replace(/(^\s*)|(\s*$)/g, '');
}
l 解析查询字符串为一个对象
function parseQueryString(url) {
var params = {};
var arr = url.split('?');
//不存在查询字符串
if (arr.length < =1) {
return params; //返回空对象
}
arr = arr[1].split('&');
var param, key, value;
for (var index in arr) {
param = arr[index].split('=');
key = param[0].trim();
value = param[1].trim();
//此处还需要解码decodeURIComponent()
params[key] = value;
}
return params;
}
l //关于闭包的例子
<a href="#" id="anchor0">aaaaa0</a>
<a href="#" id="anchor1">aaaaa1</a>
<a href="#" id="anchor2">aaaaa2</a>
<script type="text/javascript">
function init() {
for (var i=0; i<3; i++) {
//也可以在外部调用函数,思想就是能够获取到i的副本
//闭包会获取所在函数变量的终值
//j存储了i每一个值的副本
(function(j) {
var anchor = document.getElementById('anchor'+i);
var text = anchor.innerHTML;
anchor.onclick = function() {
alert(text);
}
})(i)
}
}
l this之争
function Dog() {
this.dog_name = 'HaHa';
}
Dog.prototype.get_name = function() {
//return this.dog_name;
alert(this.dog_name);
}
function show_dog() {
var dog = new Dog();
/* 区分:
* dog.get_name() 单独运行
* 把dog.get_name做为事件处理器的区别
*/
//document.getElementById('btn').onclick = dog.get_name; //undefined
document.getElementById('btn').onclick = bind(dog, dog.get_name); //HaHa
}
//返回函数 把callback在object环境中执行
function bind(object, callback) {
return function() {
callback.apply(object, arguments);
}
}
show_dog();
l null和undefined的联系
var a;
console.log(typeof a == 'undefined');
console.log(a == undefined);
//undefined的值由null值派生出来
console.log(null == undefined);
console.log(a == null);
var b = null;
console.log(b == undefined); //true
l 判断下面的变量的值
function abc() {
aa = ‘global’;
}
abc();
alert(aa); //global
function abc() {
aa = ‘local’; //local
var aa; //代码提升
}
abc();
alert(aa); //ERROR: aa未定义
l 如果只判断对象是否存在,推荐使用
if (typeof myObj == ‘undefined’) {
var myObj = {};
}
如果除了判断对象是否存在,还要判断是否有null值
if(!myObj) {
var myObj = {}; //var 代码提升
}
//检测typeof对变量返回值
var a;
console.log(typeof a); //声明了a变量 undefined
console.log(typeof b); //未声明b变量 undefined
为了跨平台,建议避免使用window表示顶层对象
try...catch也可用来判断变量是否存在的方法
l JS中null和undefined容易参数混淆,在可能涉及到两者的情况下,可以用“精准比较”运算符
console.log(undefined == null); //true
console.log(undefined === null); //false;
l 自更新函数:
function selfUpdate() {
this.selfUpdate = function() {
console.log('updated!!');
}
console.log('self');
}
selfUpdate(); //self
selfUpdate(); //updated!!
l 下面的做法是错误的
//添加方法和属性
var CustomObject = function() {
//...
};
CustomObject.value = 5;
CustomObject.methodName = function() { console.log(this.value); };
CustomObject.methodName(); //5
//实例化一个对象
var newObject = new CustomObject();
newObject.methodName(); //TypeError: newObject.methodName is not a function
l 关于字面量对象添加方法的方式
var coreMethods = {
add: function(a, b) {
return a + b;
}
};
//会覆盖上面的add()函数
coreMethods.add = function(a, b) {
return a;
}
l 在构造函数中返回对象
var coreMethods = {
add: function(a, b) {
return a + b;
},
minus: function(a, b) {
return a - b;
}
//...
};
//继承上面的对象, 并返回对象
var SimpleMath = function() {
var oMethods = coreMethods; //继承coreMethods对象
//为oMethods对象添加新属性
oMethods.power = function(a, b) {
return Math.pow(a, b);
};
return oMethods; //返回对象
};
//new操作符 创建上下文环境对象 此时this对象指向SimpleMath对象
var oSm = new SimpleMath();
console.log(oSm.add(1, 3));
l for..in循环会遍历对象及其原型的方法和属性
function queryProperty(obj) {
//要想只输出属于目标对象自身的属性,应使用hasOwnProperty()
for(var prop in obj) {
if(obj.hasOwnProperty(prop)) {
console.log(prop);
}
}
}
l 加号的另一用处:
//1355992061494
console.log(+new Date()); //+可以把Date对象转化成数字,在后续的数学计算中就无须转换了
l 为函数添加默认参数值
//function add(a, b=1) 函数定义有错误:b=1
function add(a, b) {
var b = b || 1; //如果b不存在,获取其默认值
return a + b;
}
console.log(add(2, 4));
l JS中两个感叹号的作用
var a;
console.log(a == false); //false
console.log(undefined == false); //false
console.log(null == false) //false
//!!把undefined、null类型准化成布尔值false
console.log(!!undefined == false); //true
console.log(!!null == false) //true
console.log("" == false) //true
console.log(0 == false) //true
console.log(!!a); //false
console.log(a); //undefined
l JS中没有块级作用域, JS程序先解析后执行, 变量和函数在解析时被声明
if(!('a' in window)) {
var a = 1; //变量a在解析时被声明,因此if语句条件为false
}
console.log(a); //undefined
l 命名函数表达式不在变量对象上添加标识符(IE认为是函数声明, 但会被同名赋值的变量覆盖)
在JS程序解析时函数声明会覆盖同名的变量声明,但函数声明会被同名赋值的变量覆盖
var a = 1;
var b = function a(x) {
x && a(--x);
};
console.log(a);
-------------------------------------------------
function a() { //该函数解析时被无视了
console.log('...');
}
var a; //变量a无关是否初始化赋值
a = 1;
console.log(typeof a); //number
-------------------------------------------------
function a(x) {
return x * 2;
}
var a; //解析时被无视了
console.log(typeof a); //function
l arguments对象和命名参数指向不同的内存地址,对待传递的实参两者会实时保持一致
function b(x, y, a) {
arguments[2] = 10;
console.log(a);
}
b(1, 2, 3); //10
b(1, 2) //undefined
-------------------------------------------------------------
l 赋值变量会无视下面的同名变量声明, 不要被声明变量时会自动赋值为undefined迷惑
function b(x, y, a) {
arguments[2] = 10;
var y; //被无视了
console.log(y); //2
}
b(1, 2, 3);
//和上面的等价
var c = 1;
var c;
console.log(c); //1
l call()函数的用法
var b;
function a() {
console.log(this);
}
//下面的三种方式this对象都将指向window对象
a.call(undefined);
a.call(null);
a.call(b);
判断传递的参数是元素还是元素集合
例如:function addClass(element, className) { ... }
判断element是集合还是单个元素
if(element != null) { //避免传递不存在的元素,但对空集合无效
var len = element.length;
//len取值的可能情况len>=0 及undefined
if(len === undefined) {
//对元素处理
}else {
//对元素集合处理
}
}
在JS中最好不要有连等操作
var b = 'abc';
function test() {
var a = b = 3; //b是全局变量, a是局部变量
}
test();
console.log(b); //3
length属性三种作用
1、 返回字符串的长度(字符个数)
2、 设置或返回数组元素的个数
3、 返回函数的形参个数
试一试
new function A(){
console.log(this); //A
//eval()不会改变执行环境
eval('console.log(this)'); //A
(function() {
//匿名函数在window对象上执行
console.log(this); //window
eval('alert(this)'); //window
})();
}();