网站首页 极客学院 视频课堂 极客论坛 下载专区 行业新闻 欢迎光临极客研究院,今天是2019-10-18 星期五
会员面板
帐号:
密码:
验证码:
极客学院
教程搜索
输入要搜索的内容:

下载专区
精品教程
   网站首页 > WEB开发 > JavaScript教程 > 金极客干货教学之:JS高阶知识点

金极客干货教学之:JS高阶知识点

对于很多不是专业的前端程序员,对于JS的使用就是用来验证一下表单,或者使用Jquery等前端框架做一些简单的动态效果。

还有很多做后端的认为JS比较简单,但大家试下研究下Jquery等这些前端框架的源码,你全部能看得懂了吗?
JS远远没有你想像中的那么简单。下面我们来一点一点挖掘JS让人惊喜的知识点:

我们都知道,定义JS函数并调用JS方法可以像下面一样。
例001:
<script>
    function aa()
    {
        alert("this is aa");
    }

    aa();

</script>

但除了上面最菜鸟的方法以外,我们还可以这样

例002
<script>
    var aa=function()     //var可以省略
    {
        alert("this is aa");
    }
    aa();      //调用时必须带括号

</script>


用例002方法的好处是可以直接执行了,像下面一样

例003

<script>
    var aa=function()   
    {
        alert("this is aa");
    }();    //后面加个括号表示直接就执行了
</script>
例子001可不能用这种方法

  function aa()
  {
      alert("ok");
  }();  //这样加括号会出现语法错误



var aa=function() 

{

}

这一写法,使一个函数看起来更像一个对象了,熟悉这种写法,对后面学习JS“原型”的这个概念非常有帮助的。

前面这几个例一定要了理解清晰,这个基础不打好,否则后面学习JS闭包的机制就难接受了,
教程原创 金极客 http://www.kimgeek.com 王颂元

JS用函数做另一个函数的参数

再来看过用函数做参数的例子,没错,JS函数的参数也可以是一个函数
<script>
    function aa()
    {
        alert("this is a");
    }
    function bb(pa)
    {
        pa();
    } 
    bb(aa());    //调用bb时把aa这个函数作为参数传过去
</script>

要注意,用函数作为参数时要注意括号的问题,上例关于调用时括号的问题

function bb(pa)
{
        pa();  // 这里带括号

bb(aa());  //这里也带括号
也可以这样:
function bb(pa)
{
        pa;  // 这里不带括号

bb(aa());  //这里带括号

还可以像下面这样 
function bb(pa)
{
        pa();  // 这里带括号

bb(aa);  //这里不带括号

但不能像下面这样:
function bb(pa)
{
        pa;  // 这里不带括号

bb(aa);  //这里不带括号

这样浏览器解释时就没办法识别这个参数是不是函数了。

良好的书写习惯还是全部加上括号为好,因为还有可能aa这个函数也带参数,括号就一定不能省了。

可能有人会问,在什么时候会需要用到用函数做参数的场合?别急,我们再看看一例先:

<script>
    function aa(i)
    {
        alert("result="+i);
    }
    function bb(k,pa)
    {
        k=k+100;
        pa(k);
    }  
    bb(10,aa);
</script>

上例中,bb多了个参数k,经过计算后,把这个K传给指定的一个函数,再进行下一步的操作。

如果大家有过java开发的经验,都知道java有匿名函数的概念,如果没有java基础的,也没关系,上例改成用匿名函数的方法就像下面这样:

<script>
    function bb(k,pa)
    {
        k=k+100;
        pa(k);
    }   
    bb(10,function(i){ alert("result="+i);});     //本例不再独立定义一个aa function了,直接把aa函数的功能写在bb的实参中,这样的函数没有名称,所以叫匿名函数
</script>

为了增加易读性。一般写成下面的样子

<script>
    function bb(k,pa)
    {
        k=k+100;
        pa(k);
    }   
    bb(10,function(i){
            alert("result="+i);
    });
</script>

如果你有耐性理解了上面的几个例子,现在你就能理解Jquery里面很多功能的使用都是这样的,
很多人都知道Jquery 用get可以获取其它页面内容,但很多人不知道jquery get功能的工作原理是怎么样的。

<div id="box"></div>

<script>

$.get("demo_test.html",function(data)

{

     $("#box").html(data);

});

</script>

这个时候,你就能完成理解这段jquery使用的代码了,jquery利用ajax获取了demo_test.html的内容,然后再调用你指定做为参数的函数,然后做你指定的工作。

如果不是用函数做参数,要实现这个功能可能要分两步,

1.获取到远程内容放到一个字符串变量中。
2.自己再写一个些操作,把这个字符串变量进行处理。(例如放到div显示或alert输出)
如果是java程序员,比较习惯于这种写法,因为java经常这样写一个匿名函数做实参,甚至写一个class来做实参。
如果不熟悉这种写法的,好好回过头看一看理解了我前面所列举的几个例子,定能理解jquery的写法

函数体内包含函数

先看下js变量作用域的问题
<script>
    var i=5;
    function aa()
    {
        i=8;
    }
    aa();
    alert(i);   //这里会输出8
</script>

再看下下例

<script>
    var i=5;
    function aa()
    {
        var i=8;  //加个var,表示是定义了一个新的内部变量,不再是调用外部的全局变量了
    }
    aa();
    alert(i);   //这里会输出5
</script>

所以有时我们自己写js文件给别人调用时,内部使用的变量一定要加var,否则会有很多意想不到的后果
<script>
    function aa()
    {
        var i=8; 
    }
    aa();
    alert(i);   //这样调用会出错,因为函数体外不能访问函数内定义的变量
</script>

函数体内定义函数的例子:
<script>
    function aa()
    {
        function a1()
        {
            alert("this is a1");
        }
        a1();
    }
    aa();
</script>

上例中,在aa函数体内定义了一个函数a1();和函数内部定义的变量一样,只能在aa体内调用,aa体外调用会出错。

用函数做另一个函数的返回值

在JS中函数的返回值除了是变量,还可以是一个函数
<script>
function aa()
{
    return function()
    {
        alert("ok");
    }
}
var result=aa();    //aa的返团成员值是一个函数,即result实际上是一个函数
result();
</script>

JS闭包的概念

网上很多闭包的教程,都是讲一些难懂的理论,很多人看了好多文章都云里雾里的
我来举一个闭包应用的场景
假如我们要写一个js文件(比如我想自己开发一个简单的jquery),里面有N多功能给别人调用,如果需要使用全局变量(比如实现在的统计功能,或者setInterval定时执行时需要修改某个全局变量的值)就要注意了,我们的这个全局变量有可能被其它js文件或用户非故意就修改了值(如果名称相同)。
这个时候我们就要引用闭包的机制,把全局变量放到函数体内定义,只能用特定的方法访问和修改。这就是闭包的作用!!!!!!!!

假如我们自己写一份js文件,内容如下,如果有全局变量的情况下,没有使用闭包的情况:

pub.js

var i=100;

function aa()

{

    i++;

}

用户在引用这份js时可能在html页面会这样写:

 <script type="text/javascript" src="pub.js"></script>

<script>

aa();

alert(i); 

</script>

但如果使用了你js文件的用户又定义了一个同名的变量i,或者还有其它人写的js文件也有个全局变量i,那就悲催了


 <script type="text/javascript" src="pub.js"></script>

<script>

i=5000;  //用户无意间也使用了一个变量名i

aa();

alert(i);  //结果被干扰了

</script>

碰到这种问题,就需要闭包出场了


闭包基础的实例:
<script>
var aa=function()
{
    var i=100;   //这里定义一个内部变量,我们利用闭包机制,可以把它当全局变量来使用
    return function(){
        i++;
        return i;    
    }
}();   //这里的括号不能少,不能理解的请参考上面的例003
result=aa();
alert(result);
result=aa();
alert(result);
result=aa();
alert(result);

</script>

这时会你神奇的发现,每次调用aa时,执行里面的return,i的值会一直保存在内存中,下一次再次调用aa时,并不会执行var i=100这个语句。

这就是闭合机制,把内部变量做成了全局变量的效果来使用。

再看一例加深对闭包的理解

<script>
function aa()
{
    i=0;
    return function()
    {
        i++;
        alert(i);
    }
}
var result=aa();   //返回一个函数给result,等于专门开辟了一段内存存放这个返回函数的函数体内容。即闭包开辟了一个独立的小宇宙,再也不怕外部的干扰了
result();  
result();
result();   //result执行时原来的i一直会存放在内存中,所以i能实现累加
</script>

JS的原型和对象机制

JS不是正宗的面向对象的语言,但也有一些近似过面向对象中的类的用法,看下例
<script>
function AA()
{
    this.name="kim";   //一个函数可以定义自己的私有属性
    this.code="9013";
}

var a=new AA();  //可以用new
alert(a.name);   //输出对象的属性
</script>

函数的私有成员除了是一个变量,也可以是一个函数:

<script>
function AA()
{
    this.name="kim";
    this.code="9013";
    this.f1=function(){
        alert(this.name);
    };
}
var a=new AA();
a.f1();  //这样调用其成员函数
</script>
所以,是不是觉得js中的function 就像其它高级语言的class? 可以new出来一个实体

JS的任一个函数都有一个原型 prototype属性

function BB()
{
}
alert(BB.prototype); //这里会显示[object,object] 可以,这是一个对象

前面已经讲过,也可以有这样的写法
<script>
var a=function()
{
}
alert(a.prototype);
</script>

在上例的这种写法更像一个对象,一个对象有prototype原型属性,这样是不是容易理解多了?
那么原型有什么作用呢?
我们知道所有标准的面向对象的语言都可以有一个继承的机制,而JS是没有继承这个机制的,我们先想想继承这个机制的实现了什么功能?就是子类继承于父类,然后子类添加自己的属性和方法。
JS就可以利用原型为函数对象添加属性和方法,这样不就等于实现了继承了吗?
<script>
var A=function()
{
    this.name="Mike";
}
A.prototype.code="9014";  //利用prototype添加一属性
var a=new A();
alert(a.code);   //这个时候可以使用了a.code属性
</script>
同理,它也可以添加function作为成员
<script>
var A=function()
{
    this.name="Mike";
}
A.prototype.f1=function()
{
    alert(this.name);
}
var a=new A();
a.f1();
</script>

JS就是利用这种原型方法来实现继承的。

有了上面的基础,大家可以参考我的另一篇教学:

金极客干货教学之:打造自己的jquery

http://www.kimgeek.com/article_detail_346.html

  相关文章
本文标题:金极客干货教学之:JS高阶知识点
对本文有疑问?现在就进入论坛提问>>
 
粤ICP备18090445号