这里写目录标题
一、对象的基本理解
1. 对象的属性类型
1.1 数据属性
-
数据属性中描述其行为的4个特性
- Configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,或者能否把属性修改为属性访问器
- Enumerable:表示能否通过for-in循环放回属性
- Writeable:表示能否修改属性的值
- Value:这个属性的属性值
**默认情况下处Value外的三个特性的值均为true **
-
修改属性的默认特性必须使用object.defineProperty()方法
- 这个方法的三个参数分别为:属性所在的对象,属性的名字,和一个描述符
var person ={} object.defineProperty(person,"name",{ // 将属性的可修改属性设置为false writable:false, // 设置属性的value值 value:'张三' }) alert(person.name) // 张三 person.name = '李四' alert(person.name) //张三
- 当使用object.defineProperty()创建一个新的属性时,如果不指定,configurable、enumerable和writable都默认为false
- 【注】:当属性的特性设置为不可修改时,在非严格模式下对属性进行赋值时将会被忽略,在严格模式下会报错
1.2、访问器属性
- 访问器属性的四个特性
- Configurable:表示能否通过delete删除属性从而重新定义属性,能否修改属性的特性,能否将属性修改为数据属性
- Enumerable:表示能否通过for-in循环返回属性
- Get:在读取属性时调用的函数,默认情况下为undefined
- Ser:在写入属性时调用的函数,默认情况下为undefined
var book ={ /*year前的下划线表示只通过对象方法访问的属性*/ _year:2004, edition:1, } Object.defineProperty(book,"year",{ get:function(){ return this._year; }, set:function(newVal){ if(this._year>2004){ this._year = newVal; this.edition += newVal-2004; } } }) // 设置属性的值 book.year = 2005; alert(book.edition); //2
二、创建对象方式
1. 工厂模式
创建一个函数,用函数来封装特定的接口
function createPerson(name,age,job){
var o = new Object()
o.name = name;
o.age = age;
o.sayName = function(){
console.log(this.name)
}
return o
}
var person1 = createPerson('zs',22,'student')
2. 构造函数模式
Object和Array这种原生构造函数,在运行时会自动出现在执行环境中
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.sayName = function(){
return this.name
}
}
var person1 = new Person('zs',22,'student')
3. 原型模式
每创建一个函数都会有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法
funuction Person(){}
Person.prototype.name = 'zs';
Person.prototype.age = 29;
Person.prototype.job = 'student';
Person.prototype.sayName = function(){
console.log(this.name)
}
var person1 = new Person();
person1.sayName(); //zs
var person2 = new Person();
person2.sayName(); //zs
console.log(person1.sayName === person2.sayName); //true
- 更简单的原型语法
function Person(){}
Person.prototype = {
name:'张三',
age:22,
job:'student',
sayName(){
console.log(this.name)
}
}
这种方法创建对象constructor属性不再指向Person,而是指向Object
4、组合使用构造函数模式和原型模式
创建自定义类型的最常见的方式,就是组合使用构造函数模式和原型模式
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
}
Person.prototype = {
constructor:Person,
sayName:function(){
console.log(this.name)
}
}
var person1 = new Person('zs',22,'student');
var person2 = new Person('ls',23,'software');
console.log(person1.name === person2.name); //false
console.log(person1.sayName === person2.sayName); //true
5、动态原型模式
可以通过检查某个应该存在的方法是否有效,来决定是否需要初始化原型
function Person(name,age,job){
// 属性
this.name = name;
this.age = age;
this.job = job;
// 方法
//只有在sayName()方法不存在的情况下,才会把它添加到原型中,以下代码只在初次调用构造函数时才会执行
if(typeof this.sayName != 'function'){
Person.prototype.sayName = function(){
console.log(this.name);
}
}
}
var person1 = new Person('zhangsan',29,"student");
person1.sayName();//zs
6、寄生构造函数模式
这种模式的基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码
function Person(name,age,job){
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.sayName = function(){
console.log(this.name);
}
return o;
}
var person1 = new Person('zs',22,'student');
person1.sayName();// zs
7、稳妥构造函数模式
该模式的特点是
- 新创建对象的实例方法不用this
- 不使用new操作符调用构造函数
function Person(name,age,job){
var o = new Object();
// 这里可以定义私有变量和函数
o.sayName = function(){
console.log(name);
}
return o;
}
var person1 = Person("zs",22,"student");
person1.sayName();// zs