一、创建对象
1、直接new
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()); </span>
2、利用工厂模式方法
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()); //保持独立</span>
工厂模式解决了重复实例化的问题,但还有一个问题,那就是识别问题,因为根本无法
搞清楚他们到底是哪个对象的实例。
alert(typeof box1); //Object
alert(box1 instanceof Object); //true
2、利用构造函数
ECMAScript 中可以采用 构造函数(构造方法)可用来创建特定的对象。类型于 Object 对象。
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</span>
构造函数的方法有一些规范:
1.函数名和实例化构造名相同且大写,(PS:非强制,但这么写有助于区分构造函数和
普通函数);
2.通过构造函数创建对象,必须使用 new 运算符。
既然通过构造函数可以创建对象,那么这个对象是哪里来的,new Object()在什么地方
执行了?执行的过程如下:
1.当使用了构造函数,并且 new 构造函数(),那么就后台执行了 new Object();
2.将构造函数的作用域给新对象,(即 new Object()创建出的对象),而函数体内的 this 就
代表new Object()出来的对象。
3.执行构造函数内的代码;
4.返回新对象(后台直接返回)。
使用了构造函数的方法,和使用工厂模式的方法他们不同之处如下:
1.构造函数方法没有显示的创建对象(newObject());
2.直接将属性和方法赋值给 this 对象;
3.没有 renturn 语句。
构造函数和普通函数的唯一区别,就是他们调用的方式不同。只不过,构造函数也是函
数,必须用 new 运算符来调用,否则就是普通函数。
PS:关于 this 的使用,this 其实就是代表当前作用域对象的引用。如果在全局范围 this 就代
表window 对象,如果在构造函数体内,就代表当前的构造函数所声明的对象。
二、原型
首先是称呼问题,我姑且称没有没有new的对象或函数成为类
类里既有prototype属性和__proto__属性,而对象里只有__proto__属性。
<span style="font-size:18px;">function Box() {} //声明一个构造函数
Box.prototype.name = 'Lee'; //在原型里添加属性
Box.prototype.age = 100;
Box.prototype.run = function () { //在原型里添加方法
return this.name + this.age + '运行中...';
};
//比较一下原型内的方法地址是否一致:
var box1 = new Box();
var box2 = new Box();
alert(box1.run == box2.run); //true,方法的引用地址保持一致</span>
a、b是foo类的对象,但a、b的_proto_指向的是父类Foo的Prototype。
__proto__属性指向的才是自己的原型,而prototype是父对象的属性,子对象是继承父对象的prototype属性指向的对象的属性和方法。
使用原型的好处可以让所有对象实例共享它所包含的属性和方法
<span style="font-size:18px;">function Box(name,age) { //不共享的使用构造函数
this.name = name;
this.age = age;
this. family = ['父亲','母亲', '妹妹'];
};
Box.prototype = { //共享的使用原型模式
constructor : Box,
run : function () {
return this.name +this.age + this.family;
}
};
这种混合模式很好的解决了传参和引用共享的大难题
三、继承
实现继承的方式依靠原型链完成。
function Box() { //Box 构造
this.name = 'Lee';
}
function Desk() { //Desk 构造
this.age = 100;
}
Desk.prototype = new Box(); //Desc 继承了Box,通过原型,形成链条
var desk = new Desk();
alert(desk.age);
alert(desk.name); //得到被继承的属性
function Table() { //Table 构造
this.level = 'AAAAA';
}
Table.prototype = new Desk(); //继续原型链继承
var table = new Table();
alert(table.name); //继承了Box 和 Desk
Staff.prototype = newPerson()的继承