JavaScript 函数的初步认识

断断续续,自学了一阵子 JS,写了一个图片滚动特效,一个留言板和一个小插件。到现在,看别人的程序还是很吃力,甚至完全不懂,大概这就是学而不思则罔吧,停下来思考总结一下 JS 函数的基本问题。

JS 是面向对象的动态语言,变量、字符串、数组、大括号 {} 里定义的数据、function 函数都是对象。JS 函数分为有名函数和无名(匿名)函数,都用 function 来声明。调用也很简单,名字加一对括号,例如:

fun('hello','world');
function fun(a, b){console.log(a, b);}

运行这两句将会在浏览器控制器里生成一个 hello world. 需要注意的是,上面函数的调用是在函数声明之前,说明 function 函数在预编译时被前置,基本上面向过程的语言都是这样。

function 后面没有名字的叫匿名函数,声明后如果不立刻调用,该函数就废了,因为你再也找不到它。lisp 和 python 语言也有匿名函数,专门用 lambda 来声明。相应的,JS 匿名函数的调用为一对括号紧跟在匿名函数后面,但是解释器会产生一个语法错误,因此需要将匿名函数用一对括号包起来,JS 里叫闭包。例如:

(function (a, b){console.log(a, b);})('hello','world');

实际上,括号的作用就是将匿名函数变成一个表达式。四则运算符号,逻辑运算符号都有这个作用,采用不同的符号浏览器调用时会有性能差异,好像是 () 和 + 执行速度最快,也有人喜欢用 !(逻辑否)来闭包。

+function (a, b){console.log(a, b);}('hello','world');  

用 + 闭包,效果一样。就如同将字符串 “5” 转换为数字可以用 +“5” ,js 会动态转换类型。

在这里,本人觉得有个理解问题,并不是 function 后不给名字就是匿名函数,而是函数作为右值使用时,就会自动降级为匿名函数,右值会让 function 失去声明前置作用。例如给匿名函数一个名字:

(function fun (a, b){console.log(a, b);})('hello','world');

上面函数定义、运行正确,虽然函数有名字,而在函数闭包后(变成右值),名字将被无视, 完全被当成匿名函数使用,查询 fun 显示未定义。说明有名无名不是定义匿名的关键,而是它屁股坐在哪里决定的,大概匿名函数被叫习惯了,准确的说法应叫做右值函数。右值就是用来计算的,可以被赋值给左值。如下:

var fun = (function (a, b){console.log(a, b);});
fun('hello','world');  

上面的赋值语句,既然匿名函数已经处于等号右侧了,那毫无疑问就是右值,此时可以省略括号,不需要再闭包进行右值化。带上括号 JS 解释器也不认为错误,但是此时它却不能再用匿名函数的 () 的方法调用了,因为它有名字了。

匿名函数被命名(赋值)后,左值的数据类型是函数,JS 函数(包括有名和匿名)有个神奇的特性,可以被当成类使用:

var abc = new fun();  //fun 由匿名函数赋值,用 function 定义的有名函数也可实例化。

此时,函数 fun 被当成类,实例化给 abc 后,abc 变成一个对象,typeof 可以查看。对象显然不能当函数使用,对象的特点就是属性和方法。而 abc 实例化前的函数未定义属性和方法咋办,幸好 js 提供了一个 prototype 方法。本人认为这是 js 功能最强大的一个方法,有利于对象属性和方法的封装。

唯一令人迷惑的是,prototype 是函数继承而来的方法,并不能使用于对象。也就是 fun 可以用, abc 无效。好在给函数用 prototype 添加属性后,fun 会自动继承,而不需要重新用 new 实例化。如下:

fun.prototype.num = 5;  //添加一个属性
fun.prototype.ss = function(){console.log(this.num);};  //封装一个函数
abc.ss();

给 fun 函数封装一个 ss 方法,abc 对象将自动继承。而且,fun 自身用不上,因为函数无法调用属性和方法!这种不为自己专利他人,是多么高尚的品质!朴素的理解,大概就是 new 建立了对象到函数的指针,所以,函数改变,对象也就跟着改变,而且函数内部的 this 直接指向对象指针。

这样做有个好处,一个函数被实例化成任何多个对象后,当函数被 prototype 封装新方法,所有的对象就同时继承。

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yxp_xa

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值