一、理解对象:

//第一种:基于Object对象
var person = new Object();
person.name = 'My Name';
person.age = ;
person.getName = function(){
return this.name;
} //第二种:对象字面量方式(比较清楚的查找对象包含的属性及方法)
var person = {
name : 'My name',
age : ,
getName : function(){
return this.name;
}
} //JS的对象可以使用.操作符动态的扩展其属性,可以使用delete操作符或将属性值设置为undefined来删除属性:
person.newAtt=“new Attr”; //添加属性
alert(person.newAtt); //new Attr
delete person.age;
alert(person.age); //undefined(删除属性后值为undefined); 二、对象属性类型 //ECMA-262第5版定义了JS对象属性中特征(用于JS引擎,外部无法直接访问)。ECMAScript中有两种属性:数据属性和访问器属性 、数据属性: // configurable: 表示能否使用delete操作符删除从而重新定义,或能否修改为访问器属性。默认为true;
// enumberable: 表示是否可通过for-in循环返回属性。默认true;
// writable: 表示是否可修改属性的值。默认true;
// value: 包含该属性的数据值。读取/写入都是该值。默认为undefined;如上面实例对象person中定义了name属性,其值为’My name’,对该值的修改都反正在这个位置
// 调用Object.defineProperty()方法,它接收三个参数:属性所在对象,属性名和一个描述符对象 var person = {};
Object.defineProperty(person, 'name', {
configurable: false,
writable: false,
value: 'Jack'
});
alert(person.name); //Jack
delete person.name;
person.name = 'lily';
alert(person.name); //Jack
// 值得注意的是一旦将configurable设置为false,则无法再使用defineProperty将其修改为true 、访问器属性: // 它主要包括一对getter和setter函数,在读取访问器属性时,会调用getter返回有效值;写入访问器属性时,调用setter,写入新值;该属性有以下4个特征:
// configurable:是否可通过delete操作符删除重新定义属性;
// numberable:是否可通过for-in循环查找该属性;
// get:读取属性时调用,默认:undefined;
// set:写入属性时调用,默认:undefined; // 访问器属性不能直接定义,必须使用defineProperty()来定义,如下:
var person = {
_age:
};
Object.defineProperty(person, 'isAdult', {
get: function(){
if(this._age >= ){
return true;
}else{
return false;
}
}
});
alert(person.isAdult?'成年':'未成年'); //成年
// 这里isAdult的值,是要通过函数来判断的,如果写value,后面返回的是函数体。所以通过get来设置
// 可知,定义访问器属性时getter与setter函数不是必须的,并且,在定义getter与setter时不能指定属性的configurable及writable特性; // Object.defineProperties()方法可以用来一次性定义多个属性的特性:
var person = {};
Object.defineProperties(person,{
_age:{
value:
},
isAdult:{
get: function () {
if(this._age >= ){
return true;
}else{
return false;
}
}
}
});
alert(person.isAdult?'成年':'未成年');//成年
// 上述代码使用Object.defineProperties()方法同时定义了_age及isAudlt两个属性的特性 、获取属性特性: // 此外,使用Object.getOwnPropertyDescriptor()方法可以取得给定属性的特性:
var descriptor = Object.getOwnPropertyDescriptor(person,'_age');
console.log(descriptor);
//Object {value: "19", writable: false, enumerable: false, configurable: false}
三、创建对象 //使用Object构造函数或对象字面量都可以创建对象,但缺点是创建多个对象时,会产生大量的重复代码,因此下面介绍可解决这个问题的创建对象的方法 、工厂模式 function createPerson(name, age, job) {
var o = new Object();
o.name = name;
o.age = age;
o.job = job;
o.getName = function () {
return this.name;
}
return o;//使用return返回生成的对象实例
}
var person = createPerson('Jack', , 'SoftWare Engineer');
//创建对象交给一个工厂方法来实现,可以传递参数,但主要缺点是无法识别对象类型,因为创建对象都是使用Object的原生构造函数来完成的。 、构造函数模式 function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.getName = function () {
return this.name;
}
}
var person1 = new Person('Jack', , 'SoftWare Engineer');
var person2 = new Person('Liye', , 'Mechanical Engineer'); // 使用自定义的构造函数(与普通函数一样,只是用它来创建对象),定义对象类型(如:Person)的属性和方法。它与工厂方法区别在于:
// 1.没有显式地创建对象
// 2.直接将属性和方法赋值给this对象;
// 3.没有return语句;
// 4.此外,要创建Person的实例,必须使用new关键字,以Person函数为构造函数,传递参数完成对象创建;实际创建经过以下4个过程: // a.创建一个对象
// b.将函数的作用域赋给新对象(因此this指向这个新对象,如:person1)
// c.执行构造函数的代码
// d.返回该对象
// 上述由Person构造函数生成的两个对象person1与person2都是Person的实例,因此可以使用instanceof判断,并且因为所有对象都继承Object,因此person1 instanceof Object也返回真: // instanceof判断是否是一个类的实例
alert(person1 instanceof Person);//true;
alert(person2 instanceof Person);//true;
alert(person1 instanceof Object);//true;
alert(person1.constructor === person2.constructor);//ture; // 虽然构造函数方式比较不错,但也存在缺点,那就是在创建对象时,特别针对对象的属性指向函数时,会重复的创建函数实例,以上述代码为基础,可以改写为:
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.getName = new Function () {//改写后效果与原代码相同,不过是为了方便理解
return this.name;
}
}
//上述代码,创建多个实例时,会重复调用new Function();创建多个函数实例,这些函数实例还不是一个作用域中,当然这一般不会有错,但这会造成内存浪费。当然,可以在函数中定义一个getName = getName的引用,而getName函数在Person外定义,这样可以解决重复创建函数实例问题,但在效果上并没有起到封装的效果,如下所示:
function Person(name,age,job){
this.name = name;
this.age = age;
this.job = job;
this.getName = getName;
}
function getName() {
return this.name;
} 、原型模式 // JS每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,它是所有通过new操作符使用函数创建的实例的原型对象。原型对象最大特点是,所有对象实例共享它所包含的属性和方法,也就是说,所有在原型对象中创建的属性或方法都直接被所有对象实例共享。 function Person(){};
Person.prototype.name = 'Jack';//使用!!!原型!!!来添加属性
Person.prototype.age = ;
Person.prototype.getName = function(){
return this.name;
}
var person1 = new Person();
alert(person1.getName());//Jack
var person2 = new Person();
alert(person1.getName === person2.getName);//true;共享一个原型对象的方法
// 实例属性或方法的访问过程是一次搜索过程:
// 1.首先从对象实例本身开始,如果找到属性就直接返回该属性值;
// 2.如果实例本身不存在要查找属性,就继续搜索指针指向的原型对象,在其中查找给定名字的属性,如果有就返回;
// 基于以上分析,原型模式创建的对象实例,其属性是共享原型对象的;但也可以自己实例中再进行定义,在查找时,就不从原型对象获取,而是根据搜索原则,得到本实例的返回;简单来说,就是实例中属性会屏蔽原型对象中的属性; // 原型与in操作符
// 一句话:无论原型中属性,还是对象实例的属性,都可以使用in操作符访问到;要想判断是否是实例本身的属性可以使用object.hasOwnProperty(‘attr’)来判断; // 原生对象中原型
// 原生对象中原型与普通对象的原型一样,可以添加/修改属性或方法,如以下代码为所有字符串对象添加去左右空白原型方法: String.prototype.trim = function(){
return this.replace(/^\s+/,'').replace(/\s+$/,'');
}
var str = ' word space ';
alert('!'+str.trim()+'!');//!word space! //原型模式的缺点,它省略了为构造函数传递初始化参数,这在一定程序带来不便;另外,最主要是当对象的属性是引用类型时,它的值是不变的,总是引用同一个外部对象,所有实例对该对象的操作都会其它实例:
function Person() {}
Person.prototype.name = 'Jack';
Person.prototype.lessons = ['Math','Physics'];
var person1 = new Person();
person1.lessons.push('Biology');
var person2 = new Person();
alert(person2.lessons); // Math,Physics,Biology,person1修改影响了person2

JS面相对象的更多相关文章

  1. js编程-面相对象

    //js面相对象编程 //定义constructor构造方法 function myFn(name,sex){ this.name = name; this.sex = sex; } //用proto ...

  2. js定义对象的几种容易犯的错误

    //js定义对象的几种容易犯的错误function Person() { getName = function (){ console.info(1); }; return this;}//Perso ...

  3. 模仿console自写函数打印js的对象

    本以为写个递归函数就可以将js的对象打印出来. 当然第一个想到的估计是JSON.stringify() 这个函数.但这个函数打印到浏览器 显示效果不友好.最友好的显示肯定是 控制台打印咯. 结果尝试打 ...

  4. js自定义对象

    一,概述 在Java语言中,我们可以定义自己的类,并根据这些类创建对象来使用,在Javascript中,我们也可以定义自己的类,例如定义User类.Hashtable类等等. 目前在Javascrip ...

  5. Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换

    Atitit 跨平台异常处理(2)--------异常转换 -----java c# js异常对象结构比较and转换 { "@type":"java.lang.Runti ...

  6. js中对象使用

    简单记录javascript中对象的使用 一.创建对象 //创建一个空对象 var o={}; //创建一个含有两个属性的对象,x.y var o2={x:12,y:'12',name:'JS'}; ...

  7. JavaScript学习06 JS事件对象

    JavaScript学习06 JS事件对象 事件对象:当事件发生时,浏览器自动建立该对象,并包含该事件的类型.鼠标坐标等. 事件对象的属性:格式:event.属性. 一些说明: event代表事件的状 ...

  8. [转]JS中对象与字符串的互相转换

    原文地址:http://www.cnblogs.com/luminji/p/3617160.html 在使用 JSON2.JS 文件的 JSON.parse(data) 方法时候,碰到了问题: thr ...

  9. JS中对象与字符串的互相转换

    在使用 JSON2.JS 文件的 JSON.parse(data) 方法时候,碰到了问题: throw new SyntaxError('JSON.parse'); 查询资料,大概意思如下: JSON ...

随机推荐

  1. loj 1026( tarjan + 输出割边 )

    题目链接:http://lightoj.com/volume_showproblem.php?problem=1026 思路:Tarjan 算法简单应用.割边的特点:low[v]>dfn[u]( ...

  2. HttpSession--会话

  3. C#环境下,文本框翻屏,怎么一直显示当前插入的内容!!!!!!!!!!!!!!!!

    //-----------------------显示当前插入的位置------------------------ textBox3.SelectionStart = textBox3.Text.L ...

  4. OUYA游戏开发核心技术剖析大学霸内部资料

    OUYA游戏开发核心技术剖析大学霸内部资料 试读地址:http://pan.baidu.com/s/1ntuql8t 介绍:本教程是一本进阶级的教材,它可以让读者在了解.熟悉了OUYA设备的基础上,开 ...

  5. Codeforces Round #330 (Div. 2)

    C题题目出错了,unrating,2题就能有很好的名次,只能呵呵了. 水 A - Vitaly and Night /***************************************** ...

  6. BZOJ3799 : 字符串重组

    从大到小枚举答案与T串的lcp,然后贪心 #include<cstdio> #include<cstring> char s[5010],t[5010],ans[5010]; ...

  7. storm源码之理解Storm中Worker、Executor、Task关系 + 并发度详解

    本文导读: 1 Worker.Executor.task详解 2 配置拓扑的并发度 3 拓扑示例 4 动态配置拓扑并发度 Worker.Executor.Task详解: Storm在集群上运行一个To ...

  8. wp 处理方法

    -DeepZoom:源于遥感影像的金字塔显示方式,提供了与高分辨率图像进行交互的能力,可以快速缩放图像而不影响应用的性能,加载或平移图像时可以光滑过度 -应用:高分辨率.极大图像的浏览,3D合成图像, ...

  9. MySql Replication配置

    一.前言 Mysql Replication作为读写分离的廉价解决方案,支持一主多备的方式进行数据存储,采用二进制日志传送,目前存在着广泛应用,网上相关概念也比较多,不再重复介绍.引用一张官方提供的R ...

  10. linux rootfs制作

    http://blog.sina.com.cn/s/blog_6795385f01011ifg.html 作一个嵌入式Linux rootfs,并且实现 web 服务 1. 文件系统简介 •理论上说一 ...