1.函数的定义方式
第一种定义方式
function fn1() {
alert("fn1");
}
alert(fn)
函数就是一个特殊的对象,是一个Function类的实例,其实在内存中存储的操作是通过一个键值对来存储的
由于函数是一个对象,所以可以通过如下方式定义
以下是通过函数的拷贝来完成赋值,两个引用并没有指向同一个对象
var fn2 = fn1;
fn2(); // fn1
两个值虽然相等但是指向的是不同的空间、
两者是如下图引用的:
所以,此时改变fn1,fn2的值不会改变:
如:
fn1 = function() {
alert("fnn1");
}
fn2();//fn1
fn1();//fnn1

所以函数虽然是一个对象,但是却和对象有一些区别,对象是通过引用的指向完成对象的赋值的,而函数却是通过对象的拷贝来完成的。

所以fn1虽然变了,并不会影响fn2。
而对于对象而言,是通过引用的指向来完成赋值的,如下例子,此时修改o1或者o2会将两个值都完成修改。
因为o1和o2指向了同一块空间,当修改o2的值的时候,o1也会被修改
var o1 = new Object();
var o2 = o1;
o2.name = "Leon";
alert(o1.name);//Leon

再说一遍:函数就是对象。
2.函数的重载
首先看下面的案例
function sum(num1,num2) {
return num1+num2;
} function sum(num1) {
return num1+100;
}
alert(sum(10));//
alert(sum(10,20));//
下面两个参数的并没有调用上面的还是调用的第二个,
现在用变量的方式重写下:
var sum = function(num1,num2) {
return num1+num2;
}
var sum = function(num1) {
return num1+100;
}
也就是说,此时sum所指向的空间已经从有两个参数的函数变化到只有num1的函数中。在调用的时候就只会调用只有num1的函数。特别指出:函数的参数和调用没有关系,如果函数只有一个参数,但是却传入了两个参数,仅仅只会匹配一个,
所以在js中函数不存在重载,只存在覆盖,后面定义的会覆盖前面定义的。
函数有如下一种定义方式:
var fn = new Function("num1","num2","alert('fun:'+(num1+num2))");
这种定义方式等于定义了一个
 function fn(num1,num2){
alert(num1+num2);
}
所以通过上面的例子,充分的说明函数就是一个对象。也就是说可以改变名字,可以把函数作为参数传到函数中。

3.函数的传值
由于函数是对象,所以可以直接把函数通过参数传递进去。如下调用案例:
    function callFun(fun,arg) {
//第一个参数就是函数对象
return fun(arg);
} function sum(num) {
return num+100;
} function say(str) {
alert("hello "+str);
}
//var say = xxx
//调用了say函数
callFun(say,"eve");//hello eve
//调用了sum函数
alert(callFun(sum,20));// function fn1(arg) {
var rel = function(num) {
return arg+num;
}
return rel;//此时返回的是一个函数对象
}
//此时f是一个函数对象,可以完成调用
var f = fn1(20);
alert(f(20));//
alert(f(11));//
如排序sort默认是按照字符串排序的,如果想要排序一个有字符串的数组时候也是把排序函数作为参数传进去。
function sortByNum(a,b) {
return parseInt(a)-parseInt(b);//当进行减法的时候,会自动完成字符串转换
}
var as = [1,2,"11px",33,"12px",190];
as.sort(sortByNum);
console.log(as);//1, 2, "11px", "12px", 33, 190]
如果测试对象来排序
    function Person(name,age) {
this.name = name;
this.age = age;
}
var p1 = new Person("Leno",39);
var p2 = new Person("John",23);
var p3 = new Person("Ada",41);
var ps = [p1,p2,p3];
ps.sort(sortByAge);
// p1.name,p1["name"];
function sortByName(obj1,obj2) { //根据姓名排序
if(obj1.name>obj2.name) return 1;
else if(obj1.name==obj2.name) return 0;
else return -1;
}
function sortByAge(obj1,obj2) {//根据年龄排序
return obj1.age-obj2.age;
}
function show() {
var p = document.getElementById("person");
for(var i=0;i<ps.length;i++) {
p.innerHTML+=ps[i].name+","+ps[i].age+"<br/>";
}
}
show();
 使用以上方法来处理排序,带来的问题是需要为每一个属性都设置一个函数,如果有五十个属性呢,显然不灵活  ,但是如果通过函数的返回值调用就不一样了。
ps.sort(sortByProperty("name"));
function sortByProperty(propertyName) {
var sortFun = function(obj1,obj2) {
if(obj1[propertyName]>obj2[propertyName]) return 1;
else if(obj1[propertyName]==obj2[propertyName])return 0;
else return -1;
}
return sortFun;
}
这样就通过返回函数来灵活的实现了函数的排序功能。

4.函数的属性

arguments:不定参,通过这个属性可以获取相应的参数值,这个属性 返回值 是一个数组,其实就是传递进来的参数。在不知道函数到底有几个参数的时候用次属性。如下方式调用,

function say(num) {
alert(arguments.length);//
for(var i=0;i<arguments.length;i++) {
alert(arguments[i]);//
}
alert(num);//
}
say(5);

在arguments这个对象中有一个callee的方法,arguments.callee(arg)可以反向的调用。

  1. arguments.callee 在 ES5 strict模式中禁止被使用。
function factorial(num) {
if(num<=1) return 1;
//此时和函数名耦合在一起
// else return num*factorial(num-1);
//以下就实现了函数名的解耦合,在js中通常都是使用这种方式做递归
else return num*arguments.callee(num-1); }
但是这个解决方案并不好,在这种方式下用函数表达式实现尾递归十分困难,另一个主要问题是这样的递归调用会产生新的 this 引用。

this

当需要创建一个类的时候,设置类的属性和方法需要通过this关键字来引用但是特别注意:this关键字在调用时会根据不同的调用对象变得不同

/*** 创建了一个类,有一个color的属性和一个show的方法*/
function Circle(color) {
this.color = color;
this.showColor = showColor;
} var c = new Circle("yellow");
//使用c来调用showColor方法,等于调用了showColor()方法
//此时的this是c,所以color就是yellow
c.showColor();//yellow
//此时调用的对象等于是window,showColor的this就是window,所以就会找window中color
showColor();//red

js面向对象学习笔记的更多相关文章

  1. js面向对象学习笔记(五):tab切换

    重点是this指向问题 <style> .hide{display: none;} #box div,#box1 div{display: none;} .hover{background ...

  2. js面向对象学习笔记(三):原型

    //原型:改写对象下面公用的方法或者属性,让公用的方法或者属性在内存中只存在一份(提高性能)//原型:prototype :要写在构造函数的下面var arr =[1,2,3,4,5];var arr ...

  3. js面向对象学习笔记(四):对象的混合写法

    //对象的混合写法//1.构造函数function 构造函数() { this.属性}构造函数.原型.方法 = function () {};//调用var 对象1 = new 构造函数();对象1. ...

  4. js面向对象学习笔记(二):工厂方式:封装函数

    //工厂方式:封装函数function test(name) { var obj = new Object(); obj.name = name; obj.sayName = function () ...

  5. js面向对象学习笔记(一):创建空对象,理解this指向

    var obj = new Object();//创建一个空对象 obj.name = '小王';//属性 obj.sayName = function () { //对象方法 对象最重要的是this ...

  6. js面向对象学习 - 对象概念及创建对象

    原文地址:js面向对象学习笔记 一.对象概念 对象是什么?对象是“无序属性的集合,其属性可以包括基本值,对象或者函数”.也就是一组名值对的无序集合. 对象的特性(不可直接访问),也就是属性包含两种,数 ...

  7. 前端学习:JS(面向对象)代码笔记

    前端学习:JS(面向对象)代码笔记 前端学习:JS面向对象知识学习(图解) 创建类和对象 创建对象方式1调用Object函数 <body> </body> <script ...

  8. js再学习笔记

    #js再学习笔记 ##基本 1.js严格区分大小写   2.js末尾的分号可加,也可不加   3.六种数据类型(使用typeof来检验数据的类型) `typeof` - undefined: `var ...

  9. JS数组学习笔记

    原文:JS数组学习笔记 最近在备课数组,发现很多ES5的方法平时很少用到.细节比较多,自己做了大量例子和整理,希望对大家了解JavaScript中的Array有所帮助. 概念 数组是值的有序集合.每个 ...

随机推荐

  1. Python 闭包、迭代器、生成器、装饰器

    Python 闭包.迭代器.生成器.装饰器 一.闭包 闭包:闭包就是内层函数对外层函数局部变量的引用. def func(): a = "哈哈" def func2(): prin ...

  2. docker服务端与客户端通信方式

    docker的服务端与客户端间可以通过unix.tcp方式进行通信.但默认情况下,服务端只监听本地unix接口/var/run/docker.sock,所以客户端只能在服务端所在的机器上使用该unix ...

  3. DevExpress WPF控件记录

    以下是博主用到DevExpress WPF控件时的一些记录笔记: 1.Canvas控件:Canvas控件的背景色一定要设置(background="Transparent"),不然 ...

  4. 社工工具包 SEToolkit

    社会工程学(Social Engineering)简称社工,其通过分析攻击对象的心理弱点,利用人性的本能反应,以及任何好奇心,贪婪等心理特征进行的,使用诸如假冒,欺骗,引诱等多种手段来达成攻击目标的一 ...

  5. 怎样理解第三方Cookie

    1. Cookie往往是用来存储用户信息的, 但有些恶意站点设法伪造了带有正确Cookie的HTTP请求, 这时就会产生安全问题( CSRF 攻击 ). 这里恶意网站获取cookie的行为就是第三方c ...

  6. hdu 1502 大数dp

    对于每一个dp的问题 从其最优解的结构(分哪几种形式或者情况)入手 然后分析状态 这样就比较好找出状态转方程这里数据结构的选择很简单 顺序数组就可以 填充的方式顺序填充就可以 然后这道题目卡了我大数. ...

  7. 使用 FTP 迁移 SQL Server 数据_迁移数据_快速入门(SQL Server)_云数据库 RDS 版-阿里云

    背景信息 阿里云数据库 SQL Server 版导入数据有如下限制: 仅支持导入 SQL Server 2005.SQL Server 2008.SQL Server 2008R2 版本数据 仅支持全 ...

  8. Linux与Windows的设备驱动模型对比

    Linux与Windows的设备驱动模型对比 名词缩写: API 应用程序接口(Application Program Interface ) ABI 应用系统二进制接口(Application Bi ...

  9. SvcUtil.exe工具生成客户端代理类

    1.以管理员身份运行vs下命令工具: 2.运行代码示例:C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin>svcutil http: ...

  10. C++ STL 之 内建函数对象

    STL 内建了一些函数对象.分为:算数类函数对象,关系运算类函数对象,逻辑运算类仿函数.这些仿函数所产生的对象,用法和一般函数完全相同,当然我们还可以产生无名的临时对象来履行函数功能.使用内建函数对象 ...