this,who are you?
这个问题有时很重要。
概括的来讲:this是个引用,永远指向当前代码所处的对象中。
还有个需要注意的技巧:如何动态的改变这个this?也就是说我能规定this是谁吗?
答案是可以的,你可以控制这件事。可以用call()函数和apply()函数。call()和apply()是Function.prototype对象中的方法,也就是说任何函数都有一个call和apply方法,用这个方法可以定义该方法执行的上下文(this)和参数。
看代码:
输出:
apply和call把第一个参数定义为上下文对象,也就是this的指向,其余参数作为函数的参数。不同的是apply的第二个参数是参数数组。
在<javascript精粹>中看到这样一个利用apply函数的例子,觉得很用。
每个函数都自带一个arguments参数,里面是参数列表,这个arguments有点像数组但是不是数组,下面代码将arguments神奇的转换为数组。
<script>
document.write(arguments.constructor);
//可以看出现在arguments是object类型
arg=Array.prototype.slice.apply(arguments);
document.write("</br>");
document.write(arg.constructor);//现在的arg是Array
}
arg2array(1,2,3,4);
</script>
闭包意味着内层的函数可以引用外层函数内的变量,即使外层函数的执行已经终止,引用依然存在。
看下面这个例子:有这样一个导航
<ul>
<li>随笔</li>
<li>文章</li>
<li>新闻</li>
</ul>
为每一个itm添加点击事件:
var liEle=document.getElementsByTagName('li');
for(var i=0;i<liEle.length;i++){
liEle[i].onclick=function(){
alert(i);
}
}
alert(i)调用的是外部函数的局部变量,这时它应该是liEle.length.因为在事件触发时,外部函数已经执行完毕 ,所以i=liEle.length。但是,我们如果想保存每个li元素i,该如何做呢?有一个种方法是给li对象添加一个属性,即变成这样:
var liEle=document.getElementsByTagName('li');
for(var i=0;i<liEle.length;i++){
liEle[i].index=i;
liEle[i].onclick=function(){
alert(this.index);
}
}
这样做可以,但是不好,因为你增加了变量,有没有更好的办法呢?有的。
var liEle=document.getElementsByTagName('li');
for(var i=0;i<liEle.length;i++){
liEle[i].onclick=function(index){
return function(){alert(index);}
} (i);
}
为什么这样行?看红色字体的部分,有了它,那么它所属的那个匿名函数被执行了,这个函数的局部变量index已经被赋值了i,而且它返回一个函数,这是event handler,被绑定到了onclick事件。事件被触发,函数被执行,alert(index)里面的index是对外部函数变量的引用,外部函数已经被执行,所以这个index就是你想要的那个i。
企鹅的面试我的一道题,没想起来,被bs了,~~~~(>_<)~~~~
参考:http://jibbering.com/faq/notes/closures/
第一句话需要记住的:javascript中的作用域由函数划分而非由块(如 if while)划分。
第二句话需要记住的:所有的全局作用域的变量其实都是window对象的属性。
第三局话需要记住的:如果一个变量不用var声明,那么这个变量不管定义在哪里,它都是全局的。
在javascript中进行类型检查,主要有两种方式。一种是利用typeof操作符,一种是利用javascript所有对象都有的一个constructor属性。
一:先来分析typeof
用typeof来进行类型检查的方式:
用typeof进行类型检查,所有的自定义类型都会返回object,所以不能区分出到底是个对象。
二:用construtor属性
constructor属性的原理:所有的javascript对象都有一个constructor属性,它引用的是原本用来构造该对象的那个函数。
用constructor属性进行类型检查的方式:
代码:

输出:
所以,用construcor能够尽心更加准确的类型检测。
对于两种方法还有一个差别,看代码:

它们对待空对象的态度不太一样