函数类型 function 函数名称(参数表) { 函数执行部分; } 注意: 1.参数列表直接写行参名即可,不用写var,不用指定类型 2.return 返回函数的返回值并结束函数运行。 3.函数可以当做参数进行传递。 //函数当做参数传递 <script type="text/javascript" charset="UTF-8"> function test(test1){ test1(); } function test1(){ alert("调用方法TEST1"); } //函数传递调用 test(test1); //匿名函数传递 调用 test(function (){ alert("调用方法TEST2"); }); </script> function test3(){ function test4(){ alert("调用方法TEST4"); }; test4();//方法内部嵌套定义方法,只能在方法内部调用 } test3(); 三种函数定义的方式: 1.function语句形式 function test1(){alert("我是TEST1");} 调用:test1(); 2.函数直接量形式 //function语句形式与函数直接量形式在使用方面没有区别,除了解析机制。 var test2 = function(){alert("我是TEST2");} 调用:test2(); 3.通过Function构造函数形式定义 var test3 = new Function("a","b","return a+b;"); 调用:test3(); 区别点: 1.构造函数方式的机制是动态的,其他两种是静态的。在大量循环创建的过程中,动态的创建方式耗时长。 2.解析机制,function语句方式是优先解析,而其他两种是顺序解析,指在执行到此语句时才解析,意味着调用语句不能放在function函数前面。 3.作用域,构造函数的方式是顶级作用域,意味着此function是全局的。 测试实例: //创建方式1,2的性质是静态, 方式3的性质是动态 var d1 = new Date(); var t1 = d1.getTime(); for(var i=0; i<100000;i++){ //function test4(){} //执行在10-20之间,编译一次放在内存中 var test5 = new Function();//执行在 500-600之间,每次都需要编译,动态解析与静态解析的区别 } var d2 = new Date(); var t2 = d2.getTime(); //alert(t2-t1); //解析顺序,对于function语句式函数,javaScript解析器会优先解析 //而对于new Function方式,javaScript顺序解析 //test6(); function test6(){ alert("test6"); } //test7();//报错,提示缺少对象 var test7 = function(){ alert("test7"); } //顶级作用域测试 var k = 1; function test8(){ var k = 2; function test9(){alert(k)} var test10=function (){alert(k)} var test11= new Function ('return k'); //顶级作用域,相当于在方法外面定义 alert(test11()); } test8(); //匿名函数 格式: (function(){//代码 })(); 解释:,包围函数(function(){})的第一对括号向脚本返回未命名的函数,随后一对空括号立即执行返回的未命名函数,括号内为匿名函数的参数。 例子:(function(arg){ alert(arg+100); })(20); 这个例子返回120。 -------------------------------------------------------------------------------------------- //函数的参数 //形参列表 //传入的参数可以与定义的参数个数不统一,只是结果可能是NaN,比如test(1,2,3),那么d的值为undefined //形参与实参 function test(a,b,c,d){ return a+b; } test(); 示例1: function test(a,b){ alert(test.length);//查询形参个数 alert(arguments.length); //arguments 查询传入参数的实际参数 //arguments只能在函数内部访问 alert("Frist argument: "+arguments[0]); if(test.length == arguments.length){ return a+b; }else{ return "参数不正确!"; } } //arguments更多用于递归操作 //arguments.callee 返回arguments所属函数对象引用,这相当于内部调用自己 function fact(num){ if(num <= 1) { return 1; }else{ return num*arguments.callee(num-1);//等同于return num*fact(num-1); 解除耦合 } } var f = fact;//将函数引用付给f alert(f(5)); -------------------------------------------------------------------------------------------- this对象 this对象是运行时基于函数的执行环境绑定的。在全局函数中,this等于window, 而函数被作为某个对象的方法调用时,this指的调用者。 也就是说this关键字总是指调用者。 <script type="text/javascript"> var k = 10; function test(){ this.k = 20;//this总是指向调用者 } test();//等同于window.test(),调用者是window alert(k);//20 </script> -------------------------------------------------------------------------------------------- 每一个函数都把包括两个非继承而来的方法:call,apply 这两个方法的用途都是在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。 call,apply的用途之一就是传递参数,但事实上,它们真正强大的地方是能够扩充函数赖以 运行的作用域。扩充作用域的最大好处是对象不需要与方法有任何耦合关系。 语法:call(thisObj,param1,param2...) //apply相同 定义:调用一个对象的一个方法,以另一个对象替换当前对象。 说明: call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象 function sum(x,y){ return x+y; } function call1(num1,num2){ return sum.call(this,num1,num2); //将sum函数绑定到call1方法上,将本方法接收的num1,num2传递给sum方法 } function apply1(num1,num2){ return sum.apply(this,[num1,num2]); } //alert(call1(10,20)); //alert(apply1(10,30)); //call方法扩充作用域 var color = 'red'; var obj = {color:'blue'}; function showColor(){ return this.color; } //alert(showColor.call()); //alert(showColor.call(obj)); //call方法的简单模拟 function test1(a,b){ return a+b; } //自定义对象 function Obj(x,y){//方法名称大写代表对象 this.x = x; //通过this给对象赋予属性 this.y = y; return x*y; } var o = new Obj(10,20); o.method = test1;//将test1方法赋予o对象 o.method(o.x,o.y); //alert(test1.call(o,o.x,o.y)); //alert(test1(o.x,o.y)); delete o.method; //删除对象o的方法method -------------------------------------------------------------------------------------------- 执行环境是javascript重要的一个概念,它定义了函数或变量有权访问的其他数据,决定它们各自的行为。每个执行环境都有一个关联的对象, 环境中定义的变量和函数都保存在这个对象中。 一个需要注意的点: javascript没有块级作用域的概念,高级语言比如java 在for,if语句中存在块级作用域概念,for,if块内定义的变量,外部无法访问。 function test(){ for(var i=0;i<=5;i++){//此时定义代表在function test内部定义变量i alert(i); } alert(i); //弹出对话框,显示为6 } test(); //作用域实例 var name = "xiao A"; var obj = { name : "xiao B", getName: function(){ return function(){ return name; } } } //alert(obj.name); //alert(obj.getName()()); //等同于 var k = obj.getName(); k(); var k = obj.getName(); //全局作用域 //alert(k()); var obj1 = { name : "xiao B", getName: function(){ var o = this;//将调用者对象付给o alert(o); return function(){ return o.name; } } } alert(obj1.getName()()); -------------------------------------------------------------------------------------------- /*闭包 封装变量 //Javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、 参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包 作用: 一个是可以读取函数体所在外部函数的局部变量,另一个就是让这些变量的值始终保持在内存中。 */ //闭包简单示例 var func = function (){ var x =1 ; return function(){ x++; alert(x); }; }; var f = func(); //f变量得的是function(){x++;alert(x);}的"对象"引用,里面仍然包含着x的值,因为执行作用域被付给了f,所以变量一直存在没有被摧毁 f();//2 f();//3 //如果采用下面的方式回执行,结果一直为2,理解为此function的返回没被变量引用,没有形成执行上下文,因此每次访问都为2 func()();//2 func()();//2 还是等于2,理解为每次访问都是一个新的对象 //闭包:一个函数可以访问另外一个函数作用域中的变量 //封闭性:private起到一个包括变量的作用 function f(x){ var temp = x; return function(x){ temp += x; //此function中引用到了上级中的temp变量 alert(temp); } } var a = f(50); alert(a); a(5); //55 a(10);//66 a(20);//85 //闭包实例3 <html> <body> <div>1</div> <div>2</div> <div>3</div> <div>4</div> <div>5</div> <script> var divs = document.getElementsByTagName('div'); for(var i = 0,len = divs.length;i<len;i++){ divs[i].onclick = function(){ alert(i); }; }; </script> </body> </html> //无论点击哪个DIV,弹出的结果是5,想想为什么? //怎么样使得点击每个DIV都显示对应的数字0,1,2,3,4呢,再看如下例子 <script> var divs = document.getElementsByTagName('div'); for(var i = 0,len = divs.length;i<len;i++){ (function(i){//绑定一个匿名函数(function())() 此时的i相当于是一个参数,相当于private参数,会保存下来i的值 divs[i].onclick = function(){ alert(i); //i调用的 }; })(i); }; </script> //示例4 var mult = function (){ var sum =1 ; for(var i=0;i<arguments.length;i++){ sum =sum *arguments[i]; }; return sum ; }; //这个函数接受一些number类型的参数,并返回这些参数的乘积 mult(3,4,5);//60 mult(3,4,5,6)//360 //如果每次传递同样的参数,都去计算一遍,是一种资源上的浪费,可以加入缓存机制来提高这个函数的性能 /* cache这个变量仅仅在mult函数中被使用,暴露在全局作用域下 既然是mult函数专用,干脆将这个变量封闭在mult函数内部,避免这个变量在其它地方被调用或者修改,引起错误 //还可以对代码进行重构,把比较独立的代码提炼出来*/ var mult = (function (){ var cache = {}; var calcute = function (){ var sum =1 ; for(var i=0;i<arguments.length;i++){ sum =sum *arguments[i]; }; return sum ; }; return function(){ var arrgs = Array.prototype.join.call(arguments,',');//利用call方法扩展作用域,实际上就是调用Array原型中的join方法,将参数数组作为作为this对象,','为参数 if (cache[arrgs]){ return cache[arrgs]; }; return cache[arrgs]=calcute.apply(null,arguments) ; }; })(); //如果这些独立小函数在其它地方没用用到,最好使用闭包把它们封闭起来 //闭包和面向对象设计 var person = function(name){ return { getName:function(){ return name ; } }; }; var man = person('bob'); man.getName(); //name变成了man这个对象的私有成员 -------------------------------------------------------------------------------------------- javascript面向对象 三种方式: 1.直接创建变量对象 2.通过function函数返回对象 3.通过构造函数new对象 //1.手工创建对象 var obj = {};//var obj = new Object(); obj.name = 'z3'; obj.sex = '男'; obj.sayName = function() {alert(obj.name)}; obj.sayName(); //2.工厂模式 创建对象 function createPerson(name,sex,age){ var obj = {}; obj.name = name; obj.sex = sex; obj.age = age; return obj; } var person1 = createPerson('l4','女',12); alert(person1.name); //3.构造函数创建对象 //函数的第一个字母大写,约定为类的模板 //3.1 function Person(name,age,sex){ this.name = name; //this关键字指向new的对象 this.age = age; this.sex = sex; this.say = function(){ alert(this.name); } } //通过new构造一个对象 var person2 = new Person('w5',18,'男'); var person3 = new Person('z6',20,'男'); person2.say(); alert(person2.constructor);//打印出person2的构造函数 alert(person1.constructor);//natvie code alert(person2.constructor == person3.constructor);//判断person2的构造函数是否等于person3的构造函数 alert(person2 instanceof Person);//判断person2是否是Person的实例 alert(person3 instanceof Person); //3.2 function Person(name,age,sex){ return { name : name, age : age, sex : sex, say : function(){ alert(this.name); } } } //通过new构造一个对象 var abc = new Person('123',18,'男'); abc.say(); var abc1 = new Person('1234',18,'女'); abc1.say(); -------------------------------------------------------------------------------------------- //1.利用js对象模拟Map对象 <script type="text/javascript" charset="UTF-8"> function Map(){//定义对象的"构造函数"(或者叫函数) //private var obj={};//空的对象容器,承载键值对 //map的put方法 this.put = function(key,value){//this代表当前对象 obj[key] = value;//将键值对绑定到obj对象上 } this.size = function(){ var count = 0; for(var attr in obj){ count++; } return count; } this.get = function(key){ if(obj[key] || obj[key] === 0 || obj[key] === false){//===代表先对比变量值,再对比变量类型(考虑隐形转换情况) return obj[key]; }else{ return null; } } this.remove = function(key){ if(obj[key] || obj[key] === 0 || obj[key] === false){ delete(obj[key]);//删除 } } this.eachMap = function(fn){ for(var attr in obj){ fn(attr,obj[attr]); } } } //模拟java里的Map var m = new Map(); m.put('01','abc'); m.put('02',0); m.put('03',true); m.put('04',new Date()); alert(m.size()); alert(m.get('02')); m.remove('02'); m.eachMap(function(key,value){//将function作为参数传递过去 称为回调函数 alert(key +" : "+ value); }); </script> //2.利用对象的特性,去掉数组中的重复项 <script type="text/javascript" charset="UTF-8"> var arr = [1,2,3,4,5,1,3,5,2,10]; //js对象的特性:在js对象中key是永远不会重复的 //1.把一个数组转化为一个对象 //2.把数组中的值变为js对象中的key //3.把这个对象再还原成数组 function toObject(arr){ var obj = {};//私有对象 for(var i = 0;i <arr.length;i++){ obj[arr[i]] = true; } return obj; } //对象变为数组 function keys(obj){ var arr = [];//私有对象 for(var attr in obj){ if(obj.hasOwnProperty(attr)){ arr.push(attr); } } return arr; } function uniq(newArr){ return (keys(toObject(newArr))); } alert(uniq(arr)); </script>
相关推荐
在提供的资源中,《代码之美》PDF文件可能包含了关于编程实践和代码风格的指导,而《Javascript面向对象编程》PPT可能更具体地阐述了JavaScript OOP的细节和示例。学习这些材料将有助于深入理解JavaScript的面向对象...
“基于闭包的JavaScript面向对象编程框架” 本文总结了基于闭包的JavaScript面向对象编程框架的设计和实现。通过使用闭包,实现了基于类的面向对象编程的封装、继承和多态特征。 闭包(Closure)是JavaScript中的...
在本文中,我们将介绍JavaScript面向对象编程中的经典案例,包括对象、类、继承、原型链和闭包等概念。 一、对象和类 在JavaScript中,对象是指一个实体,可以拥有自己的属性和方法。对象可以使用工厂函数或构造...
JavaScript作为一门浏览器语言的核心思想;面向对象编程的基础知识及其在... 《JavaScript面向对象编程指南》着重介绍JavaScript在面向对象方面的特性,展示如何构建强健的、可维护的、功能强大的应用程序及程序库
《JavaScript面向对象编程指南》内容包括:JavaScript作为一门浏览器语言的核心思想;面向对象编程的基础知识及其在JavaScript中的运用;数据类型、操作符以及流程控制语句;函数、闭包、对象和原型等概念,以代码...
### JavaScript面向对象编程精要 #### 一、引言 JavaScript是一种灵活且强大的脚本语言,它虽然起源于一种简单的浏览器脚本语言,但随着时间的发展,JavaScript已经成为了一种功能全面的编程语言,尤其是在Web开发...
JavaScript是一种广泛...通过深入学习这本《JavaScript面向对象编程指南(第2版)》,开发者不仅能掌握JavaScript的面向对象编程基础,还能了解到实际项目中如何有效地运用这些知识,提升编程技巧和解决问题的能力。
JavaScript作为一门浏览器语言的核心思想;...如何实现JavaScript中缺失的面向对象特性,如对象的私有成员与私有方法;如何应用适当的编程模式,发挥JavaScript语言特有的优势;如何应用设计模式解决常见问题等。
JavaScript,作为一种广泛应用...JavaScript 面向对象程序设计——继承与多态.pdf 和 JavaScript 面向对象程序设计——封装.pdf 这两个文档可能深入探讨了这些主题,帮助读者深入理解并掌握JavaScript的面向对象开发。
### JavaScript面向对象精要 #### 一、概述 《JavaScript面向对象精要》是一本深入讲解JavaScript面向对象编程原理的专业书籍。本书由知名的前端开发者Nicholas C. Zakas撰写,全面介绍了JavaScript作为一种动态...
JavaScript面向对象编程是一种基于原型(Prototype)的编程范式,它是动态类型语言,允许开发者创建具有复杂特性的对象。在JavaScript中,面向对象主要通过构造函数、原型链和闭包来实现。以下是对这一主题的详细...
JavaScript函数闭包是模拟面向对象编程的一种技术,它允许函数记住并访问其词法作用域,即使在函数执行完毕后也能保持对其的访问。这种特性使得JavaScript能够在没有内置类和继承等传统面向对象特性的情况下实现类似...
在这个“JavaScript面向对象基础”的资料中,我们将会探讨JavaScript中的类、对象、封装、继承以及多态等关键概念。 1. **对象与对象字面量** 在JavaScript中,对象是由键值对组成的无序集合,可以使用对象字面量...