Javascript OOP -- 深入理解函数
发布时间:2017年8月13日    分类:前端文章
暂无文章数据...

深入函数与对象

函数就是一个特殊的对象(Object),是Function类的实例,其实在内存中存储的操作是通过一个键值对来存储.
函数虽然是一个对象,但和对象有一定的区别.

  • 函数的定义与内存模型:
function fn1 () { alert('123'); } var fn2 = fn1; fn2(); //用fn2完成函数调用,结果是123

这段代码我相信很多人都能看懂,我们来看看它的内存模型:

内存模型

举个例子证明改变fn1的时候fn2并没有改变,还是上面的例子:

function fn1 () { alert('123'); } var fn2 = fn1; fn1 = function () { alert('111'); }; fn2(); //用fn2完成函数调用,结果还是123

通过上面的两个例子,虽然fn2 = fn1但是他们指向的是不同的空间,我们可以证实了函数是通过对象的拷贝来完成。

  • 对象的定义与内存模型:
var obj1 = new Object(); var obj2 = obj1; obj1.name = 'lee'; alert(obj2.name); //lee

我们来看看它的内存模型,画的有点渣~๑乛◡乛๑

内存模型

通过上面我们就可以看出,此时修改obj1或者obj2都会将两个值完成修改,对象是通过引用来指向完成对象的赋值的.

动态语言Javascript函数的灵活性

Javascript中函数真的有重载么?

function sum (num1,num2){ return num1 + num2; } function sum (num1){ return num1 + 10; } alert(sum(10)); //20

我们不难看出,结果为20 <= (这是一句废话)…我们再看下面的代码:

function sum (num1,num2){ return num1 + num2; } function sum (num1){ return num1 + 10; } alert(sum(10,20)); //??

我们来思考一下,它的结果返回什么?
发生了什么?

没错,结果返回为20。此时sum所指向的空间变成了一个,因为在JS中函数名相同的后面的会覆盖前面。
特别注意:函数的传入参数与调用无关!!!
如果调用传入两个参数,而形参只有一个,就只会匹配一个参数。
所以说,在Javascript中函数没有重载的功能!

作为值的传递

function fn (fun,arg){ return fun(arg); } function say (str){ alert('Hello'+str); } fn(say,'World'); //返回Hello World

动态语言的灵活性非常高,我们不难看出函数还可以作为值传递到另外的一个函数中去调用.

作为返回值 (一道例题引发的思考)

我们先来说说数组的排序功能(sort),看例子:

var arr = [1,2,1,3,5,11]; console.log(arr.sort()); //[1, 1, 11, 2, 3, 5]

默认的排序是按字符串来排序的,这么排序肯定是我们不希望看到的。我们都知道sort()方法可以传递一个函数,我们来改进一下:

var arr = [1,2,1,3,5,11]; function bySort(num1,num2) { return num1 - num2; } console.log(arr.sort(bySort)); //[1, 1, 2, 3, 5, 11]

一切看起来都很正常,因为这是数字排序,那么如果我们想给对象排序呢?

function Fn (name,age) { this.name = name; this.age = age; } var p1 = new Fn('lee',23); var p2 = new Fn('zhangsan',33); var p3 = new Fn('Dave',13); var ps = [p1,p2,p3]; ps.sort(); //无效!

sort

我们可以按照刚才的思路再写一个给姓名的排序的函数,传入进sort()中进行排序:

function sortByName(obj1,obj2){ if (obj1.name > obj2.name)return 1; else if(obj1.name == obj2.name)return 0; else return -1; } ps.sort(sortByName);

sort

那么问题来了,如果我们要写年龄排序呢?是不是还要写一个方法,如果还有很多呢,比如地址按字母排序呢?我们来按照函数作为返回值来实现动态排序:

function sortByPro(dynamic) { function sortFn (obj1,obj2) { if (obj1[dynamic] > obj2[dynamic])return 1; else if (obj1[dynamic] == obj2[dynamic]) return 0; else return -1; } return sortFn; } ps.sort(sortByPro('age'));

sort

就暂时先写到这里,这是不过是总结的一些小的技巧与心得,如果哪里有错误请指正!谢谢!