JavaScript 你应该知道的知识

今天醒的比较早,闲着没事,翻来js书看看, 不料有很多意想不到的收获,和大家分享!

在函数体内获取 参数(学了这么长时间,才知道有这个东西,悲催啊,我还经常纳闷,为啥那些编好的js库里,我找不到参数的用途)

<script type="text/javascript">
        function a() {

            if (arguments.length > 0) {
                for (i in arguments) {
                    alert(arguments[i]);
                }
            }

        }

        window.onload = a(1, 2, 3, 4, 5);
    </script>

既然可以获取到 参数,那么就可以 对传入的参数 进行验证, 正则也好,规定参数类型也好, 就都可以实现了,增加了函数的容错功能.

下面来看获取 函数 形参,和实参数目的例子:

<script type="text/javascript">
       function a() {

           var arguments1 = arguments.length; //获取实参的个数
           var arguments2 = arguments.callee.length; // 获取形参的数目
            //在 非匿名函数下,  可以使用  函数名.length获取形参 个数. 本例是 a.length
           document.write("实参个数:" + arguments1 + "</br>" + "形参个数:" + arguments2);

       }

       window.onload = a(1, 2, 3, 4, 5);
   </script>

 

正确理解 this

学习 this 之前,首先 要弄明白什么是 调用者和 所有者的概念.

所谓调用者就是 调用函数的域( 变量域,对象的属性域),

所有者 就是 调用函数的对象.

定义一个函数:

function a(s){ return s;}

var b=a;  //把函数a 赋值给变量b

var o= { x:f}   //把函数赋值给 对象o的 x属性

把函数a赋值给 变量b,则 变量域b就是 函数a的调用者. 此时变量b存储着 函数a的地址,同理,对象o的x属性域 也存储着函数a的引用地址,所以他们被称为调用者.

而 变量e属于全局对象 window所有,此时 window便是函数f的所有者,同理,o对象的x属性,属于o对象所有,所以o也是 函数a的所有者.

理解这些之后,在来看 this,

一般来说,在函数被调用过程中,关键字 this总是指向 函数的所有者.

下面看一个例子:

var x=1;

function f(){ this.x=2;}

 

f();  //调用 函数f

alert(x);  //此时 弹出 2

通过调用函数f, 函数内部的关键字this指向的对象 是 window,所以 this.x就 等效于 window.x ,于是 它就覆盖了 全部变量 x的值.弹出2

 

下面在举一个 例子:

function f(){

        this.x= function(x){return x}

}

f();  //调用函数f

alert(f.x(4));  //此时 会返回编译错误  f.x is not a function

那么 使用 alert(window.x(4));  则会 弹出 4,这是为什么呢,下面解释一下:

虽然方法x在 函数f体内定义,但是它已经不属于函数f了, 因为window是 函数f的所有者,而 this就是指向 window的,所有 x方法 是window的方法.

 

不过 我们可以 借助 new在 实例化 函数f,则此时 函数f变成了 一个对象类,实例化以后 this指向的就是本对象了,而不是window了

function f()

{

    this.x=function(s){ return x;}

}

var a=new f();

alert(a.x(4));  //此时 弹出4

 

 

动态 调用函数: call() 和apply()方法

function a(a, b) { return a + b; }
        function o(a, b) {return a * b;}

        alert(a.call(o, 3, 4));

通过 call方法, 把函数a绑定到 o这个伪对象上,作为 o的一个方法 出现,然后动态 调用该方法.

 

那么也可以转换为下面的的代码:

function a(a, b) { return a + b; }
function o(a, b) {return a * b;}

o.f=a;

alert(o.f(3, 4));   //弹出7

delete o.f;   // 删除o对象的f方法

 

下面在看一 apply()的用法:

其实 apply和call本有本质的区别,只是 apply()传递的参数 是以 数组的形式 传递的.

function a(a, b) { return a + b; }
function o(a, b) {return a * b;}

alert(a.call(o, [3,4]));  //弹出7

 

这两个函数给开发带来很多便利:看下面的代码:

求数组的最大值:

var a = [1, 2, 34, 233, 111];
        var m = Math.max.apply(Object, a);
        alert(m);  

把系统函数 Math.max方法 做为 object方法来使用,

好处: 通过调用 call()和apply()动态调用函数 可以用完之后马上删除,避免资源占用,可以实现灵活的调用.

代码证明,动态调用函数后,马上删除:代码如下:

function f(){}

f.call(Object);

Object.f(); // 运行一下, 编译失败……Object.f is not a function

  call()和apply()延伸 之高级用法:

call()和apply()在js手册这样定义:调用一个对象的一个方法,以另一个对象替换当前对象.

其实就是改变对象的 this 所 指向的内容.

 

<script type="text/javascript">

       var x = "a";
       function b() { this.x = "b"; }
       function f() { alert(this.x); }

       window.onload = function () {

           f();
           f.call(new b());


       };


     
   </script>

上述代码会弹出2次.一次是 a,一次是b. 就是 通过call()改变了 this的指向.

 

第二种用法(很霸道…)

<script type="text/javascript">

       function f() {
           this.a = "a";
           this.b = function () { alert("b"); }
       }

       function e() {

           f.call(this);
           b();
       }
       window.onload = e;
   </script>

通过 f.call(this) 相当于把 f的属性a和方法拷贝到 e中,以供调用.是不是很强大……

本质上将 就是 更改了 f函数内部关键字 this的指向了e,这样e就可以引用 函数f内的成员了.

posted @ 2012-03-21 08:50  高捍得  阅读(214)  评论(0编辑  收藏  举报