定制对象
var house = {
rooms: 7,
sharedEntrance: false,
lock:function(){},
unlock:function(){}
};
alert(house.rooms);
alert(house.sharedEntrance);
house.rooms = 8;
alert(house.rooms);
类
function Accommodation(){};
var house = new Accommodation(); //用new创建出来的对象都被称作是这个函数所示结构的对象实例
var apartment = new Accommodation(); //创建对象的过程就叫做模板实例化的过程
//找出对象的构造器
alert(house.constructor === Accommodation); //true
//还可以用 instanceof 来完成
alert(apartment instanceof Accommodation);
公有私有保护的属性和方法
var Accommodation = (function(){
//定义“类”的构造函数,因为处在一个新的函数内,我们也切换到一个新的作用域中,所以可以使用与保存函数返回值得那个变量相同的名字
function Accommodation(){};
//此处定义的所有变量都是私有的,为了区分加了_,这些变量在当前作用域之外不能用。
var _isLocked = false,
_isAlarmed = false,
_alarmMessage = "Alarm activated";
//仅在当前作用域中定义的函数也都是私有的
function _alarm(){
_isAlarmed = true;
alert(_alarmMessage);
}
function _disableAlarm(){
_isAlarmed = false;
}
//所有定义在原型上的方法都是公有的,当我们在此处创建类在闭包结束处被返回后,就可以在当前作用域之外访问这些方法了
Accommodation.prototype.lock = function(){
_isLocked = true;
_alarm();
}
Accommodation.prototype.unlock = function(){
_isLocked = true;
_disableAlarm();
}
//定义一个getter函数来对私有变量_isLocked的值进行只读访问——相当于把该变量定义为“受保护的”
Accommodation.prototype.getIsLocked = function(){
return _isLocked;
}
//定义一个setter函数来对私有变量_alarmMessage进行只写访问——相当于将其定义为“受保护的”
Accommodation.prototype.setAlarmMessage = function(message){
_alarmMessage = message;
};
//返回在这个作用域中创建的“类”,使之在外层作用域中即后面代码的所有位置都可用。只有共有的属性和方法是可用的。
return Accommodation;
}());
var house = new Accommodation();
house.lock();
// house._alarm(); //报错
alert(house._isLocked); //undefined
console.log(house.getIsLocked()); //true
house.setAlarmMessage("The alarm is now activated!");
house.lock(); //"The alarm is now activated!"
一个用于简化其他“类”创建的基“类”
//定义一个名为Class的对象,该对象有一个create()方法用于创建新的“类”。我们用闭包来维护内部函数;
//避免公开暴露这些函数
var Class = (function(){
//调用create()方法时,它将根据一个对象直接量来定义并且返回一个新的“类”,该对象直接量为这个“类”的原型提供了各种公有属性和方法。
//一个名为initialize()的方法将被作为构造函数来执行。如果代表父“类”的可选参数paraentPrototype被传入,则新创建的“类”将成为该父“类”的子类
function create(classDefinition,parentPrototype){
//定义新“类”的构造函数,如果classDefinition对象直接量包含initialize()方法,则在构造函数中使用该方法
var _NewClass() = function(){
if(this.initialize && typeof this.initialize === 'function'){
this.initialize.apply(this,arguments);
}
},
_name;
//(在继承其他“类”时)如果传入一个parentPrototype对象
//则子类将继承parentPrototypee的所有属性和方法
if(parentPrototype){
_NewClass.prototype = new parentPrototype.constructor();
for (_name in parentPrototype) {
if (parentPrototype.hasOwnProperty(_name)) {
_NewClass.prototype[_name] = parentPrototype[_name];
}
}
}
//通过定义一个函数来创建闭包,然后在闭包中返回另一个函数来替代传入的函数
//将传入的函数包装起来,并为当前对象提供一个_parent()方法,
//以支持父“类”中同名方法的访问,这样就实现了多态的支持
function polymorph(thisFunction,parentFunction){
return function(){
var output;
this._parent = parentFunction;
output = thisFunction.apply(this,arguments);
delete this._parent;
return output;
};
}
//将作为参数传入的“类”定义应用到新创建的“类”上,
//覆盖所有parentPrototype中已存在的属性和方法
for (_name in classDefinition) {
if (classDefinition.hasOwnProperty(_name)) {
//如果正在利用多态,即创建和父“类”方法同名的新方法,
//我们希望提供一种在子“类”方法中调用父“类”同名方法的简单方式
if (parentPrototype && parentPrototype[_name] && typeof classDefinition[_name] === 'function') {
_NewClass.prototype[_name] = polymorph(classDefinition[_name],parentPrototype[_name]);
}else{
//如果不需要多态,则直接将calssDefinition对象直接量中的项映射到新“类”的原型即可
_NewClass.prototype[_name] = classDefinition[_name];
}
}
}
//确保构造函数属性设置正确,不管是否继承
//(以防classDefinition对象直接量包含名为constructor的属性方法)
_NewClass.prototype.constructor = _NewClass;
//为新创建的“类”自身定义一个extend()方法,指向私有的extend()函数,这个函数定义在下面,
//我们通过此方法可以将当前“类”作为父“类”来创建一个新的子类
_NewClass.extend = extend;
return _NewClass;
}
//extend()与create()方法相同,不过隐含了一个额外的参数,即用来进行继承的父“类”的原型
function extend(classDefinition){
return create(classDefinition,this.prototype);
}
//用相同的名字将私有的create()方法暴露
return {create: create};
}());
对象方法
var personalDetails = {
name:"Den Odell",
email: "den.odell@me.com"
};
console.log(Object.isExtensible(personalDetails));//true
//阻止对personalDetails对象进行扩展
Object.preventExtensions(personalDetails);
console.log(Object.isExtensible(personalDetails));//false
//尝试为personalDetails对象添加一个新属性
personalDetails.age = 35; //如果开启严格模式就会报错