原型模式和基于原型继承的js对象系统
像同样基于原型编程的Io语言一样,javascript在原型继承方面,实现原理和Io非常类似,javascript也遵守这些原则
所有数据都是对象
要得到一个对象,不是通过实例化类,而是找到一个对象作为原型并克隆它
对象会记住它的原型
如果对象无法响应某个请求,它会把这个请求委托给它自己的原型.
一 , 所有数据都是对象
javascript模仿了java引入两套类型机制:基本型和对象类型.
基本型有:undefined,number,string,Boolean,function,object.
javascript中的根对象是object.prototype,它是一个空的对象.javascript中的每个对象都是克隆自它.object.prototype是他们的原型
var obj1 = new Object();
var obj2 = {};
console.log( Object.getPrototypeOf( obj1 ) === Object.prototype ); // 输出:true
console.log( Object.getPrototypeOf( obj2 ) === Object.prototype ); // 输出:true
二 , 要得到一个对象,不是通过实例化,而是找到一个对象作为原型并克隆它.
运用new运算符从构造器中得到一个对象,比如:
function Person(name){
this.name = name;
}
person.prototype.getName = function (){
return this.name;
}
var a = new Person('cat');
console.log(a.name);//cat
console.log(a.getName() );//cat
console.log(object.getPrototypeOf(a) === Person.prototype);//true
Person并不是类,而是构造器.js的函数可以作为普通函数被调用,也可以作为构造器被调用.当使用new运算符来调用函数时,此时函数就是一个构造器.
在Chrome和Firefox等向外暴露了对象_proto_属性的浏览器下,我们可以通过以下代码来理解new运算的过程
function Person(name){
this.name = name;
}
person.prototype.getName = function (){
return this.name;
}
var objectFactory = function(){
var obj = new Object(), //从Object.prototype上克隆一个空对象
Constructor = [].shift.call(arguments);//取得外部传入的构造器,此例是Person
obj._proto_ = Constructor.prototype; //指向正确的原型
var ret = Constructor.apply( obj, arguments );// 借用外部传入的构造器给 obj 设置属性
return typeof ret === 'object' ? ret : obj;// 确保构造器总是会返回一个对象
};
var a = objectFactory( Person, 'sven' );
console.log( a.name ); // 输出:sven
console.log( a.getName() ); // 输出:sven
console.log( Object.getPrototypeOf( a ) === Person.prototype );// 输出:true
三 , 对象会记住它的原型
对js来说,不能说对象有原型,只能说对象的构造器有原型."对象把请求委托给它自己的原型"这句话,更好的说法是对象把请求委托给它的构造器的原型.
js给对象提供了_proto_的隐藏属性,这个属性指向它的构造器的原型对象,即{constructor}.prototype.
var a = new Object();
console.log(a._proto_ === object.prototype);//true
实际上,_proto_就是对象与"对象构造器的原型"联系起来的纽带.
obj._proto_ = Constructor.prototype;
//通过这种方式来改变默认指向的object.prototype
四 , 如果对象无法响应某个请求,它会把这个请求委托给它的构造器原型
js中对象最初都是由Object.prototype对象克隆而来,但是构造器的原型不仅限于object.prototype,而是可以动态指向其他对象的.利用这一特性,
当对象a需要借用b的能力时,可以让a的构造器原型指向对象b,从而达到继承效果.
第一个例子:
var obj = {name:'nike'};
var A = function(){};
A.prototype = obj;
var a = new A();
console.log(a.name);//nike
这段代码运行的时候,引擎是这样工作的:
- 首先,尝试遍历对象
a中所有的属性,但是没有找到name这个属性. - 查找
name属性的这个请求被委托给了对象a的构造器的原型,它被a._proto_记录下来并指向A.prototype,而后者刚好被设置为对象obj. - 在对象
obj中找到了name属性,并返回它的值.
第二个例子:
var A = function(){};
A.prototype = {name:'nike'};
var B = function(){};
B.prototype = new A();
var b = new B();
console.log(b.name);//nike
读这段代码,引擎是这样工作的:
- 首先,遍历对象
b的属性,但是没有找到name这个属性; - 查找任务被委托给
b的构造器的原型B.prototype,但是还是没有; - 由于
B.prototype是通过A构造器构造的对象,所以这个任务被委托给构造器A的原型A.prototype; - 在
A.prototype中找到name属性,返回值.
原型模式和基于原型继承的js对象系统的更多相关文章
- 面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统
面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统 原型模式和基于原型继承的JavaScript对象系统 在 Brendan Eich 为 JavaScrip ...
- 【原型模式】--重写原型对象prototype的影响
//[原型模式]--重写原型对象prototype的影响 2014-12-12//定义构造函数function Person() { }//直接指定构造函数的原型为一个对象(为了简化逐个给原型添加成员 ...
- 【js基础】创建对象的几种常见模式(工厂模式,构造函数模式,原型模式,构造原型组合模式)
一.工厂模式 缺点:没有解决对象识别的问题 优点:解决了创建多个相似对象的问题 function createPerson(name,age,job){ var o = new Object(); o ...
- 通过JavaScript原型链理解基于原型的编程
零.此文动机 用了一段时间的Lua,用惯了Java C++等有Class关键字的语言,一直对Lua的中的面向对象技术感到费解,一个开源的objectlua更是看了n遍也没理解其中的原理,直到看到了Pr ...
- JS构造函数、对象工厂、原型模式
1.对象创建的3中方法 1.1.对象字面量 var obj = { name: "mingzi", work: function () { console.log("wo ...
- js设计模式:工厂模式、构造函数模式、原型模式、混合模式
一.js面向对象程序 var o1 = new Object(); o1.name = "宾宾"; o1.sex = "男"; o1.a ...
- JS 设计模式一 -- 原型模式
原型模式 概念: 原型模式 是指原型实例指向创建对象的种类,并通过拷贝这些原型创建新的对象,是一种用来创建对象的模式,也就是创建一个对象作为另一个对象的prototype属性. 实现原型模式: 方法一 ...
- 原型模式 -- JavaScript语言的灵魂
原型模式就是将原型对象指向创建对象的类,使这些类共享原型对象的方法与属性.JS是基于原型链实现对象之间的继承,是对属性或者方法的共享,而不是对属性和方法的复制. // 图片轮播类 var LoopIm ...
- Java原型模式
原型模式 原型模式也称克隆模式.原型模式jian ming zhi yi,就是先创造出一个原型,然后通过类似于Java中的clone方法,对对象的拷贝,克隆类似于new,但是不同于new.new创造出 ...
随机推荐
- JSP慕课网之application、page、pageContext、config、exception
接下来使用getSession().forward().include()方法. 跳转的include.jsp页面:
- 常用Git操作
--------------------git-------------------- 1.简介 1.Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.[1] ...
- css:box-sizing什么作用
css3 box-sizing属性 box-sizing属性可以为三个值之一:content-box(default),border-box,padding-box. content-box,bord ...
- Java jdk 快速配置
JAVA_HOME C:\Program Files\Java\jdk1.8.0_92 Path %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin; CLASSPATH ...
- Swiper 滑动
1.http://www.swiper.com.cn/download/ 下载Swiper.JS Swiper.CSS 2.引入项目,添加html <div class="cont ...
- C语言程序设计课程设计自查表格
课程设计自查表格 序号 项目 完成与否(完成打勾) 1 格式是否符合标准(缩进是否规范) 2 是否模块化设计(使用函数分解系统功能) 3 函数名否易懂(不得使用f1(int a1,int a2)这样的 ...
- 1st_homework_SE--四则运算题目生成器
0x00 Code 查询源代码及README请点此 0x01 需求分析 实现一个自动生成小学四则运算题目的命令行程序. 0x02 功能设计 主要功能为: 接受用户输入以便知道要出多少道题目python ...
- 扫雷游戏制作过程(C#描述):第五节、菜单操作(续)
前言 这里给出教程原文地址. 该项目已经放在github上托管. 发布版已经分享到百度网盘 菜单操作(续) 接着节前一章节的内容,我们继续完善菜单栏的功能. 我们首先,先完善Rank的选项,我们希望我 ...
- 201521123063 《Java程序设计》 第7周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 ArrayList代码分析 1.1 解释ArrayList的contains源代码 public boole ...
- 201521123109 《java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...