JavaScript学习总结--创建对象(6_其他方法)

前面我们一共介绍了四种方法用来封装对象(工厂,构造模式,原型模式,构造+原型),并且重点对构造函数+原型模式做了一些改进,使之更加完美,那么除了这几种方法, 还有两种方式用来封装对象,还是那句话,选择适合自己的(其实每种方法都各有利弊,在我刚开始学习时总感觉就是拆东墙补西墙)。

首先来看第一种方法

function Person(name,age){
  var o=new Object();
  o.name=name;
  o.age=age;
  o.sayName=function(){
    console.log(this.name);
  };
  return o;
}
var person_01=new Person("Sakura",22);
var person_02=new Person("Misaka",20);

看到这我猜你多半在想大哥你蒙我呢?这不是工厂模式啊呸,这不是构造函数啊呸这是啥?

这就是工厂模式+构造函数混合模式,有人把它叫寄生构造函数模式(mdzz)

首先我们看到这种模式在原本构造函数的基础上又增加了工厂模式,即在函数内部创建了一个新对象o,最后又返回出这个新对象o

书上讲这种模式可以在特殊情况下用来为对象创建构造函数,有一个例子

function SpecArr(){
  var values=new Array();
  values.push.apply(values,arguments);
  values.toPopedString=function(){
    return this.join("|");
  }
return values;
}
var colors=new SpecArr('red','blue','green');
console.log(colors.toPopedString());
//red|blue|green

这段代码啥意思呢?

1.首先创建了一个构造函数SpecArr

2.然后又在构造函数内部创建了一个数组对象

3.又给这个数组对象利用apply对象冒充,再用方法添加了一些数组元素(调用时赋值)(由于这里构造函数并没有指定参数个数,所以使用apply,传入arguments对象)

4.然后给这个数组对象添加了一个方法,该方法的作用是使用“|”符号将数组合并为一个字符串

5.最后返回这个对象

那么说到底,当我们需要为某个原生对象添加自定义方法时,使用诸如Array.prototype.xxx不被允许,所以通过这种方法,可以仅仅给通过这个构造函数实例化的内置对象添加一个私有的方法,该方法只对这个实例化的对象可见

var a=['456','fsdf','dasfgg'];
a.toPopedString();
console.log(a);

//error:Uncaught TypeError: a.toPopedString is not a function

所以其他未通过这个构造函数实例化的数组对象无法调用这个方法

需要注意的是使用这种方法创建出来的对象不能再用instanceof操作符来确定对象的类型(当然这个例子中colors instanceof Array为true,而colors instanceof  SpecArr则为false)

总的来说这种方法还是尽量少用,除非在之前四种方法无法满足的情况下再使用这种方法

第二种 (稳妥构造函数模式)

这种方法是著名的道格拉斯·克罗克福德(Douglas Crockford,蝴蝶书的作者)发明的

这种方法适合在一些安全的环境中,这种环境中可能会禁止使用this和new

稳妥构造函数模式与上面的寄生构造函数模式有点像,举个栗子吧

function Person(name,age){
  var o=new Object();
  //这里可以再定义一些私有属性和方法
  o.sayName=function(){
    console.log(name);
  }
  return o;
}
var person_01=Person("Sakura",22);
person_01.sayName();

这样创建的对象,你会发现没有使用new关键字调用构造函数,而是直接调用了构造函数,所以person_01再用无法直接调用它的属性(name,age等),只有通过sayName才能访问他的属性,这使得它非常适合在某些安全执行环境中运行

 

好了,封装对象的方法一共就这么多(6种),反正都是各有利弊吧,最后两种可以权当了解,接下来将引入面向对象第二大特性

待续

...

posted @ 2016-06-02 21:14  Sakura_大表哥  阅读(140)  评论(0编辑  收藏  举报