1)  构造函数模式

es中的构造函数可以用来创建特定类型的对象,像Object和Array这样的原生构造函数,在运行时会自动出现在执行环境中,此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法,例如:

function Person(name,age,job){

     this.name=name;

     this.age=age;

     this.job=job;

     this.sayName=function(){

      alert(this.name);

}

}

var person1=new Person(“Nicholas”,29,”Software Engineer”);

Var preson2=new Person(“Greg”,27,”Doctor”);

要创建Person的新实例,必须使用new操作符,以这种方式调用构造函数实际上火经历一下4个步骤:

  • l 创建一个新对象;
  • l 将构造函数的作用域赋给新的对象(因此this就指向这个新对象);
  • l 执行构造函数中的代码(为这个新对象添加属性);
  • l 返回新对象.

对象的constructor属性最初是用来标识对象类型的,但是,提到检测对象类型,还是instanceof操作符要更可靠一些,我们在这个例子中创建的所有对象既是Object的实例,同时也是Person的实例,这一点通过instanceof操作符可以得到验证.

alert(person1 instanceof Object);//true

alert(person1 instanceif Person);//true

alert(person2 instanceof Object);//true

alert(person2 instanceof Person);//true

构造函数模式虽然好用,但也并非没有确定,使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍,而sayName()的方法去死不同的Function的实例.

2)  原型模式

我们创建的每一个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所以实例共享的属性和方法.如下面的例子所示:

function Person(){

}

Person.prototype.name=”Nicholas”;

Person.prototype.age=29;

Person.prototype.job=”Software Engineer”;

Person.prototype.sayName=function(){

 alert(this.name);

};

var person1=new Person();

person1.sayName();”//Nicholas”

var person2=new Person();

person1.sayName();//”Nicholas”

Alert(person1.sayName==person2.sayName)://true
  • l 理解原型对象

无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象,在默认情况下,所有原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针,就上面例子来说,Preson.prototype.constructor指向Person,而通过这个构造函数,我们还可以继续为原型对象添加其他属性和方法.

创建了自定义的构造函数之后,其原型对象默认只会取得constructor属性,至于其他方法,则都是从Object继承而来的,当调用构造函数创建一个新实例后,该实例内部将包含一个指针(内部属性),指向构造函数的原型对象,ECMA-262第5版中管这个指针叫[[prototype]],虽然在脚本中没有标准的方式访问[[prototype]],但ff,safari和chrome在每个对象上都支持一个属性_proto_;而在其他实现中,这个属性对脚本则是完全不可见的。

虽然在所以实现中都无法范围到[[prototype]],但可以通过isPrototypeOf()方法来确定对象之间是否存在这种关系,从本质上讲,如果[[prototype]]指向调用isPrototypeOf()方法的对象(Person.prototype),那么这个方法就返回true,如下:

alert(Person.prototype.isPrototypeOf(person1));//true

alert(Person.prototype.isPrototypeOf(person2));//true

这里,我们用原型对象的isPrototypeOf()方法测试了person1和person2,因为它们内部都有个指向Person.prototype的指针,因此都返回了true;

es5增加了一个新方法叫 Object.getPrototypeOf(),在所有支持的实现中,这个方法返回[[prototype]]的值,例如:

alert(Object.getPrototypeOf(person1)==Person.prototype);//true

alert(Object.getPrototypeOf(person2).name);//”Nicholas”

每当代码读取某个对象的某个属性时,都会执行一次搜索,目标是具有给定名字的属性,搜索首先从对象实例本身开始,如果在实例中找到了具有给定名字的属性,则返回该属性的值;如果没有找到,则继续搜索指针指向的原型对象,在原型对象中查找具有给定名字的属性,如果在原型对象中找到了这个属性,则返回该属性的值。

使用hasOwnPrototype()方法可以检测一个属性是存在于实例中,还是存在于原型中,这个方法值在给杜属性存在于对象实例中时才返回true,看下面例子:

Function Person(){

}

Person.prototype.name=”Nicholas”;

Person.prototype.age=29;

Person.prototype.job=”Software Engineer”;

Person.prototype.sayName=function(){

 alert(this.name);

}

var person1=new Person();

var person2=new Person();

alert(person1.hasOwnProperty(“name”))//false

person1.name=”Greg”;

alert(person1.name)//”Greg”

alert(person1.hasOwnProperty(“name”))//true

alert(person2.name)//”Nicholas”

alert(person2.hasOwnproperty(“name”));//false

delete  person1.name

alert(person1.name);//”Nicholas”

alert(person1.hasOwnProperty(“name”));//false

IE早期版本的实现中存在一个bug,即屏蔽不可枚举属性的实例属性不会出现在for-in循环中,例如:

var o={

  toString:function(){

   Return “My object”

}

};

for (var prop in o){

If(prop==”toString”){

  alert(“Found toString”);

}

}

当以上代码运行时,应该会显示一个警告框,表明找到了toString()方法,这里的对象o定义了一个名为toString的方法,该方法屏蔽了原型中的toString方法,在IE中,由于其实现认为原型的toString方法被打伤了[[Enumerable]]标记就应该跳过该属性,结果我们不会看到警告框.该bug会影响默认不可枚举的所有属性和方法。

要取得对象上所有可枚举的实例属性,可以使用es5的Object.keys方法,这个方法接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组,例如:

function Person(){

}

Person.prototype.name=”Nicholas”;

Person.prototype.age=29;

Person.prototype.job=”Software Engineer”;

Person.prototype.sayName=function(){

   alert(this.name);

};

var keys=Object.keys(Person.prototype);

alert(keys);//”name,age,job,sayName”

var p1=new Person();

p1.name=”Rob”;

p1.age=31;

var p1keys=Object.keys(p1);

alert(p1keys);//”name,age”

如果你想要得到所有实例属性,无论它是否可枚举,都可以使用Object.getOwnPropertyNames()方法

var keys=Object.getOwnPropertyNames(Person.prototype);

alert(keys);//”constructor,name,age,job,sayName”

javascript高级编程笔记06(面相对象2)的更多相关文章

  1. javascript高级编程笔记01(基本概念)

    1.在html中使用JavaScript 1.  <script> 元素 <script>定义了下列6个属性: async:可选,异步下载外部脚本文件. charset:可选, ...

  2. javascript高级编程笔记05(面向对象)

    面向对象设计 es中有两种属性:数据属性和访问器属性 数据属性: 数据属性包含一个数据值的位置,在这个位置可以读取和写入值,数据属性有4个描述其行为的特性 [[Configurable]]:表示能否通 ...

  3. javascript高级编程笔记02(基本概念)

    ParseInt()函数: 由于Number函数在转换字符串时比较复杂而且不合理,我们常常转换字符串都用parseInt函数, Parseint函数规则: 忽略字符串前面的空格,直到找到第一个非空格字 ...

  4. javascript高级编程笔记04(基本概念)

    Function类型 Es5中规范了另一个函数对象的属性:caller,这个属性中保存着调用当前函数的函数的引用,如果是在全局作用域中调用当前函数,这它的值为null function outer() ...

  5. javascript高级编程笔记03(正则表达式)

    引用类型 检测数组 注:我们实际开发中经常遇到要把数组转化成以逗号隔开,我以前都是join来实现,其实又更简单的方法可以用toString方法,它会自动用逗号隔开转换成字符串,其实toString内部 ...

  6. JavaScript高级编程———基本包装类型String和单体内置对象Math

    JavaScript高级编程———基本包装类型和单体内置对象 <script> var stringObject = new String("hello world") ...

  7. Android高级编程笔记(四)深入探讨Activity(转)

    在应用程序中至少包含一个用来处理应用程序的主UI功能的主界面屏幕.这个主界面一般由多个Fragment组成,并由一组次要Activity支持.要在屏幕之间切换,就必须要启动一个新的Activity.一 ...

  8. JavaScript高级编程———JSON

    JavaScript高级编程———JSON < script > /*JSON的语法可以表达一下三种类型的值 简单值:使用与javas相同的语法,可以在JSON中表达字符串.数值.布尔值和 ...

  9. JavaScript高级编程——Date类型

    JavaScript高级编程——Date类型 <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" ...

随机推荐

  1. [改善Java代码]频繁插入和删除时使用LinkedList

    一.分析 前面有文章分析了列表的表里方式,也就是“读”的操作.本文将介绍表的“写”操作:即插入.删除.修改动作. 二.场景 1.插入元素 列表中我们使用最多的是ArrayList,下面看看他的插入(a ...

  2. Jquery 全选、反选问题解析

    最近工作中,需要使用Jquery实现复选框的全选和反选,本人虽然不是专职撸前端的,但这个小问题感觉也没什么难度,下面直接上代码: <div id="list"> < ...

  3. 在jQuery环境下制作轻巧遮罩层

    遮罩层的好处就是可以屏蔽用户对遮罩层下方元素的操作. 制作原理很简单:1设置遮罩层触发按钮 2设置遮罩层内容 3设置遮罩层背景(重点是捕获内容div的大小位置)4设置点击触发按钮遮罩层背景内容同时显示 ...

  4. ios Swift ! and ?

    swift ?和!之间区别: Swift 引入的最不一样的可能就是 Optional Value 了.在声明时,我们可以通过在类型后面加一个? 来将变量声明为 Optional 的.如果不是 Opti ...

  5. Contoso 大学 - 3 - 排序、过滤及分页

    原文 Contoso 大学 - 3 - 排序.过滤及分页 目录 Contoso 大学 - 使用 EF Code First 创建 MVC 应用 原文地址:http://www.asp.net/mvc/ ...

  6. NSUserDefaults存储自定义对象

    场景是这样的: 现在有一个数组如下,数组中存放着自定义的对象GoodscCategory <__NSArrayM 0x7ffb9c2032b0>( <GoodscCategory: ...

  7. Error LNK2001 无法解析的外部符号 的几种情况及解决办法

    最近遇到的关于VS里编译出现的“无法解析的外部符号”问题,在网上寻求解决办=办法时查到下面的博客内容,作者讲解的挺全面的,作为收藏以备将来查询. 原文http://blog.csdn.net/shen ...

  8. dsu + lca

    贴一下使用dsu和lca的代码,dsu的代码很简单,可以马上写出来,但是lca的代码就不熟练了.这里lca的计算还是用了dfs的访问时间标记,我想起来割边, 割点的判断, dfu[u], low[u] ...

  9. Using OpenCV Java with Eclipse

    转自:http://docs.opencv.org/trunk/doc/tutorials/introduction/java_eclipse/java_eclipse.html Using Open ...

  10. [CSS]三角形

    CSS盒子模型 当我们把padding和width,height全部设置为0,border设为一个较大的像素时 即:我们需要什么方向的三角形,只需把其余的三角形背景色设置为transparent: