<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. LINUX系统中动态链接库的创建与使用{补充}

    大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一部 ...

  2. [IoLanguage]Io Programming Guide[转]

    Io Programming Guide     Introduction Perspective Getting Started Downloading Installing Binaries Ru ...

  3. Android客户端调用Asp.net的WebService

    Android客户端调用Asp.net的WebService 我来说两句 |2011-11-23 13:39:15 在Android端为了与服务器端进行通信有几种方法:1.Socket通信2.WCF通 ...

  4. [cocos2dx 3.0 + iap]中文文档(转)

    一.In App Purchase概览Store Kit代表App和App Store之间进行通信.程序将从App Store接收那些你想要提供的产品的信息,并将它们显示出来供用户购买.当用户需要购买 ...

  5. linux-kernel/CodingStyle

    https://www.kernel.org/doc/Documentation/zh_CN/CodingStyle Chinese translated version of Documentati ...

  6. Little shop of flowers - SGU 104 (DP)

    题目大意:把 M 朵花插入 N 个花瓶中,每个花插入不同的花瓶都有一个价值A[Mi][Nj],要使所有的花都插入花瓶,求出来最大的总价值(花瓶为空时价值是0). 分析:dp[i][j]表示前i朵花插入 ...

  7. C#三种判断数据库中取出的字段值是否为空(NULL) 的方法

    操作数据库,需要判断返回的字段值是否为空,收集了3种方法供参考 1 通过System.DBNull判断,网上大部分都使用这个方法. DataTable dt;                     ...

  8. Jquery案例——某网站品牌列表的效果

    一下是效果图.点击"显示全部品牌",高亮推荐品牌,并显示全部品牌. HTML文件: <!DOCTYPE html> <html lang="en&quo ...

  9. C#中5中timer的比较

    C#中有5个timer,它们的主要区别如下: System.Threading.Timer  在线程池启动一个后台任务.我前段时间写过一个关于timer的垃圾回收的需要注意一下,参见谁动了我的time ...

  10. [转]PHP100视频教程(2012-2013版)下载地址及密码

    [转] PHP100视频教程(2012-2013版)  下载地址及其密码 先记起来,不用再到处找密码了. NO 名称 下载地址 密码 1 [第01讲]开启PHP学习之路,融入新互联网时代 http:/ ...