1、属性类型:分为数据属性和访问器属性,都可以通过Object.defineProperty()方法来设置,传入的第一个参数是要修改的对象,第二个参数是对象的属性,第三个参数是一个对象,包括要设置的属性及属性值。定义多个属性用Object.defineProperties()。可以通过Object.getOwnPropertyDescription()方法来读取,第一个参数为要访问的对象,第二个参数是要访问的对象的属性,返回值是一个对象,用.value或者.configurable来获取属性。(configurable、enumerable、writable、value\configurable、enumerable、set、get)
2、js的设计模式:
一、工厂模式:
function createObjFactory(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
return o;
}
var person1 = createObjFactory('mike','28','teacher');
工厂模式虽然解决了创建多个相似的问题,可以省去很多重复性的代码。
但是也有缺点:没有解决对象识别问题(即怎样知道这个对象从哪来的)
二、构造函数模式:
function Person(name,age,job){ //大写
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
alert(this.name);
};
}
var person1 = new Person('john','23','doctor');
var person2 = new Person('wq','25','worm');
Person('hehe','12','dentist');//当做普通函数调用,当在全局作用域中调用一个函数时,this对象总指向Window对象
var o = new Object();
Person.call(o,'haha','22','actor');//此处不能写成o.Person('hehe','22','ee');因为o中不存在Person方法
这种创建对象的方式,可以通过调用person1.constructor来取得person1的构造函数(不过constructor是一个属性,可以随时改变),也可以用instanceof来检测:person1 instanceof Person //true person1 instanceof Object //true(person1是Person的实例也是Object的实例)。
但是也有缺点:Person中的sayName方法每次都要新建不同的Function实例;虽然可以把sayName定义为全局方法,可是如果一个构造函数要用到很多方法,那会在全局定义很多全局函数,丝毫没有封装性。
三、原型模式:
每个函数都有prototype(原型)属性,这个属性是一个指针,指向一个对象,包含了此函数的所有实例可以共享的属性和方法。所以:
function Person(){
}
Person.prototype.name = 'John';
Person.prototype.age = '9';
Person.prototype.sayName = function(){
alert('this.name');
}
var person1 = new Person();
person1.sayName(); //John
var person2 = new Person();
person2.sayName(); //John
alert(person1.sayName == person2.sayName) //true
这个模式也有缺点:给所有的实例都初始化了相同的属性值;虽然对共享函数是比较合适的,但是对于包含引用类型值的属性来说,问题就很突出了:比如prototype中有一个属性friends,它的value是一个数组,数组是一用类型,当在一个实例对象中改变friends属性的时候,另外一个实例中引用的值也跟着变化。
四、组合使用构造函数模式和原型模式:(使用最广泛的)
把需要共用的方法放到prototype中,把方法之外的其他值用构造函数的this中。
五、动态原型模式:
在构造函数中添加公共方法的时候,做个判断:
if(typeof this.sayName != function){
Person.prototype.sayName = function(){
alert(this.name);
}
}
这样可以保证只有第一次调用构造函数的时候才会执行六、寄生构造函数模式:
有一种情况:创建一个具有额外方法的特殊数组,犹豫不能直接修改Array的构造函数,可以使用这种模式。
function SpecialArray(){
var values = new Array();
values.push.apply(values,arguments);
values.toString = function(){
return this.join('|');
};
return values;
}
var colors = new SpecialArray('red','blue');
alert(colors.toString()); //'red|blue|green'
但是,返回的对象与构造函数与构造函数原型属性之间没有关系。
七、稳妥构造函数模式:
安全环境中,禁止使用this和new
稳妥对象:指的是没有公共属性,而且其方法也不引用this的对象。
function Person(name,age){
var o = new Object();
//这里可以定义私有变量和函数,外部访问不到
o.sayName = function(){
alert(name);
};
return o;
}
//调用的时候也不用new
var friend = Person('Nancy','11');
friend.sayName();