1. 属性类型
数据属性
①Configurable 表示能否通过delete删除属性,默认值true
②Enumerable 表示能否通过for-in循环访问属性,默认值true
③Writable 表示能否修改属性的值,默认值true
④Value 包含这个属性的默认值,默认值Undefined.
var person = {}; Object.defineProperty(person, 'name', { configurable: false, value: 'Nicholas' } ); alert(person.name); delete person.name; alert(person.name);
访问器属性
①set 在写入属性时调用的函数
②get 在读取属性时调用的函数
var book = { _year: 2004, edition: 1 }; Object.defineProperty(book,'year',{ get: function(){ return this._year; }, set: function(newValue){ if(newValue > 2004){ this._year = newValue; this.edition += newValue - 2004; } } }); book.year = 2005; alert(book.edition); //2
2. 创建对象
①构造函数当做函数用
function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.sayName = function(){ alert(this.name); } } // 构造函数 var person = new Person('Nicholas', 29, 'software Engineer'); person.sayName(); // 作为普通函数 Person('Greg', 27, 'Dector'); //添加到了window(在全局作用域中调用一个函数,this对象总是指向浏览器中的window对象) window.sayName(); // 作为另一个对象作用域调用 var o = new Object(); Person.call(o,'Kristen', 25, 'Nurse'); //可以使用call()或者apply() 在某个特殊对象的作用域中调用Person()函数,这里在对象o的作用域调用的,因此调用后o就拥有了所有的属性和sayName()方法。 o.sayName();
②把函数变成全局变量,添加到对象里面
function sayName(){ alert(this.name); }; function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; //直接指向全局的sayName方法 } var person1 = new Person('Nicholas', 29, 'software'); person1.sayName();
3. 原型模式
①使用
function Person(){ } Person.prototype.name = 'Nicholas'; Person.prototype.age = 29; Person.prototype.job = 'software'; Person.prototype.sayName = function(){ alert(this.name); } var person1 = new Person(); person1.sayName();
②理解 个人理解:每个对家都有一个构造函数,这个原型对象的属性就有这个构造函数,只是这个原型对象还可以自己添加属性
这里要学习一个in操作符,判断通过对象能够访问给定属性时返回true,就是判断该属性是不是该对象的属性。alert('name' in Person);
③组合构造函数模式和原始模式 (使用最常见的模式)
//组合使用构造函数模式和原型模式 function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.friends = ['Shelby','Court']; } Person.prototype = { //重新定义原型对象 constructor: Person,//构造函数 sayName: function(){ alert(this.name); } }