JavaScript九阴真经 第三章:函数的对象化能力
任何一个函数都可以为其动态地添加或去除属性,这些属性可以是简单类型,可以是对象,也可以是其他函数。也就是说,函数具有对象的全部特征,你完全可以把函数当对象来用。其实,函数就是对象,只不过比一般的对象多了一个括号“()”操作符,这个操作符用来执行函数的逻辑。即,函数本身还可以被调用,一般对象却不可以被调用,除此之外完全相同。请看下面的代码: functionSing(){
with(arguments.callee) alert(author + \:\};
Sing.author = \李白\
Sing.poem = \汉家秦地月,流影照明妃。一上玉关道,天涯去不归 \Sing();
Sing.author = \李战\Sing.poem = \日出汉家天,月落阴山前。女儿琵琶怨,已唱三千年 \Sing(); 初识原型 prototype源自法语,软件界的标准翻译为“原型”,代表事物的初始形态,也含有模型和样板的意义。JavaScript中的prototype概念恰如其分地反映了这个词的内含,我们不能将其理解为C++的prototype那种预先声明的概念
JavaScript的所有function类型的对象都有一个prototype属性。这个prototype属性本身又是一个object类型的对象,因此我们也可以给这个prototype对象添加任意的属性和方法。既然prototype是对象的“原型”,那么由该函数构造出来的对象应该都会具有这个“原型”的特性。事实上,在构造函数的prototype上定义的所有属性和方
法,都是可以通过其构造的对象直接访问和调用的。也可以这么说,prototype提供了一群同类对象共享属性和方法的机制。 我们先来看看下面的代码: functionPerson(name) {
this.name = name; //设置对象属性,每个对象各自一份属性数据 };
//给Person函数的prototype添加SayHello Person.prototype.SayHello = function()方法。{
alert(\}
varBillGates = newPerson(\创建BillGates对象 varSteveJobs = newPerson(\创建SteveJobs对象 BillGates.SayHello(); //通过BillGates对象直接调用到SayHello方法 SteveJobs.SayHello(); //通过SteveJobs对象直接调用到SayHello方法
alert(BillGates.SayHello == SteveJobs.SayHello); //因为两个对象是共享prototyp e的SayHello,所以显示:true 程序运行的结果表明,构造函数的prototype上定义的方法确实可以通过对象直接调用到,而且代码是共享的。显然,把方法设置到prototype的写法显得优雅多了,尽管调用形式没有变,但逻辑上却体现了方法与类的关系,相对前面的写法,更容易理解和组织代码。那么,对于多层次类型的构造函数情况又如何呢? 我们再来看下面的代码:
functionPerson(name) { //基类构造函数
this.name = name; };
Person.prototype.SayHello = function(){ //给基类构造函数的prototype添加方法
alert(\};
functionEmployee(name, salary) { //子类构造函数 Person.call(this, name); //调用基类构造函数 this.salary = salary; };
Employee.prototype = newPerson(); //建一个基类的对象作为子类原型的原型, 这里很有意思
Employee.prototype.ShowMeTheMoney = function(){ //给子类添构造函数的pr ototype添加方法
alert(this.name + \ };
varBillGates = newPerson(\创建基类Person的BillGates对象 varSteveJobs = newEmployee(\创建子类Employee 的SteveJobs对象
BillGates.SayHello(); //通过对象直接调用到prototype的方法
SteveJobs.SayHello(); //通过子类对象直接调用基类prototype的方法,关注! SteveJobs.ShowMeTheMoney(); //通过子类对象直接调用子类prototype的方法 alert(BillGates.SayHello == SteveJobs.SayHello); //显示:true,表明prototyp e的方法是共享的
创建对象的两种方法 基于object 使用字面量
创建第二个对象的还是一样的,哪些属性又要重新写一遍, 如何解决重复的代码
可以使用构造函数【其实就是一个平通对象】 //定义构造函数
function Flower(name,age,){ }
//通过构造函数创建对象
var flower1 = new Flower(\长春花1\,12); var flower2 = new Flower(\长春花1\,12); flower1.showName(); flower2.showName(); //constructor看看flower是不是Flower的构造函数 alert(flower1.constructor==Flower); alert(flower2.constructor==Flower); //使用instanceof操作符检测对象类型 alert(flower1 instanceof Flower);//true alert(flower1 instanceof Object);//true
优化构造函数:
this.name=name; this.age=age;
this.showName=function(){ }
alert(this.name);
每个方法都需要在示例里面重新创建一遍,
每一个构造方法里面都有一个shouName()的方法重新创建 对于我们的这些方法能不能放在一个一个function示例中, 能不能把这个函数独立出去呢
//定义构造函数
function Flower(name,age,){ }
function showName(){有一个指针指导构造函数 //这里相当于一个全局的变量 }
如果定义很多的方法,也要写很多, 避免方法的方法的重构
每个函数都有一个prototype属性,这个属性是一个指针, 指向一个对象
prototype就是通过调用构造函数而创建的那个对象实例的原型对象
alert(this.name); this.name=name; this.age=age;
//this.showName=function(){ //}
//alert(this.name);