以下通过一段示例代码,说明原型模型中的基本概念以及知识点。

<!DOCTYPE html>
<html>
<head>
<title>原型模型</title>
<script type="text/javascript">
function Person(){}; // Person.prototype.name="Lucy";
// Person.prototype.age=15;
// Person.prototype.sayName=function(){
// alert(this.name);
// }; //3.更简单的原型语法
Person.prototype={
constructor:Person,//若constructor属性值真的很重要,则需要手动设置回适当的值。
name:"Lucy",
age:15,
sayName:function(){
alert(this.name);
}
}; // var p1,p2;
p1=new Person();
p2=new Person();
//hasOwnProperty()检测一个属性存在于实例中(true),还是存在于原型中(false)
alert(p1.hasOwnProperty("name"));//false
p1.name="Bob";
p1.job="student";//设置实例属性
alert(p1.name);//"Bob",来自实例
alert(p1.hasOwnProperty("name"));//true alert(p1.sayName==p2.sayName);//true 检查实例是否共享方法
alert(p1.job);
alert(p1.hasOwnProperty("age"));//false
alert(p1.hasOwnProperty("job"));//true // /*********************************** 2.原型与in操作符 *********************************************/ // /********单独使用in操作符********/
// 通过对象能够访访问到属性时,返回true
alert("job" in p1);//true
alert("age" in p1);//true
alert("name" in p1);//true
alert("name" in p2);//true //该函数确定属性是存在于原型对象中还是存在于实例对象中。 true:属性为原型对象属性;false:为实例对象属性。
function hasPrototypeProperty(object,name){
return !object.hasOwnProperty(name)&&(name in object);
}
alert(hasPrototypeProperty(p1,"job"));
alert(hasPrototypeProperty(p2,"name"));
// /******************************/ // /********for-in ***********/
// 返回的是所有能够通过对象访问的、可枚举的属性,其中包括存在于原型中的属性、也包括存在于实例中的属性。
// Object.keys(object):接收一个对象作为参数,返回一个包含所有可枚举属性的字符串数组。
var keys=Object.keys(Person.prototype);
alert(keys);//"name,age,sayName"
var p1keys=Object.keys(p1);
alert(p1keys);//"name,job" //顺序即为for-in访问时的顺序
for(var prop in p1keys){
alert(p1keys[prop]);
} //Object.getOwnPropertyNames(object) 获取实例所有属性,包括不可枚举属性
var p1allkeys=Object.getOwnPropertyNames(p1);
alert(p1allkeys);//"name,job"
var p1allkeys=Object.getOwnPropertyNames(Person.prototype);
alert(p1allkeys);//constructor,name,age,job,sayName constructor属性为不可枚举
// /******************************/
// /*****************************************************************************************/ /************************************ 3.更简单的原型语法 ****************************************/
//设置为简单的原型语法后,Person.prototype设置为一个以对象字面量形式创建的新对象。最终结果相同,不过对象的constructor属性不再指向Person。
//若constructor属性值真的很重要,则需要手动设置回适当的值。
var friend=new Person();
alert(friend instanceof Object);//true
alert(friend instanceof Person);//true
alert(friend.constructor==Person);//false
alert(friend.constructor==Object);//true var keys2=Object.keys(Person.prototype);
alert(keys2);//constructor,name,age,job,sayName //简单原型语法中手动设置constructor属性之后,会导致它的[Enumerable]特性值为true,默认情况下原生的constructor值为false
//重设构造函数,只适用于ECMAScript5兼容浏览器
Object.defineProperty(Person.prototype,"constructor",{
enumerable:false,
value:Person
});
var keys3=Object.keys(Person.prototype);
alert(keys3);//name,age,job,sayName //
/**********************************************************************************************/ /************************************ 4.原型的动态性 ****************************************/
var per=new Person();
//可以随时为原型添加属性和方法,并且所有的修改能够立即在所有对象实例中反映出来。
Person.prototype.sayHi=function(){
alert("Hi!");
}
per.sayHi(); //若重构整个原型对象,就会在调用构造函数时为实例添加一个指向最初原型的[Prototype]指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。
//实例中的指针仅指向原型,而不是构造函数。
function Student(){};
var st=new Student();//先创建实例对象
Student.prototype={//重构原型对象原型
constructor:Student,
name:"Nike",
age:20,
speakEnglish:function(){
alert("Hello!");
}
};
st.speakEnglish();//error 0: Object doesn't support property or method 'speakEnglish'
// /**********************************************************************************************/ /************************************ 5.原型的问题 ****************************************/
//原型中所有属性是被很多实例共享的,这种共享对于函数非常适合。对于包含基本值得属性也没有什么,通过在实例上添加一个同名属性就可以隐藏原型中对应的属性。
//然而,对于包含引用类型的值来说,就会存在问题。如下例所示。
function Singer(){};
Singer.prototype={
constructor:Singer,
name:"Nike",
age:30,
albums:["Suger","Live"]//"Suger","Live"是所有实例对象的共享albums集合
};
var s1=new Singer();
var s2=new Singer();
s1.albums.push("Flowers");//“Flowers”是s1的唱片集
alert(s1.albums);//"Suger","Live","Flowers"
alert(s2.albums);//"Suger","Live","Flowers",而"Flowers"不是s2的唱片
alert(s1.albums===s2.albums);//指向同一个albums
/**********************************************************************************************/
</script>
</head>
<body> </body>
</html>

部分摘自《JavaScript高级程序设计(第3版)》

JS面向对象——原型模型的更多相关文章

  1. js面向对象-原型链

    var Person = function (name) { this.name = name; } Person.prototype.say = function () { console.log( ...

  2. Js面向对象原型~构造函数

    脑袋一团浆糊,但希望写点啥,所有就有了这篇博文了,抱歉哦....开始吧!!!!  什么是构造函数??   所谓"构造函数",其实就是一个普通函数,但是内部使用了this变量.对构造 ...

  3. JS面向对象——工厂模型

    工厂模型抽象了创建具体对象的过程,以下示例代码说明工厂类型: <!DOCTYPE html> <html> <head> <title>工厂模型< ...

  4. JS面向对象——动态原型模型、寄生构造模型

    动态原型模型 组合使用构造函数模型和原型模型,使得OO语言程序员在看到独立的构造函数和原型时很困惑.动态原型模型致力于解决该问题,它把所有的信息封装在构造函数中,通过在构造函数中初始化原型(仅在必要情 ...

  5. JS面向对象——组合使用构造函数模型与原型模型

    该模型为创建自定义类型最常用的方式. <!DOCTYPE html> <html> <head> <title>组合使用构造函数模型和原型模型</ ...

  6. JS面向对象——组合使用构造函数模型与原型模型中的隐患

    组合使用构造函数模型和原型模型中的问题,使用对象字面量重写原型模型会有隐患(涉及到原型的动态性),如下例: <!DOCTYPE html> <html> <head> ...

  7. JS面向对象(2) -- this的使用,对象之间的赋值,for...in语句,delete使用,成员方法,json对象的使用,prototype的使用,原型继承与原型链

    相关链接: JS面向对象(1) -- 简介,入门,系统常用类,自定义类,constructor,typeof,instanceof,对象在内存中的表现形式 JS面向对象(2) -- this的使用,对 ...

  8. 【JavaScript】 JS面向对象的模式与实践 (重点整治原型这个熊孩子 (/= _ =)/~┴┴ )

    参考书籍 <JavaScript高级语言程序设计>—— Nicholas C.Zakas <你不知道的JavaScript>  —— KYLE SIMPSON   在JS的面向 ...

  9. js面向对象、创建对象的工厂模式、构造函数模式、原型链模式

    JS面向对象编程(转载) 什么是面向对象编程(OOP)?用对象的思想去写代码,就是面向对象编程. 面向对象编程的特点 抽象:抓住核心问题 封装:只能通过对象来访问方法 继承:从已有对象上继承出新的对象 ...

随机推荐

  1. Nginx+lua_Nginx+GraphicsMagick来实现实时缩略图

    1.安装GraphicsMagick cd /usr/local/src wget http://sourceforge.net/projects/graphicsmagick/files/graph ...

  2. Graph Neural Networks for Computer Vision

    Graph Neural Networks for Computer Vision I was attracted by this image: This is an inspiring image ...

  3. 使用getchar和putchar输入输出单个字符

    getchar()和putchar()只能用于输入输出单个字符,而不能字符串. #include<iostream> using namespace std; int main(){ ch ...

  4. python内建模块——collections模块

    在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdict.namedtuple和Ord ...

  5. BUUCTF |[0CTF 2016]piapiapia

    步骤: nickname[]=wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere ...

  6. 学习日记4、datagrid多行删除

    1.前台展现单选框datagrid代码 $('#List').datagrid({ url: '@Url.Action("GetList")', width: $(window). ...

  7. NOIp 基础数论知识点总结

    推荐阅读 NOIp 数学知识点总结: https://www.cnblogs.com/greyqz/p/maths.html Basic 常用素数表:https://www.cnblogs.com/g ...

  8. [CSP-S模拟测试]:旋转子段(数学)

    题目描述 $ZYL$有$N$张牌编号分别为$1,2,...,N$.他把这$N$张牌打乱排成一排,然后他要做一次旋转使得旋转后固定点尽可能多.如果第$i$个位置的牌的编号为$i$,我们就称之为固定点.旋 ...

  9. Log4j appender、layout

    appender输出类型配置 layout日志信息格式 Threshold属性指定输出等级 Append属性指定是否追加内容 (1)appender输出类型配置 Log4j官方的appender给出了 ...

  10. 安装依赖的时候,报错npm WARN checkPermissions

    解决办法1 . 删除node_modules文件夹,重新安装依赖. 解决办法2 . 统一使用同一个npm安装依赖 . 原因:有的依赖包是用npm安装的,有的依赖包是用cnpm安装的.