JavaScript创建对象的模式

JavaScript创建对象的几种模式。

1.工厂模式

通过函数创建对象并返回这个对象

 1 function factoryMode(name,age) {
 2     var o = new Object();
 3     o.name = name;
 4     o.age = age;
 5     o.rap = function () {
 6         alert("bla bla");
 7     }
 8     return o;
 9 }
10 var tu = factoryMode("tu", 25);
11 var tan = factoryMode("tan", 24);
View Code

工厂模式的缺点是无法知道这个对象是什么类型的。

2.构造函数模式。

function Person(name, age) {
    this.name = name;
    this.age = age;
    this.intro = function () {
        alert("name:" + this.name + ",age:" + this.age)
    };
    this.clothes = {};

}
var tu = new Person("tu", 25);
var tan = new Person("tan", 24);
alert(tu.intro == tan.intro)   //false
alert(tu.clothes == tan.clothes) //false

构造函数的模式缺点是:没创建一个实例就会为每一个引用属性或者函数创建新的实例。这些实例的函数是不同的对象

可以将构造函数中的函数定义为全局函数,这样每个对象的这个函数就指向同一个函数。但是这样就失去了封装的意图。

3.原型模式

3.1 每个创建的函数都有一个prototype属性,这个属性指向一个对象,既函数的原型对象。原型对象有一个属性constructor指向这个函数。

每个通过这个函数创建的实例有一个[[prototype]]的属性,没有提供方法访问它。这个属性执行的是创建该对象的原型对象。部分浏览器支持对象_proto_属性获得其[[prototype]]属性。

1 function Person() {
2 }
3 Person.prototype.name = "tu";
4 Person.prototype.age = 25;
5 Person.intro=function(){};
6 var person1 = new Person();
7 var person2 = new Person();
8 person1.intro == person2.intro  //true

3.2原型对象的属性及方法

 isPrototypeOf() 该原型是否为对象的原型对象  如:Person.prototype.isPrototypeOf(person1)  //true

3.3获取对象的[[Prototype]]属性

  • _proto_ 部分浏览器支持,不是emcascript的标准
  • Object.getPrototypeOf(object) 如Object.getPrototypeOf(person1) 

 3.4 检测对象的属性

  查找对象的属性的过程如下,先查找该对象的属性,如果没有就去构造函数中查找,最后去原型对象中查找

  • hasOwnProperty(属性名) ,这个属性是否存在于该对象上,而是不从原型对象中来的。person1.hasOwnProperty("name")  //false
  • in 操作符 ,判断对象有这个属性,无论来自原型还是对象自己。"name" in person1;//true
  • for - in ,在使用 for-in 循环时,返回的是所有能够通过对象访问的、可枚举的(enumerated)属性,其中既包括存在于实例中的属性,也包括存在于原型中的属性
  • object.keys()  返回对象的所有属性的字符串集合。Object.keys(person1) //[]    Object.keys(person1.__proto__) //  ["name", "age"]

3.5 通过字面量为原型对象赋值。  

这种方式原型的constructor属性指向的是Object,可以手动修改这个值,并且将其[[enumerable]]设为false

3.6原型的动态性。

原型和对象是松散的关系。实例与原型之间的连接只不过是一个指针,所以动态为原型对象添加属性对象也可以访问到。

3.7原型模式的问题

  • 构造函数参数,结果所有的实例初始化时所有的属性值是一模一样的。
  • 原型中的引用类型的属性是共享的,所以这就存在在一个实例中修改了其引用属性的值,其他对象也会随之变化。这个问题很严重

4.采用构造函数和原型模式两种方式结合的方式。

在构造函数中定义实例属性,在原型对象中定义共享的属性和方法。

5.动态原型模式,在构造函数中为原型对象添加属性。可以判断其存在与否

posted @ 2019-07-26 15:06  tooSimple_sz  阅读(151)  评论(0)    收藏  举报