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

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

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

  1. 再说一遍:函数就是对象。
  1. 2.函数的重载
  1. 首先看下面的案例
  1. function sum(num1,num2) {
  2. return num1+num2;
  3. }
  4.  
  5. function sum(num1) {
  6. return num1+100;
  7. }
  8. alert(sum(10));//
  9. alert(sum(10,20));//
  1. 下面两个参数的并没有调用上面的还是调用的第二个,
  1. 现在用变量的方式重写下:
  1. var sum = function(num1,num2) {
  2. return num1+num2;
  3. }
  4. var sum = function(num1) {
  5. return num1+100;
  6. }
也就是说,此时sum所指向的空间已经从有两个参数的函数变化到只有num1的函数中。在调用的时候就只会调用只有num1的函数。特别指出:函数的参数和调用没有关系,如果函数只有一个参数,但是却传入了两个参数,仅仅只会匹配一个,
所以在js中函数不存在重载,只存在覆盖,后面定义的会覆盖前面定义的。
函数有如下一种定义方式:
  1. var fn = new Function("num1","num2","alert('fun:'+(num1+num2))");
这种定义方式等于定义了一个
  1. function fn(num1,num2){
  2. alert(num1+num2);
  3. }
  1. 所以通过上面的例子,充分的说明函数就是一个对象。也就是说可以改变名字,可以把函数作为参数传到函数中。
  2.  
  3. 3.函数的传值
  1. 由于函数是对象,所以可以直接把函数通过参数传递进去。如下调用案例:
  1. function callFun(fun,arg) {
  2. //第一个参数就是函数对象
  3. return fun(arg);
  4. }
  5.  
  6. function sum(num) {
  7. return num+100;
  8. }
  9.  
  10. function say(str) {
  11. alert("hello "+str);
  12. }
  13. //var say = xxx
  14. //调用了say函数
  15. callFun(say,"eve");//hello eve
  16. //调用了sum函数
  17. alert(callFun(sum,20));//
  18.  
  19. function fn1(arg) {
  20. var rel = function(num) {
  21. return arg+num;
  22. }
  23. return rel;//此时返回的是一个函数对象
  24. }
  25. //此时f是一个函数对象,可以完成调用
  26. var f = fn1(20);
  27. alert(f(20));//
  28. alert(f(11));//
  1. 如排序sort默认是按照字符串排序的,如果想要排序一个有字符串的数组时候也是把排序函数作为参数传进去。
  1. function sortByNum(a,b) {
  2. return parseInt(a)-parseInt(b);//当进行减法的时候,会自动完成字符串转换
  3. }
  4. var as = [1,2,"11px",33,"12px",190];
  5. as.sort(sortByNum);
  6. console.log(as);//1, 2, "11px", "12px", 33, 190]
  1. 如果测试对象来排序
  1. function Person(name,age) {
  2. this.name = name;
  3. this.age = age;
  4. }
  5. var p1 = new Person("Leno",39);
  6. var p2 = new Person("John",23);
  7. var p3 = new Person("Ada",41);
  8. var ps = [p1,p2,p3];
  9. ps.sort(sortByAge);
  10. // p1.name,p1["name"];
  11. function sortByName(obj1,obj2) { //根据姓名排序
  12. if(obj1.name>obj2.name) return 1;
  13. else if(obj1.name==obj2.name) return 0;
  14. else return -1;
  15. }
  16. function sortByAge(obj1,obj2) {//根据年龄排序
  17. return obj1.age-obj2.age;
  18. }
  19. function show() {
  20. var p = document.getElementById("person");
  21. for(var i=0;i<ps.length;i++) {
  22. p.innerHTML+=ps[i].name+","+ps[i].age+"<br/>";
  23. }
  24. }
  25. show();
  1.  使用以上方法来处理排序,带来的问题是需要为每一个属性都设置一个函数,如果有五十个属性呢,显然不灵活  ,但是如果通过函数的返回值调用就不一样了。
  1. ps.sort(sortByProperty("name"));
  2. function sortByProperty(propertyName) {
  3. var sortFun = function(obj1,obj2) {
  4. if(obj1[propertyName]>obj2[propertyName]) return 1;
  5. else if(obj1[propertyName]==obj2[propertyName])return 0;
  6. else return -1;
  7. }
  8. return sortFun;
  9. }
  1. 这样就通过返回函数来灵活的实现了函数的排序功能。

4.函数的属性

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

  1. function say(num) {
  2. alert(arguments.length);//
  3. for(var i=0;i<arguments.length;i++) {
  4. alert(arguments[i]);//
  5. }
  6. alert(num);//
  7. }
  8. say(5);

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

  1. arguments.callee 在 ES5 strict模式中禁止被使用。
  1. function factorial(num) {
  2. if(num<=1) return 1;
  3. //此时和函数名耦合在一起
  4. // else return num*factorial(num-1);
  5. //以下就实现了函数名的解耦合,在js中通常都是使用这种方式做递归
  6. else return num*arguments.callee(num-1);
  7.  
  8. }
  1. 但是这个解决方案并不好,在这种方式下用函数表达式实现尾递归十分困难,另一个主要问题是这样的递归调用会产生新的 this 引用。
  2.  
  3. this
  4. 当需要创建一个类的时候,设置类的属性和方法需要通过this关键字来引用但是特别注意:this关键字在调用时会根据不同的调用对象变得不同
  1.  
  1. /*** 创建了一个类,有一个color的属性和一个show的方法*/
  2. function Circle(color) {
  3. this.color = color;
  4. this.showColor = showColor;
  5. }
  6.  
  7. var c = new Circle("yellow");
  8. //使用c来调用showColor方法,等于调用了showColor()方法
  9. //此时的this是c,所以color就是yellow
  10. c.showColor();//yellow
  11. //此时调用的对象等于是window,showColor的this就是window,所以就会找window中color
  12. showColor();//red
  1.  

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. 【01字典树】hdu-5536 Chip Factory

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=5536 [题意] 求一个式子,给出一组数,其中拿出ai,aj,ak三个数,使得Max{ (ai+aj ...

  2. 怎样在页面关闭时发起HTTP请求

    比如有需求是要让页面关闭时, 在数据库中记录用户的一些数据或log日志. 这时就需要在用户关闭页面时发起HTTP请求. 做法是对window.onunload设置事件监听函数, 在函数内发起AJAX请 ...

  3. Java多线程(十一):线程组

    线程组 线程组可以批量管理线程和线程组对象. 一级关联 例子如下,建立一级关联. public class MyThread43 implements Runnable{ public void ru ...

  4. HTTP协议探究(二):代理、网关和隧道

    一 复习与目标 1 复习 缓存目的:减轻服务器压力,不重复请求相同的内容 缓存位置:浏览器或中间代理 相关状态码:200或403 相关首部: etag和since-none-match.last-mo ...

  5. C++通用框架和库

    C++通用框架和库 来源 https://www.cnblogs.com/skyus/articles/8524408.html 关于 C++ 框架.库和资源的一些汇总列表,内容包括:标准库.Web应 ...

  6. mybatis+oracle 批量插入,若数据库中有则做更新操作

    1.只批量插入: insert into WXPAY_ACCOUNT(id ,out_trade_no ,transaction_id)select SEQ_WXPAY_ACCOUNT.nextval ...

  7. C8051F环境搭建

    https://www.silabs.com/ USB调试器 U-EC6: 支持JTAG模式.C2模式 JTAG接口定义: 适用型号C8051F00x C8051F01x C8051F02x C805 ...

  8. 浅谈nginx简介和应用场景

    简介 nginx是一款轻量级的web服务器,它是由俄罗斯的程序设计师伊戈尔·西索夫所开发. nginx相比于Tomcat性能十分优秀,能够支撑5w的并发连接(而Tomcat只能支撑200-400),并 ...

  9. 嵌入式Linux应用开发完全手册读书笔记——常用的命令

    嵌入式开发中常用的命令 grep命令 用法:grep [option] PATTERN [FILE...] 例如: 在内核目录下查找包含"request_irq"字样的文件 gre ...

  10. 牛客练习赛53 E 老瞎眼 pk 小鲜肉 (线段树,思维)

    链接:https://ac.nowcoder.com/acm/contest/1114/E来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...