<script type="text/javascript">
//1、理解原型对象
//2、原型与in操作符
//3、更简单的原型语法
//4、原型的动态性
//5、原生对象原型
//6、原型对象的问题 //1、无论什么时候,只要创建了一个函数,就会根据一组特定的规则,为该函数创建一个prototype属性,该属性指向函数的原型对象
//在默认情况下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针
//如
function Person(){ }
//Person.prototype.constructor 指向Person
//创建了自定义的构造函数之后,其原型对象默认只会取得constructor属性,至于其他方法则都是从Object继承而来
//当调用函数的创建一个新实例之后,该实例的内部包含一个指针(内部属性)指向构造函数的原型对象
//在Firefox、safari、chrome在每个对象上都支持一个属性_proto_访问
var p1=new Person();
alert(Person.prototype.isPrototypeOf(p1)) alert(Object.getPrototypeOf(p1)==Person.prototype) //虽然可以通过对象实例访问保存在原型中的值,但却不能通过对象实例重写原型中的值。如果我们在实例中添加了一个属性
//而该属性的名称与原型的中的实例同名,那我们就在实例中创建该属性,该属性将会屏蔽原型中的那个属性。eg:
function Person() {
}
Person.prototype.name="amber";
Person.prototype.age=23;
Person.prototype.job="software engineer";
Person.prototype.sayName=function(){
alert(this.name)
} var person1=new Person();
var person2=new Person();
person1.name="amber.Xu";
alert(person1.name);//amber.xu --来自实例
alert(person2.name);//amber --来自原型 delete person1.name;
alert(person1.name);//amber --来自原型 //使用hasOwnProperty()方法可以检测一个属性是存在于实例中还是存在于原型中,这个方法(从Object继承而来)
//只在给定属性存在于对象实例中时,才会返回true
function Person() {
}
Person.prototype.name="amber";
Person.prototype.age=23;
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 来自实例 alert(person2.hasOwnProperty("name"));//false 来自实例 person1.name="amber.xu";
alert(person1.name);
alert(person1.hasOwnProperty("name"));//true 来自实例 delete person1.name;
alert(person1.name);
alert(person1.hasOwnProperty("name"));//false 来自原型 //2、原型与in操作符
//in 有两种使用方式,一个是的单独使用和在for-in 中使用。在单独使用时,in操作符会在对象能够访问给定属性时返回true
//无论该属性时来自原型还是实例
function Person() {
}
Person.prototype.name="amber";
Person.prototype.age=23;
Person.prototype.job="software engineer";
Person.prototype.sayName=function(){
alert(this.name)
}
var person1=new Person();
var person2=new Person();
alert("name" in person1);//true 来自原型
alert("name" in person2);//true 来自原型
alert("height" in person1);//false //这样就可以封装一个函数(给定属性是否是来给定对象的原型)
function hasPrototypeProperty(object,name){
return !object.hasOwnProperty(name) && (name in object);
}
alert("----------------------------------");
alert(hasPrototypeProperty(person1,"name"));//true person1.name="张三";
alert(hasPrototypeProperty(person1,"name"));//false //使用for-in 返回的是所有能够通过对象访问、可枚举的属性,其中既包含原型属性也包含实例属性。
//屏蔽了原型中不可枚举属性(将Enumerable标记为false的属性)的实例属性也会在for-in中返回
//ie早期版本总中有一个bug:屏蔽了原型中不可枚举属性的实例属性也不会在for-in中返回
//eg:
var o={
toString:function(){
return "my object";
}
}; for(var prop in o){
if(prop=="toString"){
alert("找到了");//在ie早期版本中不会显示
}
} //要取得对象上所有可枚举的属性,可以使用ECMAScript5的Object.keys()方法。接受一个对象作为参数,
//包含所有可枚举属性的字符串数组
function Person() {
}
Person.prototype.name="amber";
Person.prototype.age=23;
Person.prototype.job="software engineer";
Person.prototype.sayName=function(){
alert(this.name)
}
var person1=new Person();
var person2=new Person();
var keys=Object.keys(Person.prototype);
alert(keys) person1.name="amber.Xu";
person1.age=23;
var keys=Object.keys(person1);
alert(keys) alert("-----------------------------------------")
//如果想要得到所有的实例属性不管他是否可以枚举,都可以使用
alert(Object.getOwnPropertyNames(person1));
alert(Object.getOwnPropertyNames(Person.prototype)); alert("更简单的原型语法-----------------------------------------")
//3、更简单的原型语法
function Person() { } Person.prototype={
name:"AMBER",
age:23,
job:"software",
sayName:function(){
alert(this.name)
}
} //这样写之后constructor属性不再指向Person函数,而是指向Object构造函数。
//尽管通过instanceof操作符还能返回正确的结果,但是通过constructor已经无法确定对象的类型了,eg:
var friend=new Person();
alert(friend instanceof Person)//true
alert(friend instanceof Object)//true
alert(friend.constructor==Person);//false
alert(friend.constructor==Object);//true
//如果constructor对你真的很重要,可以向下面一样设置成适当的值 function Person() { } Person.prototype={
constructor:Person,
name:"AMBER",
age:23,
job:"software",
sayName:function(){
alert(this.name)
}
}
var friend=new Person();
alert("手动设置constructor-----------------------------------------")
alert(friend.constructor==Person);//true //这种手动的添加了constructor会使constructor变成可枚举的元(原生的constructor属性时不可枚举的)。
//这种情况下就可以使用
Object.defineProperty(Person.prototype,"constructor",{
enumerable:false,
value:Person
}); //原型的动态性
var friend=new Person();
Person.prototype.sayHi=function(){
alert("Hi");
} friend.sayHi();//Hi (正常执行)
//因为实例和原型之间是松散的连接关系,实例与原型之间的连接只不过是一个指针,而非副本
//当我们调用sayHi()方法时,首先会在实例中搜索名为sayHi的方法,在没找到的情况下会搜索原型。 //但是,如果是重写整个原型对象,那么情况就不一样了。
//我们知道,调用构造函数时会为实例添加一个指向最初原型的Prototype指针,而把原型修改为另一个对象就等于切断了构造函数与最初原型之间的联系。
//请记住:实例中的指针仅指向原型,而不指向构造函数。eg:
function A(){}
var a1=new A();
A.prototype={
constructor:A,
name:"AMBER",
age:23,
job:"software",
sayName:function(){
alert(this.name)
}
}
alert("ERROR-------------------------------------");
alert(a1.sayName());
//我们创建了一个A的实例,然后又重写了其原型对象,然后在调用a1.sayName()发生了错误,因为a指向的原型中不包含以该名字命名的属性/方法 //原生对象的原型
//原型模式的重要性不仅体现在创建自定义类型方面。就连所有的原生的引用类型,都是采用这种模式创建的。所有的原生引用类型
//都在其构造函数的原型上定义的方法 eg:
alert(typeof Array.prototype.sort);//function
alert(typeof String.prototype.substring);//function
//不仅可以在原生对象的原型取得虽有默认方法的引用,而且可以定义新的方法
//为String类型添加一个startsWith()的方法
String.prototype.startsWith=function(text){
return this.indexOf(text) == 0;
};
var msg="Hello";
alert(msg.startsWith("H")); //我们并不建议这样做。 alert("原型对象的问题");
//6、原型对象的问题 实例
function Ques() {
} Ques.prototype={
constructor:Ques,
name:"amber",
age:23,
job:"IT",
friends:["张三","李四"],//引用类型
sayName:function(){
alert(this.name)
}
}; var q1=new Ques();
var q2=new Ques();
q1.friends.push("王五");
alert(q1.friends);//
alert(q2.friends);//
alert(q1.friends===q2.friends);
//相信大家已经看到了问题,当我创建了两个实例q1、q2,当我为q1的“朋友”添加了“王五”之后,q2的”朋友“也有了三个张三、李四、王五
//那是因为数组存在于Ques.prototype上,而非q1上。所以出现了如上结果。 //而正是这个问题,我们很少看到有人单独使用原型模式的原因所在。
</script>

javascript——面向对象程序设计(2)的更多相关文章

  1. JavaScript 面向对象程序设计(下)——继承与多态 【转】

    JavaScript 面向对象程序设计(下)--继承与多态 前面我们讨论了如何在 JavaScript 语言中实现对私有实例成员.公有实例成员.私有静态成员.公有静态成员和静态类的封装.这次我们来讨论 ...

  2. JavaScript面向对象程序设计:数组

    或许你会奇怪,面向对象的程序设计为什么从数组开始讲起?这是因为……其间的种种关系吧……嘿嘿,这里先卖个关子,先来看看我们熟悉的数组在JavaScript里面是什么样子的.   1. 创建数组   在J ...

  3. javascript面向对象程序设计系列(一)---创建对象

    javascript是一种基于对象的语言,但它没有类的概念,所以又和实际面向对象的语言有区别,面向对象是javascript中的难点之一.现在就我所理解的总结一下,便于以后复习: 一.创建对象 1.创 ...

  4. [TimLinux] JavaScript 面向对象程序设计

    1. 面向对象 面向对象语言有一个标志:都有类的概念.通过类可以创建任意多个具有相同属性和方法的对象.ECMAScript中没有类的概念,因此JavaScript中的对象夜雨基于类的语言中的面向对象有 ...

  5. javascript——面向对象程序设计(4)

    <script type="text/javascript"> //1.继承 //2.原型链 //3.借用构造函数 //4.组合继承 //5.原型式继承 //6.寄生式 ...

  6. javascript——面向对象程序设计(3)

    <script type="text/javascript"> //1.结合使用构造函数模式和原型模式 //2.动态原型模式 //3.寄生构造函数模式 //4.稳妥构造 ...

  7. javascript——面向对象程序设计(1)

    <script type="text/javascript"> //ECMA-262把对象定义为:“无序属性的 集合,其属性可以包含基本值.对象或者函数” //理解对象 ...

  8. javascript面向对象程序设计

    在学习js面向对象编程之前,首先须要知道什么是面向对象.面向对象语言都有类的概念,通过它能够创建具有同样属性和方法的对象.但js并没有类的概念,因此js中的对象和其它语言的对象有所不同. js对象能够 ...

  9. javascript 面向对象程序设计--深刻理解对象

    javascript中,每个对象都是基于一个引用类型创建的,我们可以把ECMAScript 的对象想象成散列表:无非就是一组名值对,其中值可以是数据或函数. 深刻理解对象 创建自定义对象的最简单方式就 ...

随机推荐

  1. javascipt取整数四舍五入

    1.丢弃小数部分,保留整数部分 parseInt(5/2) 2.向上取整,有小数就整数部分加1 Math.ceil(5/2) 3,四舍五入. Math.round(5/2) 4,向下取整 Math.f ...

  2. Linux学习笔记24——进程管道

    一 管道的作用 通常把一个进程的输出通过管道连接到另一个进程的输入. 二 popen和pclose函数 #include <stdio.h> FILE *popen(const char ...

  3. java 对list进行排序

    前提: list中的元素是自定义对象,如何根据对象的元素进行排序呢? 比如List<Student>students 是一个list,每个元素都是Student对象,Student对象中有 ...

  4. HDOJ/HDU 2555 人人都能参加第30届校田径运动会了(判断加排序~)

    Problem Description 杭州师范大学第29届田径运动会圆满的闭幕了,本届运动会是我校规模最大,参赛人数最多的一次运动会.在两天半时间里,由学生.教工组成的61支代表队共2664名运动员 ...

  5. Live555 Streaming from a live source

    https://www.mail-archive.com/live-devel@lists.live555.com/msg05506.html-----ask--------------------- ...

  6. 转 :hdoj 4857 逃生【反向拓扑】

    逃生 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...

  7. [CF 351B]Jeff and Furik[归并排序求逆序数]

    题意: 两人游戏, J先走. 给出一个1~n的排列, J选择一对相邻数[题意!!~囧], 交换. F接着走, 扔一硬币, 若正面朝上, 随机选择一对降序排列的相邻数, 交换. 若反面朝上, 随机选择一 ...

  8. 【设计模式 - 14】之命令模式(Command)

    1      模式简介 命令模式的定义: 命令模式将命令封装成对象,从而使调用一个命令变为调用一个对象的指定方法. 命令模式的优点: 1)        降低了系统耦合度: 2)        新的命 ...

  9. IOS 多个ImageView图片层叠透明区域点击事件穿透

    经常用到多个透明图片层叠,但又需要获取不同图片的点击事件,本文实现图片透明区域穿透点击事件 实现人体各个部位点击 - (BOOL) pointInside:(CGPoint)point withEve ...

  10. 写一个函数,参数为$n,生成一个数组,其元素为1~$n,各元素位置随机排列,不得重复

    function rand_array($n){ $array=range(1,$n); shuffle($array); return $array; }