你的位置:首页 > Java教程

[Java教程]javascript 高级程序设计学习笔记(面向对象的程序设计) 1

Object构造函数或对象字面量都可以用来创建对象,但这些方式有个明显的缺点:使用相同一个接口创建很多对象,会产生大量重复代码。

工厂模式

//工厂模式  function createDog (name,age) {    var o = new Object();    o.name = name;    o.age = age;    o.sayAge = function () {       alert(age);     };    return o;  }    var dog1 = createDog("Bob","11");  var dog2 = createDog("Ann","5");

工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。

构造函数模式

//构造函数模式  function Dog (name,age) {     this.name = name;     this.age = age;     this.sayAge = function () {       alert(age);     };  }  var dog1 = new Dog("Bob","11");  var dog2 = new Dog("Ann","5");

这个例子中直接将方法和属性赋给了this对象。此时函数名Dog使用的D是大写字母,构造函数始终应该以一个大写字母开头,这主要是为了区别于ES中的其他函数;因为构造函数本身也是函数,只不过可以用来创建对象而已。

创建构造函数的新实例,必须使用 new 操作符。

以下为创建步骤

1.创建一个新对象;

2.将构造函数的作用域赋给新对象(this指向新对象);

3.执行构造函数的代码;

4.返回新对象。

dog1和dog2分别保存着Dog的一个不同的实例。这两个对象都有一个constructor(构造函数)属性,该属性指向Dog。

alert(dog1.constructor == Dog); //truealert(dog2.constructor == Dog); //true

constructor属性最初是用来标识对象类型的。检测对象类型还是用instanceof操作符更靠谱一些。

alert(dog1 instanceof Object) //truealert(dog1 instanceof Dog) //true

Dog1同时也是Object的实例,是因为所以对象均继承自Object。

构造函数也可以作为普通函数来调用

//作为普通函数Dog("Bob","11");window.sayAge(); //"11"//在另一个对象作用域中调用var o =new Object();Dog.call(o,"Bob","11");o.sayAge(); //11

构造函数的弊端:

每个方法都要在每个实例上重新创建一遍,这样会占用更多的内存,影响效率。

以这种方式创建的函数,会导致不同的作用域链和标识符解析。因此不同的实例上命名的函数是不相等的。

alert(dog1.sayAge == dog2.sayAge) //false

原型模式

我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象。

使用prototype对象的好处是不必再构造函数中定义对象实例的信息,而是将这些信息直接添加到prototype对象中。

function Dog(){}  Dog.prototype.name = "Bob";  Dog.prototype.age = "11";  Dog.prototype.jump = function(){alert("跳一下");};  var dog1 = new Dog();  dog1.jump();       //跳一下  var dog2 = new Dog();  dog2.jump();       //跳一下  alert(dog1.name);  alert(dog1.jump == Dog2.jump); //true  

原型对象的验证

  isPrototypeOf():

在创建自定义构造函数后,原型对象默认只会却constructor属性;其他方法从Object继承而来。当调用构造函数创建新实例后,该实例内部将包含一个指针

指向原型对象。但这个属性对脚本是完全不可见的,它存在于实例与构造函数的原型对象之间。

此时可以通过isPrototypeOf()方法来确定。

alert(Dog.prototype.isPrototypeOf(dog1)); //true

 Object.getPrototypeOf():

alert(Object.prototypeOf(dog1) == Dog.prototype); //truealert(Object.prototypeOf(dog1).name); //"Bob"

该方法可以取得对象的一个原型。

hasOwnProperty():

hasOwnProperty()方法可以检测一个属性是存在于实例中,还是原型中。

function Dog(){}  Dog.prototype.name = "Bob";  Dog.prototype.age = "11";  Dog.prototype.jump = function(){alert("跳一下");};  var dog1 = new Dog();  var dog2 = new Dog();  alert(dog1.hasOwnProperty("name")); //false  dog1.name = "Gina";  alert(dog1.name);  //"Gina"  alert(dog1.hasOwnProperty("name")); //true  alert(dog2.hasOwnProperty("name")); //false--来自原型

 所以,只有给定属性存在于对象实例中才会返回true,这里dog1的name被一个新值屏蔽了。