设计模式——构造函数模式

工厂模式虽然实现了批量生产,但是不能进行品牌的区分-->"实例识别"

对象:一个泛指,js中万物皆对象
:对象的一个具体的细分
实例:类中一个具体的事物
例如:自然界中万物皆对象,我们把自然中的事物分为了几大类:人类、动物类、植物类...而每一个人都是我们人类中的一个实例
我们想学习js,我们需要给js分类,然后在研究每一个类别中具体的东西-->面向对象的编程思想
所有的编程语言都是面向对象开发的-->js也是一门轻量级的脚本编程语言
面向对象开发-->研究 类的继承、封装、多态

js中的类:内置类(浏览器天生自带的)、自定义类

内置类
Object(对象类)、Array(数组类)、RegExp(正则类)、Date、Math、Number(数字类)、String(字符串类)、Boolean(布尔类)、Function(函数类)、Null、Undefined
每一个对象数据类型都是Object这个类的一个实例,每一个数组都是数组类的实例,每一个字符串都是String这个类的一个实例......

可以在控制台console.dir(Array.prototype); 就可以清晰地看到Array上的方法,方便我们学习



HTMLColle ction(元素集合类)-->包含获取的所有的元素,它是一个类数组,我们通过getElementsByTagName、getElementsByClassName等获取的元素结合都是这个类的一个实例
console.dir(document.getElementsByTagName("div"));
console.dir(document.getElementsByClassName(".w"));

NodeList(节点集合类)-->获取的节点集合(类数组),都是这个类的一个实例
console.dir(document.getElementsByName("zhufeng"));

CSSStyleDeclaration(元素的行内样式集合类)
通过元素的style获取的样式集合都是这个类的一个实例

HTMLDivElement(div元素标签类)-->每一个HTML标签都一个自己对应的类
HTMLElement、Element、Node、EventTarget、Document、Window....
console.dir(document.getElementById("div1"));



自定义类:自己想创建一个类,需要如何的处理?--->构造函数模式

function Fn() {
            var a = 12;
            this.b = 13;
            this.c = function () {
                console.log(14);
            }
        }
        var f1 = new Fn(); //f1是Fn的一个实例
  

此时, Fn就是一个自定义类

使用构造函数模式来创建自定义类-->构造函数和普通函数的区别?
1、普通的函数的名字遵循驼峰命名法,构造函数的名字我们一般都让第一个单词首字母大写(约定俗成的一个技巧,但是不是强制的)
2、在执行的时候,普通函数createPerson("A小伙伴",7);,但是构造函数模式执行不一样了var p1=new CreatePerson("A小伙伴",7);
  通过new执行的我们称之为构造函数模式,此时CreatePerson就不叫做函数名了而叫做(CreatePerson类)-->类是函数数据类型的
  通过构造函数执行返回的结果叫做当前类的一个实例,例如:p1就是CreatePerson类的一个实例-->实例是对象数据类型的
3、在作用域中运行的时候
  构造函数模式执行和普通函数执行一样,都会形成一个私有的作用域,里面首先给形参赋值,然后在预解释,JS代码从上到下执行-->构造函数也有普通函数的一面
  1)在构造函数模式中,我们不需要手动的创建对象(也不需要手动的返回,工厂模式是需要手动创建和返回的),浏览器会默认的创建一个对象(并且当代码执行完成后自动返回)
  2)然后JS代码开始从上到下执行,在执行的过程中,我们把对应的属性和方法,分别的添加给我们浏览器自己创建的那个对象,并且函数中以这个对象为执行的主体(this)
  浏览器默认创建的那个对象数据类型的数据,其实就是我们当前类的一个实例,而函数中的this也是当前类的一个实例-->只有this.xxx=xxx才是相当于给当前的实例增加属性和方法

function CreatePerson(name, age) {
        age = age || 25;
        var index = 3;//index是私有作用域中的一个私有的变量,和当前的实例没有任何的关系
        this.name = name;//这样才相当于给我们的实例增加了属性name
        this.age = age;
        this.say = function () {
            console.log("my name is " + this.name + "~ my age is " + this.age + "~ i can say chinese~");
        };

        //return 100;
        //return {name:"哈哈"};
        //浏览器会把默认创建的实例对象返回,如果我们手动加了return:
        //1)返回的是基本数据类型值,对最后的实例没有影响
        //2)返回的是引用数据类型值,会把默认返回的实例对象覆盖掉,返回的就不是当前类的实例了,p1就不在是CreatePerson的实例了
    }
    var p1 = new CreatePerson("A小伙伴", 7);
    //console.log(p1.name);//"A小伙伴"
    //console.log(p1.index);//undefined

    var p2 = new CreatePerson;//在不传第参数的情况下,可以把()省略

 注意:

一、类是函数数据类型的,而它的实例是对象数据类型

console.log(typeof CreatePerson);//->"function"
console.log(typeof p1);//->"object"

  

二、检测某一个实例是否属于这个类 instanceof

console.log(p1 instanceof CreatePerson);//->true
console.log(p1 instanceof Object);//->true p1也是一个对象数据类型的值,所以它也是Object这个类的一个实例
console.log(p1 instanceof Array);//->false

  


三、JS中提供了hasOwnProperty用来检测某一个属性是否是这个对象的私有属性
in:检测某一个属性是否属于这个对象(既可以检测私有的属性,也可以检测公有的属性)

console.log(p1.hasOwnProperty("say"));//-->true
console.log("say" in p1);//-->true

  


自己编写一个方法实现:检测某一个属性attr是否为obj这个对象的公有属性

function myHasPubProperty(attr, obj) {
  return (attr in obj) && !(obj.hasOwnProperty(attr));
}

  

 

posted @ 2015-11-25 21:51  cataway  阅读(412)  评论(0编辑  收藏  举报