昨天晚上去图书馆借书,没想到看到这么一本书,还挺新的。。就拿过来看了一眼,貌似是我需要的啊,面向对象的动态语言,灵活著称,可以帮助我理解原型对象还有为自己封装自己的库打下基础。。好了,开始学习吧。。我现在整的是好兴奋,没有哪件事可以让我这么激动想要去了解和学习。
第一篇 面向对象编程
第一章 灵活的语言
面向对象编程(OOP)是一种程序设计范型。它将对象作为程序的基本单元,将程序和数据封装在其中,以提高程序的重用性、灵活性和扩展性。
用对象收编函数:
var CheckObject = { checkName : function () { // 验证姓名 }, checkEmail : function () { // 验证邮箱 }, checkPassWord : function () { // 验证密码 } };
CheckObject. checkName();
将方法放入对象中,但是貌似这样做。。。好像是没有问题的对吧。但是!如果别人想要重用你的代码怎么办呢?如果是简单的复制一下,可以这样修改:
var CheckObject = function () { this.checkName = function () { // 验证姓名 }; this.checkEmail = function () { // 验证邮箱 }; this.checkPassWord = function () { // 验证密码 } }; var a = new CheckObject(); a.checkEmail();
这样就是一个类了,既然是一个类,那么我们就要用new关键字来创建新的对象。所有的方法都放在函数内部了,通过this定义的,所以每一次通过new关键字创建新对象的时候,新创建的对象都会对this上的属性进行复制。每个新创建的对象都有自己的一套方法了。。是复制没错,但是有时候消耗是很奢侈的,所以我们处理一下:
var CheckObject = function () {}; CheckObject.prototype = { checkName : function () { }, checkEmail : function () { }, checkPassword : function () { } }; var a = new CheckObject(); a.checkName(); a.checkEmail(); a.checkPassword();
这样子做,创建对象的方法就都是一个了,以为它们要依着原型链去寻找,而找到的方法都是同一个。但是调用了3个方法。。所以要写3次a。。
var CheckObject = function () {}; CheckObject.prototype = { checkName : function () { return this; }, checkEmail : function () { return this; }, checkPassword : function () { return this; } }; var a = new CheckObject(); a.checkName().checkEmail().checkPassword();
在JavaScript中this指向的是当前对象,所以可以将它返回。就可以写成和jQuery一样的链式结构了。。这个我觉得是,但是不确定,以后等我研读了jQuery的源码了再来思考是不是这样实现的。
Function.prototype.checkEmail = function () { // 验证邮箱 };
如果想给每一个函数都添加一个验证邮箱的方法就可以这样写。但是!!!这样污染了原生对象Function,别人创建的函数里也就包含了这个方法。但是可以自定义一个方法,这我在昨天的面试题里分析的时候就看到了!自己封装一个方法!
Function.prototype.addMethod = function ( name , fn ) { this.prototype[name] = fn; };
这里遇到了一些问题。。后面的代码貌似不起作用,不知道是作者写错了还是?所以那就下一章吧!
第二章 面向对象编程
在JavaScript中创建一个类很容易,首先声明一个函数保存在一个变量里。一般来说这个代表类的变量名首字母大写!!然后这个函数(类)的内部通过对this变量添加属性或方法来实现对类添加属性或方法。
var Book = function ( id , bookname , price ) { this.id = id; this.bookname = bookname; this.price = price; };
这样我们就将所需要的方法和属性封装在这个类里边了,但是我们不能直接使用这个类,还是需要用new关键字来实例化新的对象:
var book = new Book( 10 , 'Javascript设计模式' , 50 ); alert( book.bookname ); // Javascript设计模式
由于JavaScript的函数级作用域,声明在函数内部的变量和方法外部是访问不到的所以通过此特性我们可以创建类的私有变量和私有方法。然而通过this创建的,每隔对象自身都拥有一份且外部也可以访问到。因此this创建的属性可以看做是公有属性和公有方法。所以我们还可以将它作为特权方法。可以使用特权方法初始化实例对象的一些属性,因此这些在创建对象时调用的特权方法还可以看做是类的构造器。例:
var Book = function ( id , bookname , price ) { // 私有属性 var num = 0; // 私有方法 function ( checkId ) {} // 特权方法 this.getName = function () {}; this.getprice = function () {}; this.setName = function () {}; this.setPrice = function () {}; // 对象公有属性 this.id = id; // 对象公有方法 this.copy = function () {}; // 构造器 this.setName(); this.setPrice(); };
而其中:
// 类静态公有属性(对象不能访问) Book.isChinese = true; // 这里面是公有属性和方法 Book.prototype = { isJsBook : false, display : function () {} }; var b = new Book( 11 , 'JavaScript设计模式' , 50 );
console.log ( b.num ); //undefined console.log ( b.isJsBook ); // false console.log ( b.isChinese ); // undefined
console.log ( Book.isChinese ); // true
这样就很清楚啦!new出的实例显示:私有属性和静态公有属性,b中是访问不到的。而类的公有属性isJsBook是在b对象中可以访问的。
可是其中还有个问题。。就是我们在初学习的时候老是忘记了new关键字!所以返回的值就变成了undefined,为啥呢?new关键字相当于对当前对象的this的不停赋值,没有new那么就直接执行这个函数,所以这个函数就在全局作用域上执行了,那么就指向了window。
这里有一个解决的办法:
var Book = function ( title , time , type ) { // 判断this是否是当前的对象 if ( this instanceof Book ) { this.title = title; this.time = time; this.type = type; } else { // 否则重新创建这个对象 return new Book ( title , time , type ); } };