1.对象的概念:无需属性的集合,属性可以为数值,对象或函数,ECMAscript中没有类的概念,这点是javascript与其他面向对象(OO)语言不同的地方。
//创建一个自定义对象 var person=new Object(); person.name="Tom"; person.age=23; person.job="web前端工程师"; person.sayName=function(){ alert(person.name); } person.sayName(); //用对象字面量语法来创建自定义对象 var person={ name:"Tom", age:23, job:"web前端工程师", sayName:function(){ alert(this.name); } } person.sayName();
2.属性类型
(1)为了描述对象属性(property)的各种特征,ECMAscript引入特性(attribute)的概念,同时为了表示特性是内部值,所以将特性放在[[]]中。
(2)ECMAscript有俩中属性:数据属性和访问器属性
数据属性的特性:[[Configurable]]:表示能否通过delete删除属性从而重新定义属性,默认为true。
[[Enumerable]]:表示能否通过for-in循环来返回属性。默认为true。
[[Writable]]:表示能否修改属性的值。默认为true。
[[Value]]:包含这个属性的值。默认为undefined。
如果想修改数据属性的特性可以调用defineProperty(属性所在对象,"属性名",{描述符对象})。
var person={}; Object.defineProperty(person,"name",{ writable:false, value:"Tom" }); alert(person.name); delete person.name; alert(person.name);
注意:调用defineProperty()时,没有指定Configurable,writable,enumerable特性时,默认为false。
访问器属性:[[Configurable]]同上。
[[Enumerable]]同上。
[[Get]]:在读取属性是调用,默认为undefined
[[Set]]:在写入属性时调用,默认为undefined
Object.defineProperties()可以通过描述符一次定义多个属性
Object.getOwnPropertyDescriptor(book,"_year");读取属性的特性,返回的是对象。
-----------------------------------------------------------------分割线---------------------------------------------------------------------------------------------------
创建对象的方式:
1.工厂模式
function createPerson(name,age,job) { var o=new Object(); o.name=name; o.age=age; o.job=job; o.sayName=function(){ alert(this.name);//this指的是o } return o; } var person1=createPerson("Tom",23,"web前端工程师"); person1.sayName();
工厂模式虽然解决多次创建相似对象的重复性问题,但是并没有解决对象识别问题,也就是typeof之后他都显示object,具体的对象是什么并没有显示(ps传送门对象都有哪些http://blog.sina.com.cn/s/blog_70a3539f0101eww3.html),所以构造函数模式出现了。
2.构造函数模式
function Person(name,age,job) { this.name=name; this.age=age; this.job=job; this.sayName=function(){ alert(this.name);//this是Person } } var person1=new Person("Tom",23,"web前端工程师"); person1.sayName();
构造函数模式和工厂模式的区别
1.没有显式的创建对象。
2.将属性和方法赋给了this对象。
3.没有return语句。
4.函数名第一个字母大写。
构造函数模式优于工厂模式的原因就是,构造函数模式中的对象实例(person1)通过constructor属性或instanceof操作符可以验证person1既是Object的实例,也是Person的实例,同时也证明所有对象均来自于Object。
但是构造函数也有缺点,对象是引用类型,对象实例化不是指针的改变,而是简单的复制,复制对象的方法和属性,假设一个对象有上千个实例,它就会复制上千个功能相同的方法,这显然是不可取的。
function Person(name,age,job) { this.name=name; this.age=age; this.job=job; this.sayName=sayName; } function sayName(){ alert(this.name) } var person1=new Person("Tom",23,"web前端工程师"); person1.sayName();
我们也可以把sayName()函数的定义战役到构造函数的外部,这样我们就将sayName属性设置成等于全局的sayName函数,这样实例化对象就共享全局作用域中的同一个sayName(),解决了构造函数对象方法的多次创建问题。但是全局作用域定义的sayName()函数只能被某个对象调用谈什么全局作用域,而且如果构造函数对象的方法有很多,就需要定义很多全局函数,封装性又从何谈起,于是原型模式应运而生。
原文:http://www.cnblogs.com/iwebkit/p/6476672.html