# javascript快速入门12--函数式与面向对象
## 函数
函数是一组可以随时随地运行的语句。
函数是 ECMAScript 的核心。
创建函数
```
function fnOne() {//具有名称的函数,函数名必须符合变量名命名规范
//可以没有符何语句
}
var fnTwo = function () {//匿名函数
};
function () {//创建匿名函数而不立即创建其引用,那么之后就没办法调用此函数
}
(function fnThree() {
})();//创建函数并立即执行一次
(function () {})();//创建匿名函数并立即执行一次
```
匿名函数与命名函数的区别
```
fnOne();//不会出错,使用function创建的具有名称的函数在任何与之相同作用域的地方都能调用
fnTwo();//出错
var fnTwo =function () {};//因为只有执行了这个赋值语句后,fnTwo才会被创建
function fnOne() {}
```
函数返回值
```
function fnTest() { return "value";//使用return来返回值
alert("Hello!!!");//执行了return之后,函数就会退出
}
```
函数参数
```
function fnTest(arg1,arg2,arg3) {
alert(arg1+"\n"+arg2+"\n"+arg3);
}
fnTest(1,2,3);
fnTest(1,2);//没有传值过去时,就会是undefined
```
arguments对象:在函数执行时函数内部就会有arguments对象,它包含了所有的参数,arguments的length属性报告了传入参数个数
```
function fnTest() { for (var i=0;i< arguments.length;i++) {
alert(arguments[i]);
}
}
fnTest(1,2,3);
fnTest(45);
```
使用arguments对象模拟函数重载
```
function fnTest() { var args = arguments; switch (arguments.length) { case 0 : return "没有输入!!!"; case 1 : return "一个参数:"+args[0]; case 2 : return "二个参数:"+args[0]+" 和 "+ args[1];
}
}
alert(fnTest());
alert(fnTest(1));
alert(fnTest(2));
```
arguments对象补充:arguments对象的callee属性指向它所在的函数
```
function fnTest() {alert(arguments.callee);}
```
## 闭包
闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量。
在 ECMAScript 中使用全局变量是一个简单的闭包实例。请思考下面这段代码:
```
var msg = "我是全局变量!!!"; function say() {
alert(msg);
}
say();
```
在ECMAScript中,在函数声明处向函数外部看到的声明的所有变量,在函数内部都能访问到它们的最终值!
```
var g = "全局变量!!!"; function fnA() { var a="A"; function fnB() { var b="B";
alert(a);//可以访问到a
alert(c);//但不以访问c
function fnC() { var c = "C";
alert(a+"\n"+b);//只要遵循从里向外看的原则,看到的变量都可以访问到
}
}
} //更复杂的闭包
function fnTest(num1,num2) { var num3 = num1+num2; return function () {
alert("num1+num2结果为"+num3);
};
} var result = fnTest(23,56);
result();
```
闭包函数只能访问变量的最终值!!!
```
function fnTest(arr) { for (var i=0;i < arr.length;i++) {
arr[i]=function () {
alert(i+" | "+arr[i]);
};
}
} var arr = [0,1,2,3,4,5];
fnTest(arr); for (var i=0;i < arr.length;i++) {
arr[i]();//始终输出6还有一个undefined
//因为函数退出后,i值为6,所以访问到的值只有6
}
```
不但在闭包中可以访问闭包外的变量值,而且还可以设置它的值
```
function fnTest() { var a=123; return {
set:function (param) {a = param},
get:function () {return a}
};
} var obj = fnTest();
alert(obj.get());//123
obj.set(4);
alert(obj.get());//4
```
## 对象,构造函数
创建一个对象
```
var obj = new Object();
alert(obj);
alert(Object);//一个函数
Object();//可以直接执行
//构造函数也是一个普通的函数
function Demo() {
} var d = new Demo();//不会出错,使用new运算符来创建对象实例
alert(d);//object
```
this关键字的用法
```
function Demo() { this.property = "属性!!!";
}
d = new Demo();
alert(d.property);//属性!!!
```
不使用new而直接执行构造函数时,this指向window
```
function Demo() { this.property = "属性!!!";
} var d = Demo();
alert(d.property);//undefined
alert(window.property);//属性!!!
```
可以给构造函数传递参数,然后可以将参数赋值给对象的属性
```
function Person(name,age) { this.name = name; this.age = age;
} var p1 = new Person("CJ",18);
```
instanceof 运算符,用来判断对象是否是某个类(虽然ECMAScript中并不存在类,但我们在这里依然使用这一术语)的实例
```
var str = new String("string");
alert(str instanceof String);//true
var arr = new Array();
alert(arr instanceof Array);//true
function Demo() {} var d = new Demo();
alert(d instanceof Demo);//true
```
## 面向对象术语
一种面向对象语言需要向开发者提供四种基本能力:
* 封装——把相关的信息(无论数据或方法)存储在对象中的能力。
* 聚集——把一个对象存储在另一个对象内的能力。
* 继承——由另一个类(或多个类)得来类的属性和方法的能力。
* 多态——编写能以多种方法运行的函数或方法的能力。
ECMAScript支持这些要求,因此可被看作面向对象的。
### 封装与私有属性:封装并不要求私有!
```
function Person(name,age) { this.name = name;//将值存储为对象的属性即是封装
this.age = age;
} var p1 = new Person("CJ",18);
```
ECMAScript目前版本并不支持私有属性,但可以通过闭包来模拟
```
function Person(name,age) { this.getName = function () {return name}; this.setName = function (param) {name=param}; this.getAge = function () {return age}; this.setAge = function (param) {age=param};
} var p1 = new Person("CJ",18);
alert(p1.name);//undefined
alert(p1.getName());//CJ
p1.setName("XXX");
alert(p1.getName());//XXX
```
### 继承:prototype属性
ECMAScript中,继承是通过构造函数的prototype属性实现的
```
function Person(name,age) { this.name=name; this.age = name;
}
alert(Person.prototype);//object
Person.prototype.sort = "人"; var p1 = new Person("CJ",18);
alert(p1.sort);//所有的Person对象的实例继承了sort这个属性
```
所有对象都有一个方法isPrototypeOf(),用来判断它是不是另一个对象的原型
```
function Person() {} var p1 = new Person();
alert(Person.prototype.isPrototypeOf(p1));//true
```
在ECMAScript中让一个类继承另一个类的方式比较特殊
```
function ClassA() { this.a = "A";
} function ClassB() { this.b = "B";
}
ClassB.prototype = new ClassA(); //让ClassB继承ClassA
var b = new ClassB();
alert(b.a);//"A",继承了属性a
alert(b instanceof ClassB);//true
alert(b instanceof ClassA);//true,因为继承,b也是ClassA的后代
alert(ClassB.prototype.isPrototypeOf(b));//true
alert(ClassA.prototype.isPrototypeOf(b));//true,ClassA.prototype也是b的原型
```
然而这样的继承有个注意点——
```
function ClassA() { this.a = "A";
} function ClassB() { this.b = "B";
} var b = new ClassB();//先实例化ClassB
ClassB.prototype = new ClassA();//再去继承ClassA,将prototype重置为另一个对象
alert(b instanceof ClassB);//false
alert(b instanceof ClassA);//false
alert(ClassB.prototype.isPrototypeOf(b));//false
alert(ClassA.prototype.isprototypeOf(b));//false
```
当构造函数需要参数时
```
function Person(name,age) { this.name = name; this.age = age;
} function Teacher(name,age,lesson) { this.tempMethod = Person;//对象冒充
this.tempMethod(name,age); //当执行Person时,由于是在Teacher某个实例上调用的,所以在Person函数中的this指向了Teacher的实例
delete this.tempMethod;//删除临时方法
this.lesson = lesson;
}
ClassB.prototype =new ClassA();//始终不应在继承时放参数
var t1 = new Teacher("HUXP",18,"C#");
alert(t1.name+" | "+ this.age+ " | "+this.lesson);
```
事实上,对于对象冒充,ECMAScript提供了更简洁的内置方法call,在每个函数上调用,第一个参数即为要冒充的对象,剩下的是函数需要的其它参数
```
function Demo(arg) { this.name = arg;
} var obj = new Object();
Demo.call(obj,"name");
alert(obj.name);//"name"
//使用call重写上面继承的例子
function Person(name,age) { this.name = name; this.age = age;
} function Teacher(name,age,lesson) {
Person.call(this,name,age);//对象冒充
this.lesson = lesson;
}
```
### 静态属性与Function类
在ECMAScript里有个有趣的地方是,函数本身也是对象(和数组也一样),也可使用new来创建.Function构造函数至少要传两个字符串参数,可以是空字符串。除了最后一个字符串会被当做函数体语句去执行,其它参数都会作为函数参数变量名!
```
var fn = new Function();//一个空函数
//创建有内容的函数
fn = new Function("arg1","alert(arg1)");//最后一个参数为执行语句的字符串,前面参数全是函数要用到的参数
//上面的代码等效于
fn = function (arg1) {alert(arg1)};//同样,由于都是赋值语句,所以要注意出现次序
fn.property ="既然是对象,那么就要以添加属性"
```
事实上,在构造函数上添加的属性就被称之为静态属性,它不会被实例所继承
```
function ClassDemo() {
}
ClassDemo.property = new Array(); var d =new ClassDemo();
alert(d.property);//undefined
alert(ClassDemo.property);//object
```
Function类的实例还有其它一些方法和属性(当然,使用function关键字声明的函数也是一样的)
```
function outer() {
inner(); function inner() {
alert(inner.caller); //函数的caller属性指向调用自身的上下文函数,这里指向outer
}
} function applyTest() { var args = arguments; this.name = args[0]; this.age=args[1];
} var obj = new Object();
applyTest.apply(obj,["name",18]);
alert(obj.name);
alert(obj.age); //apply方法与call方法类似,也用于对象冒充,只是apply方法只有两个参数
//第一个是要冒充的对象,第二个是所有参数组成的数组
```
- 介绍
- HTML/CSS 教程
- 第 1 章 HTML5 概述
- 第 2 章 基本格式
- 第 3 章 文本元素
- 第 4 章 超链接和路径
- 第 5 章 分组元素
- 第 6 章 表格元素
- 第 7 章 文档元素
- 第 8 章 嵌入元素
- 第 9 章 音频和视频
- 第 10 章 表单元素[上]
- 第 10 章 表单元素[中]
- 第 10 章 表单元素[下]
- 第 11 章 全局属性和其他
- 第 12 章 CSS 入门
- 第 13 章 CSS 选择器[上]
- 第 14 章 CSS 颜色与度量单位
- 第 15 章 CSS 文本样式[上]
- 第 15 章 CSS 文本样式[下]
- 第 16 章 CSS 盒模型[上]
- 第 16 章 CSS 盒模型[下]
- 第 17 章 CSS 边框与背景[上]
- 第 17 章 CSS 边框与背景[下]
- 第 18 章 CSS 表格与列表
- 第 19 章 CSS 其他样式
- 第 20 章 CSS3 前缀和 rem
- 第 21 章 CSS3 文本效果
- 第 21 章 CSS3 文本效果
- 第 23 章 CSS3 边框图片效果
- 第 24 章 CSS3 变形效果[下]
- 第 25 章 CSS3 过渡效果
- 第 26 章 CSS3 动画效果
- 第 27 章 CSS 传统布局[上]
- 第 27 章 CSS 传统布局[下]
- 第 28 章 CSS3 多列布局
- 第 29 章 CSS3 弹性伸缩布局[上]
- 第 29 章 CSS3 弹性伸缩布局[中]
- 第 29 章 CSS3 弹性伸缩布局[下]
- 第 30 章 使用 Emmet 插件
- Bootstrap 教程
- 第 1 章 Bootstrap 介绍
- 第 2 章 排版样式
- 第 3 章 表格和按钮
- 第 4 章 表单和图片
- 第 5 章 栅格系统
- 第 6 章 辅组类和响应式工具
- 第 7 章 图标菜单按钮组件
- 第 8 章 输入框和导航组件
- 第 9 章 路径分页标签和徽章组件
- 第 10 章 巨幕页头缩略图和警告框组件
- 第 11 章 进度条媒体对象和 Well 组件
- 第 12 章 列表组面板和嵌入组件
- 第 13 章 模态框插件
- 第 14 章 下拉菜单和滚动监听插件
- 第 15 章 标签页和工具提示插件
- 第 16 章 弹出框和警告框插件
- 第 17 章 按钮和折叠插件
- 第 18 章 轮播插件
- 第 19 章 附加导航插件
- 第 20 章 项目实战--响应式导航[1]
- 第 20 章 项目实战--响应式轮播图[2]
- 第 20 章 项目实战--首页内容介绍[上][3]
- 第 20 章 项目实战--首页内容介绍[下][4]
- 第 20 章 项目实战--资讯内容[5,6]
- 第 20 章 项目实战--案例和关于[7]
- javaScript 教程
- javascript快速入门1--JavaScript前世今生,HelloWorld与开发环境
- javascript快速入门2--变量,小学生数学与简单的交互
- javascript快速入门3--分支判断与循环
- javascript快速入门4--函数与内置对象
- javascript快速入门5--数组与对象
- javascript快速入门6--Script标签与访问HTML页面
- javascript快速入门7--ECMAScript语法基础
- javascript快速入门8--值,类型与类型转换
- javascript快速入门9--引用类型
- javascript快速入门10--运算符,语句
- javascript快速入门11--正则表达式
- javascript快速入门12--函数式与面向对象
- javascript快速入门13--BOM——浏览器对象模型(Browser Object Model)
- javascript快速入门14--DOM基础
- javascript快速入门15--节点
- javascript快速入门15--表单
- javascript快速入门16--表格
- javascript快速入门17--事件
- javascript快速入门18--样式
- javascript快速入门19--定位
- javascript快速入门20--Cookie
- javascript快速入门21--DOM总结
- javascript快速入门22--Ajax简介
- javascript快速入门23--XHR—XMLHttpRequest对象
- javascript快速入门24--XML基础
- javascript快速入门25--浏览器中的XML
- javascript快速入门26--XPath
- javascript快速入门27--XSLT基础
- PHP 教程
- 第一章 如何加载运行已发布的PHP项目
- 第二章 PHP基础
- 第三章 操作符与控制结构
- 第四章 数学运算
- 第五章 数组
- 第六章 目录与文件
- 第七章 自定义函数
- 第八章 字符串处理
- 第九章 正则表达式
- 第十章 日期与时间
- 第十一章 表单与验证
- 第十二章 会话控制
- 第十三章 上传文件
- 第十四章 处理图像
- 第十五章 MySQL 数据库
- 第十六章 PHP 操作MySQL
- 第十七章 面向对象基础
- 第十八章 面向对象的特性
- 第十九章 面向对象的工具