ECMAScript 有两种开发模式:1.函数式(过程化),2.面向对象(OOP)。面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。但是,ECMAScript 没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。
js本身是没有class类型的,但是每个函数都有一个prototype属性。prototype指向一个对象,当函数作为构造函数时,prototype则起到类似class的作用。
var box = new Object(); //创建一个Object 对象box.name = 'Lee'; //创建一个name 属性并赋值box.age = 100; //创建一个age 属性并赋值box.run = function () { //创建一个run()方法并返回值return this.name + this.age + '运行中...';};alert(box.run()); //输出属性和方法的值
上面创建了一个对象,并且创建属性和方法,并且实例化该对象,最后调用对象的方法。在run()方法里的this,就是代表box 对象本身。但是有个缺点就是不能实例化多个具有相似属性和方法的对象。于是我们想到了可不可以有一套模板来批量制作对象。于是就有了-工厂模式。看下面例子
function createObject(name, age) { //集中实例化的函数var obj = new Object();obj.name = name;obj.age = age;obj.run = function () {return this.name + this.age + '运行中...';};return obj;}var box1 = createObject('Lee', 100); //第一个实例var box2 = createObject('Jack', 200); //第二个实例alert(box1.run());alert(box2.run()); //保持独立
这种方法虽然制造出来了一套模板来规范待实例化的对象。但是还有许多问题,比如创建不同对象其中属性和方法都会重复建立,消耗内存,还有函数识别问题等等。其实还有更优秀的也是用的最多的方法,看下面示例。
function Box(name, age) { //构造函数模式this.name = name;this.age = age;this.run = function () {return this.name + this.age + '运行中...';};}var box1 = new Box('Lee', 100); //new Box()即可var box2 = new Box('Jack', 200);alert(box1.run());alert(box1 instanceof Box); //很清晰的识别他从属于Box
这个方法看似像一个函数,但又有些不太一样。比如函数名一般都小写。如果学过其他面向对象的语言就会知道,这是类的写法(此处不多分析,非强制,但这么写有助于区分构造函数和
普通函数)。这种方法是构造函数创建对象的写法,通过构造函数创建对象,必须使用new 运算符。构造函数可以创建对象执行的过程:
1)当使用了构造函数,并且new 构造函数(),那么就后台执行了new Object();2)将构造函数的作用域给新对象,(即new Object()创建出的对象),而函数体内的this 就代表new Object()出来的对象。3)执行构造函数内的代码;4)返回新对象(后台直接返回)。
注:
1)构造函数和普通函数的唯一区别,就是他们调用的方式不同。只不过,构造函数也是函数,必须用new 运算符来调用,否则就是普通函数。
2)this就是代表当前作用域对象的引用。如果在全局范围this 就代表window 对象,如果在构造函数体内,就代表当前的构造函数所声明的对象。
这种方法解决了函数识别问题,但消耗内存问题没有解决。同时又带来了一个新的问题,全局中的this 在对象调用的时候是Box 本身,而当作普通函数调用的时候,this 又代表window。即this作用域的问题。