珠峰培训

web前端设计模式-构造函数

作者:jiangwen

2016-08-14 23:20:01

288

1.设计模式

1.1 单例模式

对象数据类型的作用:

  • 把描述同一件事物的属性和方法放在同一段堆内存中,起到分组的作用,防止冲突;
  • 这样不同事物间即使属性名一样也不会发生冲突.

这种分组的编写代码模式叫做单例模式;在单例模式中把对象名叫做命名空间

单例模式是一种项目开发中经常使用的模式,可以使用单例模式进行模块化开发。例:

var person = {
name: "Amy",
age: 12,
write: function(){
alert(this.name,this.age);
}
};
person.write();

1.2 工厂模式

单例模式虽然解决了分组的问题,但是不能实现批量的生产,属于手工作业模式。
工厂模式是把实现同一件事情的代码放到一个函数中,如果以后想实现这个功能,只需执行当前函数就可以了,这就叫做函数的封装

函数的封装,是为了低耦合高内聚,减少页面中的冗余代码,提高代码的重复利用率

function factory(name,age){
var obj = {};
obj.name = name;
obj.age = age;
obj.write = function(){
alert(this.name+"can write JS!");
}
return obj;
}
var p1 = factory("Amy",12);
var p2 = factory("Bob",14);
p1.write();
p2.write();

2.构造函数

2.1 构造函数的目的

构造函数模式的目的就是为了创建自定义类,并且创建这个类的实例
构造函数模式拥有了类和实例的概念,并且实例和实例之间是相互独立的,在JS中叫做实例识别

2.2 构造函数的特点

function CreatePerson(name,age){
//浏览器默认创建的对象就是实例p1
this.name = name;
this.age = age;
this.write = function(){
console.log(this.name,this.age);
}
//浏览器默认将创建的实例返回
}
var p1 = new CreatePerson('Amy',18);
var p2 = new CreatePerson('Bob',18);
var p3 = CreatePerson("Cindy",20);
//这样就是普通函数执行方式,并非构造函数执行,则函数中this指window(方法名前没有点),p3没有返回值,则为undefined

2.2.1 构造函数成为类

  • 从形式上看,一个函数被作为构造函数还是普通函数执行的唯一区别,看是否使用了new运算符。
  • 当通过new执行后,createPerson就是一个类了。
  • 执行的时候,构造函数是new Person();而createPerson()只是普通函数执行。
  • 约定俗成的规范是首字母大写:new Person();newCreatePerson();

回顾数组的创建方式:

//字面量创建方式
var arr = [];
//实例创建方式--构造函数执行方式
var arr = new Array();

不管这两种哪种方式,arr都是Array类的实例

JS中所有的类都是函数数据类型的,通过new执行变成一个类,但是他本身也是一个普通函数

JS中所有的实例是对象数据类型的

2.2.2 构造函数的异同

相同点:都是形成一个私有作用域,然后形参赋值,然后预解析,代码从上至下执行(类和普通函数一样,类也具有普通函数的一面);
不同点:构造函数在代码执行之前,不用手动创建对象,浏览器会默认创建一个对象数据类型的值(这个对象就是当前类的实例,以当前实例为主体,将属性名和属性值赋给实例,this代表当前实例),浏览器会默认将创建的实例返回

2.2.3 this在构造函数中

this在构造函数中,就是当前类的实例;这也是this的第四种情况

2.2.4 构造函数的独立性

虽然各个实例p1,p2都是CreatePerson的实例,都拥有write方法,但是不同实例之间的方法是不一样的;实例和实例之间是单独的个体,所以私有属性之间不相等

console.log(p1.write === p2.write); //false

3.构造函数-扩展

3.1 构造函数的本质

  1. 在构造函数中,new Fn()执行,如果Fn()中不需要传递参数的话,后边的()可以省略
function Fn(){
this.x = 100;
this.getX = function(){
console.log(this.x);
}
}
var f = new Fn;
  1. 在类中出现的this.xxx=xxx中,this都是当前类的实例,而某一个属性值(方法),方法中的this则需要看方法前面的点才能知道this是谁
var ss = f.getX;
ss(); //undefined-->window下没有x属性
  1. 类有普通函数一面,也有构造函数一面
function Fn(){
var num = 10;
//this.num
this.x = 100;
this.getX = function(){
console.log(this.x);
}
}
var f1 = new Fn();
console.log(f1.num); //undefined

var num只是当前形成私有作用域中的一个私有变量,只有this才能给当前实例增加属性和方法

  1. 在构造函数模式中,
    1).浏览器会默认把实例返回,返回的是对象数据类型的值;
    2).如果手动写返回值了,若返回基本数据类型的值,当前实例是不变的;
    3).若返回引用数据类型的值,当前实例会被返回的值替换掉
function Fn(){
this.x = 100;
this.getX = function(){
console.log(this.x);
}
//浏览器默认返回实例
//return 100; 基本数据类型
//return {"name":100} 引用数据类型,会替换原有返回值
}

3.2 检测方法

  1. 检测某个实例是否属于这个类–>instanceof
var f1 = new Fn();
console.log(f1 instanceof Fn); //true
console.log(f1 instanceof Array); //false
console.log(f1 instanceof Obejct); //true-->所有实例都是对象数据类型的,而每一个对象数据类型都是Object内置类的实例
  1. “in”检测某个属性是否属于这个对象–> attr in object,不管是公有属性还是私有属性,只要存在则返回true
console.log('getX' in f1); //若返回true,则证明getX是f1的私有方法
  1. hasOwnProperty用来检测某一属性是某对象的私有属性,只能检测私有属性
console.log(f1.hasOwnProperty(getX)); //true-->说明getX是f1的私有属性

检测某一属性为该对象的公有属性

function hasPubProperty(obj,attr){
return (attr in obj) && !obj.hasOwnProperty(attr);
}
  1. isPrototypeOf来判断指定对象object1是否存在于另一个对象object2的原型链中,是则返回true,否则返回false。
object1.isPrototypeOf(object2);