一个javascript题目

前几天在QQ群里abcd(他的微博)同学出了一个题目,挺有意思,这里贴一下

[code lang=”js”]
var a = 1;
var b = {
a: 2,
b: function() {
alert(this.a);
}(),
f: this.f = function() {
alert(this.a);
}
};
function f() {
alert(3);
}
f();
b.f();
(b.f)();
(0, b.f)();
[/code]

结果是五次alert输出 1  1  2  2  1

你答对了吗?知道为什么吗?……假装自己有读者%>_<%

JavaScript concat() 方法

定义和用法

concat() 方法用于连接两个或多个数组。

该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。

语法

arrayObject.concat(arrayX,arrayX,......,arrayX)

下面用利用concat写个快速排序

[code lang=”js”]
function qsort(arr){
if(arr.length<=1){
return arr;
}
var pivot = Math.floor(arr.length/2);
var pivotItem = arr.splice(pivot,1);
var left = [], right= [];
for(var i in arr){
if(arr[i]<pivotItem){
left.push(arr[i]);
}else{
right.push(arr[i]);
}
}
left = arguments.callee(left);
right = arguments.callee(right);
return left.concat(pivotItem,right);
}
//example
var b = [1,4,2,9,7,5];
b = qsort(b);
console.log(b);//[1,2,4,5,7,9]
[/code]

Javascript 单例模式

内容非原创,纯笔记

单例模式一般是为了防止一个对象(类)被多次实例化所采用的一种手段,也就是说只有一个实例的,比如php中也会有单例模式 PHP单例模式

在javascript中,是以对象字面量的方式来创建单例对象的,也就是以花括号包裹起来的键值对的JSON形式来创建的。

ex:

[code lang=”js”]
var single_ex ={
name:’jim’,
dosomething:function(){

}
}
[/code]

 模块模式则是用来为单例创建私有变量和特权方法(公有方法),从而能增强单例的可访问性。以模块模式定义的私有变量和私有函数只有单例对象本身的特权(公有)方法可以访问到,其他外部的任何对象都不可以。

下面写一个简单的dragdrop 效果的代码 用到了单例模式

[code lang=”js”]
<div class="draggable" style="position:absolute;width:200px;height:200px;"></div>
<script type="text/javascript">
var DrogDrop = function(){
var dragging = null;
var diffX = 0;
var diffY = 0;
function handleEvent(event){
var target = event.target;
switch(event.type){
case ‘mousedown’:
console.log(target);
if(target.className.indexOf("draggable") > -1){
dragging = target;
}
diffX = event.clientX – target.offsetLeft;
diffY = event.clientY – target.offsetTop;

break;
case ‘mousemove’:
if(dragging!=null){
dragging.style.left = (event.clientX – diffX) + ‘px’;
dragging.style.top = (event.clientY -diffY) + ‘px’;
}
break;
case ‘mouseup’:
dragging = null;
break;
}
}

return {
enable:function(){
document.addEventListener(‘mousedown’,handleEvent,false);
document.addEventListener(‘mousemove’,handleEvent,false);
document.addEventListener(‘mouseup’,handleEvent,false);
},
disable:function(){
document.removeEventListener(‘mousedown’,handleEvent,false);
document.removeEventListener(‘mousemove’,handleEvent,false);
document.removeEventListener(‘mouseip’,handleEvent,false);
}
}

}();
DrogDrop.enable();
</script>
[/code]

Javascript 事件代理

日常写javascript代码的时候经常会添加一些事件处理程序,但是事件处理程序的多少直接会影响web页面的性能。在加载页面的时候这些处理程序是要加载在内存中的,事件处理程序越多占用的内存越多;而且在绑定时间处理程序的过程中会查找dom元素,也会影响性能;“每当一个事件处理程序绑定一个元素的时候,运行中的浏览器代码与支持页面交互的javascript代码之间就会建立一个连接,连接越多,页面的执行速度越慢”。

所以解决事件处理程序太多的办法就是事件代理,事件代理利用了事件的冒泡原理,比如一个li标签接收到了一个click 事件 ,这个事件由于冒泡原理会被这个li标签的父元素,父元素的父元素… 接收到。 利用这个,我们可以在较高层次的元素上指定一个时间处理程序,从而可减少事件处理程序的数量。

ex:

[code]
<ul id="pa">
<li id="item1">baidu</li>
<li id="item2">google</li>
<li id="item3">bing</li>
</ul>
[/code]

常见的做法

[code lang=”js”]
var item1 = document.getElementById(‘item1’);
var item2 = document.getElementById(‘item2’);
var item3 = document.getElementById(‘item3’);
item1.onclick = function(){
location.href = "http://baidu.com";
}
item2.onclick = function(){
location.href = "http://google.com";
}
item3.onclick = function(){
location.href = "http://bing.com";
}
[/code]

通过事件代理的做法

[code lang=”js”]
var pa = document.getElementById(‘pa’);
pa.onclick = function(e){
var target = e.target;
switch(target.id){
case ‘item1’:
location.href = "http://baidu.com";
break;
case ‘item2’:
location.href = "http://google.com";
break;
case ‘item3’:
location.href = "http://bing.com";
break;
}
}
[/code]

JavaScript 的parseInt()函数

今天写了一小段js 代码,有bug,查了下原来是parseInt()函数使用出错。

parseInt(’09’) 返回值是0

parseInt(’09’,10) 返回值是9

我没有写参数10,直接导致函数直接返回了字符串的第一个数字

上网查了一下parseInt函数的用法,查到的结果如下:

parseInt(string, radix)
string 必需。要被解析的字符串。
radix 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。

如果省略该参数或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。

如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。

返回值

返回解析后的数字。

说明

当参数 radix 的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。

举例,如果 string 以 “0x” 开头,parseInt() 会把 string 的其余部分解析为十六进制的整数。如果 string 以 0 开头,那么 ECMAScript v3 允许 parseInt() 的一个实现把其后的字符解析为八进制或十六进制的数字。如果string 以 1 ~ 9 的数字开头,parseInt() 将把它解析为十进制的整数。

提示和注释

注释:只有字符串中的第一个数字会被返回。

注释:开头和结尾的空格是允许的。

javasript函数中初始化变量容易犯的错

在javascript函数中,如果变量在未经声明的情况下初始化,那么该变量会自动被添加到全局环境中。

———————–

function add(num1,num2){

sum=num1+num2;

return sum;

}

 

var result = add(10,20);//30

alert(sum);//30

———————————————

这个例子中的变量sum在被初始化赋值时没有使用var关键字。于是当调用完add()后,添加到全局环境中的变量sum将继续存在,即使函数已经执行完毕,后面的代码依旧可以访问它。

所以初始化变量之前一定要先声明变量。