mackxu
子曰:学而时习之,不亦说乎?

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)

           }     

       }

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  判断下面的变量的值

  1.  

function abc() {

    aa = ‘global’;

}

abc();

alert(aa); //global

  1.  

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));

 

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     

    })();

}();

posted on 2013-02-27 22:31  mackxu  阅读(280)  评论(0编辑  收藏  举报