1. 创建对象的方式
var box = new Object(); //创建对象
box.name = "Mr Lee"; //添加对象属性
box.age = 100; //添加对象属性
box.run = function (){
return this.name + this.age; //this表示当前作用域下的对象。
}
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;
}
3. 构造函数/构造方法创建对象
function Box(name, age) { //使用构造
this.name = name;
this.age = age;
this.run = function () {
return this.name + this.age;
};
}
1) 构造函数不用new Object(), 但后台自动会var obj = new Object();
2) this = obj;
3) 构造函数不需要返回obj, 自动返回obj。
构造函数规范:
1) 构造函数也是函数,但函数名第一个字母大写
2) 必须使用new 构造函数名 创建相应对象
使用对象冒充调用:
var o = new Object();
Box.call(o, "Mr. Lee", 33);
var box1 = new Box("Lee", 100);
var box2 = new Box("Lee", 100); //box1和box2的属性和方法都是单独的一份,不相等。
4. 原型
每个函数都有一个prototype原型对象属性,保存共享属性或方法
function Box() { }
Box.prototype.name = "Lee";
Box.prototype.age = 100;
Box.prototype.run = function () {
return this.name + this.age;
}
box1 = new Box();
alert(box1.__proto__); //__proto__指向prototype对象。
alert(box1.constructor); //指向对象的构造方法。
var box1 = new Box();
alert(Box.prototype.isPrototypeof(box1)); 判断一个对象实例是不是指向了对象的原型对象。
//原型属性和实例属性冲突,就近访问实例属性,没有访问原型属性
var box1 = new Box();
box1.name = "Lee";
delete box1.name //删除实例属性
delete Box.prototype.name //删除原型属性
box1.hasOwnProperty("name") //判断实例是否有name属性,不在prototype中查找
alert("name" in box1); //在属性和实例中查找是否有name属性
5. 原型的字面量写法
function Box() {}
Box.prototype = { //Box.constructor指向object,而不是fucntion Box()
name: "Lee",
age: 100,
run: function() {
return this.name + this.age;
}
}
function Box() {}
Box.prototype = {
"constructor": Box, //强行指向Box
name: "Lee",
age: 100,
run: function() {
return this.name + this.age;
}
}
6. 原型的缺点
所有实例共享属性和方法,所以共享属性和方法放在prototype中定义,其他放在构造函数中。
7. 动态原型模式
function Box(name, age) {
this.name = name;
this.age = age;
Box.prototype.run = function (){ //但是run被赋值了2次
return this.name + this.age;
}
}
function Box(name, age) {
this.name = name;
this.age = age;
if(type of this.run != "function") { //避免run被赋值2次
Box.prototype.run = function (){
return this.name + this.age;
}
}
}
8. 继承
javascript通过原型链条实现类继承
function Box(){
this.name = "Lee";
}
funtion Desk(){
this.age = 100;
}
Desk.prototype = Box(); //把父类对象赋值给子类prototype,形成原型链
var desk = new Desk();
desk instanceof Desk //返回true
desk instanceof Box //返回true
9. 使用对象冒充技术实现继承
function Box() {
this.anem = name;
this.age = age;
}
function Desk(name, age) {
Box.call(this, name, age); //对象冒充,仅能继承实例属性和方法,不能继承原型属性和方法
}
Desk.prototype = new Box(); //对象冒充和原型赋值混合方式, 这种方式解决了传递参数给父类构造函数和prototype方法继承的问题。
10. 其他另类继承方式
1) 原型式继承
function obj(o) { //临时中转函数, o表示将要传递进入的一个对象
function F() { } //F构造是一个临时新建的对象,用来存储传递过来的对象
F.prototype = o; //将o对象实例赋值给F构造的原型对象
return new F(); //最后返回这个得到传递过来对象的对象实例
}
2) 寄生式继承
function create(o) {
var obj = obj(o);
obj.run = function(){
return this.name + this.age;
}
return obj;
}
3) 寄生组合继承
function create(box, desk) {
var f = obj(box.prototype);
f.constuctor = desk;
desk.prototytpe = f;
}