`

JS函数与面向对象

阅读更多

        函数是一组可以随时随地运行的语句。

一.JS函数

        创建函数:

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    P1的原型是不是Person

        在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方法只有两个参数
//第一个是要冒充的对象,第二个是所有参数组成的数组

 

文章来源:http://www.cnblogs.com/koeltp/archive/2012/09/08/2676028.html

分享到:
评论

相关推荐

    js 面向对象实例

    综合以上知识,`js 面向对象实例`涵盖了JavaScript中的面向对象编程基础,以及如何将这些概念应用到HTML5 Canvas的实践中。通过学习和实践这个实例,你不仅可以理解JavaScript的OOP机制,还能掌握如何利用Canvas API...

    Javascript面向对象编程.

    面向对象编程(Object-Oriented Programming,OOP)是编程的一种重要范式,JavaScript也完全支持这一特性,尽管它并非一种传统的静态类型语言。这篇博客文章可能详细讨论了如何在JavaScript中实现面向对象编程。 在...

    Javascript函数与对象

    ### JavaScript函数与对象详解 在JavaScript中,函数与对象是两个核心概念,它们构成了这门语言的基石。本文将深入探讨这两个主题,帮助读者更好地理解并掌握JavaScript。 #### 函数 函数是JavaScript中的第一类...

    面向对象JavaScript精要(英文原版pdf)

    - **第七章:混合式编程**:介绍如何结合面向对象编程与其他编程范式(如函数式编程)来构建复杂的系统。 #### 五、读者对象及学习目标 本书适合有一定JavaScript基础的开发者阅读。通过本书的学习,读者可以深入...

    JavaScript面向对象编程指南.pdf

    如何实现JavaScript中缺失的面向对象特性,如对象的私有成员与私有方法;如何应用适当的编程模式,发挥JavaScript语言特有的优势;如何应用设计模式解决常见问题等。 《JavaScript面向对象编程指南》着重介绍...

    第15章 javascript面向对象与原型

    在深入讲解JavaScript面向对象与原型的知识点之前,首先需要了解JavaScript的基础知识。在JavaScript中,面向对象编程(OOP)的概念虽然存在,但是它的实现与传统基于类的语言有所不同。ECMAScript,也就是...

    JavaScript面向对象编程指南

    如何实现JavaScript中缺失的面向对象特性,如对象的私有成员与私有方法;如何应用适当的编程模式,发挥JavaScript语言特有的优势;如何应用设计模式解决常见问题等。, 《JavaScript面向对象编程指南》着重介绍...

    JavaScript函数式编程

    JavaScript 是近年来非常受瞩目的一门编程语言,它既支持面向对象编程,也支持函数式编程。本书专门介绍JavaScript函数式编程的特性。 全书共9章,分别介绍了JavaScript函数式编程、一等函数与Applicative编程、...

    JS面向对象经典案例

    JS 面向对象经典案例 在JavaScript中,面向对象编程是非常重要的一部分。它提供了一种创建和组织代码的方式,能够让开发者更好地组织和维护代码。在本文中,我们将介绍JavaScript面向对象编程中的经典案例,包括...

    面向对象JavaScript开发

    JavaScript,作为一种广泛应用...JavaScript 面向对象程序设计——继承与多态.pdf 和 JavaScript 面向对象程序设计——封装.pdf 这两个文档可能深入探讨了这些主题,帮助读者深入理解并掌握JavaScript的面向对象开发。

    javascript面向对象编程

    JavaScript作为一门浏览器语言的核心思想;...如何实现JavaScript中缺失的面向对象特性,如对象的私有成员与私有方法;如何应用适当的编程模式,发挥JavaScript语言特有的优势;如何应用设计模式解决常见问题等。

    js真正了解面向对象.pdf

    在JavaScript中,理解面向对象编程(OOP)的概念是至关重要的,因为它是实现复杂逻辑和模块化代码的基础。以下是一些关于JavaScript面向对象的知识点: 1. 数据类型: JavaScript具有五种基本数据类型:number、...

    JavaScript面向对象编程指南(第2版).rar

    面向对象编程(Object-Oriented Programming,OOP)是JavaScript中的一个重要概念,它允许开发者通过对象来组织代码,提高可读性和可维护性。本指南的第二版深入探讨了JavaScript的面向对象特性,旨在帮助开发者更好...

    面向对象javascript

    在JavaScript中,我们可以使用函数对象来实现面向对象的编程。函数对象可以作为值赋给变量、作为参数传递给另一个函数、或作为其它函数的返回值。 在JavaScript中,我们可以使用prototype链来实现继承。prototype链...

    JAVASCRIPT 面向对象编程精要

    本文介绍了JavaScript面向对象编程的基本概念和技术细节,包括变量和对象的基础用法、函数的作用以及如何通过封装和继承来构建复杂的对象层次结构。JavaScript的独特之处在于它的灵活性和动态性,这使得它成为了一种...

    javascript面向对象框架

    Prototype是JavaScript的一个开源库,它扩展了JavaScript的基本对象和函数,提供了强大的面向对象特性。Prototype的核心功能包括类的创建、原型继承、元素操作、事件处理以及Ajax交互。通过Prototype,开发者可以更...

    js面向对象简单理解

    在JavaScript中,我们可以通过构造函数、原型和实例来实现面向对象编程。 首先,让我们从构造函数开始。在JavaScript中,构造函数是一种特殊类型的函数,用于创建和初始化对象。例如,我们可以定义一个名为`Person`...

    JavaScript 面向对象编程详细讲解文档

    JavaScript是一种动态类型的脚本语言,虽然它不像Java或C#那样拥有传统的类和实例机制,...虽然JavaScript的面向对象模型与传统的面向对象语言有所不同,但这并不妨碍我们利用它的灵活性和强大功能来编写高质量的代码。

Global site tag (gtag.js) - Google Analytics