javascript——面向对象程序设计(2)
<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)的更多相关文章
- JavaScript 面向对象程序设计(下)——继承与多态 【转】
JavaScript 面向对象程序设计(下)--继承与多态 前面我们讨论了如何在 JavaScript 语言中实现对私有实例成员.公有实例成员.私有静态成员.公有静态成员和静态类的封装.这次我们来讨论 ...
- JavaScript面向对象程序设计:数组
或许你会奇怪,面向对象的程序设计为什么从数组开始讲起?这是因为……其间的种种关系吧……嘿嘿,这里先卖个关子,先来看看我们熟悉的数组在JavaScript里面是什么样子的. 1. 创建数组 在J ...
- javascript面向对象程序设计系列(一)---创建对象
javascript是一种基于对象的语言,但它没有类的概念,所以又和实际面向对象的语言有区别,面向对象是javascript中的难点之一.现在就我所理解的总结一下,便于以后复习: 一.创建对象 1.创 ...
- [TimLinux] JavaScript 面向对象程序设计
1. 面向对象 面向对象语言有一个标志:都有类的概念.通过类可以创建任意多个具有相同属性和方法的对象.ECMAScript中没有类的概念,因此JavaScript中的对象夜雨基于类的语言中的面向对象有 ...
- javascript——面向对象程序设计(4)
<script type="text/javascript"> //1.继承 //2.原型链 //3.借用构造函数 //4.组合继承 //5.原型式继承 //6.寄生式 ...
- javascript——面向对象程序设计(3)
<script type="text/javascript"> //1.结合使用构造函数模式和原型模式 //2.动态原型模式 //3.寄生构造函数模式 //4.稳妥构造 ...
- javascript——面向对象程序设计(1)
<script type="text/javascript"> //ECMA-262把对象定义为:“无序属性的 集合,其属性可以包含基本值.对象或者函数” //理解对象 ...
- javascript面向对象程序设计
在学习js面向对象编程之前,首先须要知道什么是面向对象.面向对象语言都有类的概念,通过它能够创建具有同样属性和方法的对象.但js并没有类的概念,因此js中的对象和其它语言的对象有所不同. js对象能够 ...
- javascript 面向对象程序设计--深刻理解对象
javascript中,每个对象都是基于一个引用类型创建的,我们可以把ECMAScript 的对象想象成散列表:无非就是一组名值对,其中值可以是数据或函数. 深刻理解对象 创建自定义对象的最简单方式就 ...
随机推荐
- vs未找到导入的项目,请确认 <Import> 声明中的路径正确
当使用vs出现下列情况: D:\xxxx\Web\Web.csproj : error : 无法读取项目文件“Web.csproj”. D:\xxxx\WebServiceManager\Web\W ...
- [LeetCode] Longest Valid Parentheses 解题思路
Given a string containing just the characters '(' and ')', find the length of the longest valid (wel ...
- hdu 4278 Faulty Odometer
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4278 #include<cstdio> #include<cstring> # ...
- 佛山Uber优步司机奖励政策(1月25日~1月31日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- .net对js和css、img剥离项目进行压缩优化、cdn加速
由于网站首页以及经常用的页面初始化慢,想后面想了对image.js和css进行迁移优化. 1.把他放到独立的域名上面,这个就要对image,js和css从原项目上面脱离,以及把原来很多页面引用的地址修 ...
- 【OpenCV入门教程之一】 安装OpenCV:OpenCV 3.0、OpenCV 2.4.8、OpenCV 2.4.9 +VS 开发环境配置
本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/19809337 作者:毛星云(浅墨 ...
- JAVA学习.java.sql.date 与java.util.date以及gettime()方法的分析
java.sql.Date 是针对SQL语句使用的,它只包含日期而没有时间部分. java.util.Date 就是在除了SQL语句的情况下面使用. 它都有getTime方法返回毫秒数,返回的是自19 ...
- 如何解决 SogouIinput not enough space for thread data ?? 虚拟内存
问题:总是提示没有足够的空间读写数据 上图: 原因: 可能是虚拟内存设置了过大了[我不知道明白是不是也是这样,我出现这个问题就是因为我把虚拟内存设置成了4G,我的物理内存是2G的] 具体问题具体分析, ...
- nginx代理人server结合tomcat采用
相信非常多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那到底它有什么作用呢?可能非常多人未必了解. 说到反向代理,可能非常多人都听说,但详细什么是反向代理,非常多人预计就 ...
- android 06 LinearLayout
xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:la ...