1. JS中对象由特性(attribute)构成,而 attribute=method(方法) + property(包括原始值和引用值)
2. js内置对象
Object, Boolean, String, Number, Function, Date, Array, RegExp, Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, UIRError
Global, Math
3. 可以把对象当做map使用
var arr = new Object();
arr["name"] = "allei";
alert(arr["name"]);
4. 对象
// 对象创建1.1
// 类似于JAVA中:先调用默认构造器,然后再setter
var obj = new Object();
//var obj = {}; // 等价于上面
obj.name = "allei";
obj.print = function () {
alert(this.name);
};
obj.print();
// 对象创建1.2
// 类似于java中的静态工厂
function createObject(name) {
var tmp = new Object();
tmp.name = name;
tmp.print = function () {
alert(this.name);
};
return tmp;
}
var obj1 = createObject("zhangsan");
var obj2 = createObject("lisi");
obj1.print();
obj2.print();
// 对象创建1.3
// 把对象的print函数提取出来
function fun () {
alert(this.name);
}
function createObject(name) {
var tmp = new Object();
tmp.name = name;
tmp.print = fun;
return tmp;
}
var obj1 = createObject("zhangsan");
var obj2 = createObject("lisi");
obj1.print();
obj2.print();
// 对象创建2.1
function Person(name, age) {
this.name = name;
this.age = age;
this.print = function () {
alert(this.name + " " + this.age);
};
}
var p1 = new Person("zhangsan", 33);
var p2 = new Person("lisi", 55);
p1.print(); // zhangsan 33
p2.print(); // lisi 55
// 对象创建3.1
function Person2(){}
Person2.prototype.name = "zhangsan";
Person2.prototype.print = function () {
alert(this.name);
};
var p3 = new Person2();
var p4 = new Person2();
p3.print(); // zhangsan
p4.print(); // zhangsan
alert(p3 instanceof Person2); // true
// 对象创建3.2
// 属性使用构造函数的方式
// 方法使用原型的方式
function Person3(name, age) {
this.name = name;
this.age = age;
this.friends = new Array("Apache", "Java");
}
Person3.prototype.print = function () {
alert(this.name + " " + this.age + " " + this.friends);
};
var p5 = new Person3("zhangsan", 22);
var p6 = new Person3("lisi", 33);
p5.friends.push("Tomcat"); // 各自的属性互不影响
p5.print(); // zhangsan 22 Apache,Java,Tomcat
p6.print(); // lisi 33 Apache,Java
5. StringBuffer
// StringBuffer实现
/*
// 和下面的定义等价
this.StringBuffer = function(){
this._arr = new Array();
};
*/
function StringBuffer(){
this._arr = new Array();
}
StringBuffer.prototype.append = function (str) {
this._arr.push(str);
};
StringBuffer.prototype.toString = function () {
return this._arr.join("");
};
var sb = new StringBuffer();
sb.append("hello ");
sb.append("world.");
alert(sb.toString());
// 极晚绑定
var obj = new Object(); // 定义对象
Object.prototype.fun = function () { // 增加方法
alert("xxxx");
};
obj.fun(); // 新增的方法可以立刻应用到对象上
6. 继承
// 继承1:对象冒充
function Person(name, age) {
this.name = name;
this.age = age;
this.print = function () {
alert("Person.print(): " + this.name + " " + this.age);
};
}
function Student(name, age, sno) {
this.personC = Person;
this.personC(name, age); // 类似于java的super()
delete this.personC;
// 新的属性和方法
this.sno = sno;
this.print = function () { // 重写父类方法
alert("Student.print(): " + this.name + " " + this.age);
};
this.printStu = function () {
alert(this.name + " " + this.age + " " + this.sno);
};
}
var p1 = new Person("zhangsan", 22);
var s1 = new Student("lisi", 33, "100001");
p1.print();
s1.print(); // 如果子类不覆盖父类的方法,那么这里调用的就是父类的方法,和JAVA一样
s1.printStu();
// 继承2.1: call或apply用法
function Father (arg1, arg2) {
alert(arg1 + " " + this.prop + " " + arg2);
}
var obj = new Object();
obj.prop = "xxx";
// call和apply的本质是把this指针转移
Father.call(obj, "aaa", "bbb");
Father.apply(obj, new Array("aaa", "bbb"));
// 继承2.2: call或apply
function Person(name, age) {
this.name = name;
this.age = age;
this.print = function () {
alert("Person.print(): " + this.name + " " + this.age);
};
}
function Student(name, age, sno) {
// 这里可以轻易实现多重继承,只需调用每个父类的apply或call方法即可
//Person.call(this, name, age);
Person.apply(this, new Array(name, age));
// 新的属性和方法
this.sno = sno;
this.print = function () { // 重写父类方法
alert("Student.print(): " + this.name + " " + this.age);
};
this.printStu = function () {
alert(this.name + " " + this.age + " " + this.sno);
};
}
var p1 = new Person("zhangsan", 22);
var s1 = new Student("lisi", 33, "100001");
p1.print();
s1.print(); // 如果子类不覆盖父类的方法,那么这里调用的就是父类的方法,和JAVA一样
s1.printStu();
// 继承3.1: 原型链
// 原型链继承中,父类的属性和方法都应该通过prototype定义,不要再构造函数中定义
function Water () {
}
Water.prototype.name="water"; // 父类的属性和方法
Water.prototype.fatherFun = function () {
alert(this.name);
};
function HotWater () {
}
HotWater.prototype = new Water(); // 父类的构造函数不应该有任何参数
HotWater.prototype.temperature = "hot"; // 子类的属性和方法,要在上面的赋值语句后定义。
HotWater.prototype.sonFun = function () {
alert(this.temperature + " " + this.name);
};
var w = new Water();
w.fatherFun();
var hotW = new HotWater();
hotW.sonFun();
// 继承3.2:原型链和对象冒充混合使用
function Father (name) {
this.name = name;
}
Father.prototype.print = function () {
alert("Father.print(): " + this.name);
};
function Son (name, age) {
Father.call(this, name); // 对象冒充实现继承
this.age = age;
}
Son.prototype = new Father(); // 原型链实现继承
Son.prototype.print = function () { // 重写父类方法
alert("Son.print(): " + this.name);
};
Son.prototype.printSon = function () {
alert("Son.printSon(): " + this.name + " " + this.age);
};
var father = new Father("father");
father.print();
var son = new Son("son", 12);
son.print(); // 如果子类不重写,则调用父类的print方法
son.printSon();