像同样基于原型编程的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

这段代码运行的时候,引擎是这样工作的:

  1. 首先,尝试遍历对象a中所有的属性,但是没有找到name这个属性.
  2. 查找name属性的这个请求被委托给了对象a的构造器的原型,它被a._proto_记录下来并指向A.prototype,而后者刚好被设置为对象obj.
  3. 在对象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

读这段代码,引擎是这样工作的:

  1. 首先,遍历对象b的属性,但是没有找到name这个属性;
  2. 查找任务被委托给b的构造器的原型B.prototype,但是还是没有;
  3. 由于B.prototype是通过A构造器构造的对象,所以这个任务被委托给构造器A的原型A.prototype;
  4. A.prototype中找到name属性,返回值.

原型模式和基于原型继承的js对象系统的更多相关文章

  1. 面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统

    面向对象的JavaScript --- 原型模式和基于原型继承的JavaScript对象系统 原型模式和基于原型继承的JavaScript对象系统 在 Brendan Eich 为 JavaScrip ...

  2. 【原型模式】--重写原型对象prototype的影响

    //[原型模式]--重写原型对象prototype的影响 2014-12-12//定义构造函数function Person() { }//直接指定构造函数的原型为一个对象(为了简化逐个给原型添加成员 ...

  3. 【js基础】创建对象的几种常见模式(工厂模式,构造函数模式,原型模式,构造原型组合模式)

    一.工厂模式 缺点:没有解决对象识别的问题 优点:解决了创建多个相似对象的问题 function createPerson(name,age,job){ var o = new Object(); o ...

  4. 通过JavaScript原型链理解基于原型的编程

    零.此文动机 用了一段时间的Lua,用惯了Java C++等有Class关键字的语言,一直对Lua的中的面向对象技术感到费解,一个开源的objectlua更是看了n遍也没理解其中的原理,直到看到了Pr ...

  5. JS构造函数、对象工厂、原型模式

    1.对象创建的3中方法 1.1.对象字面量 var obj = { name: "mingzi", work: function () { console.log("wo ...

  6. js设计模式:工厂模式、构造函数模式、原型模式、混合模式

    一.js面向对象程序 var o1 = new Object();     o1.name = "宾宾";     o1.sex = "男";     o1.a ...

  7. JS 设计模式一 -- 原型模式

    原型模式 概念: 原型模式 是指原型实例指向创建对象的种类,并通过拷贝这些原型创建新的对象,是一种用来创建对象的模式,也就是创建一个对象作为另一个对象的prototype属性. 实现原型模式: 方法一 ...

  8. 原型模式 -- JavaScript语言的灵魂

    原型模式就是将原型对象指向创建对象的类,使这些类共享原型对象的方法与属性.JS是基于原型链实现对象之间的继承,是对属性或者方法的共享,而不是对属性和方法的复制. // 图片轮播类 var LoopIm ...

  9. Java原型模式

    原型模式 原型模式也称克隆模式.原型模式jian ming zhi yi,就是先创造出一个原型,然后通过类似于Java中的clone方法,对对象的拷贝,克隆类似于new,但是不同于new.new创造出 ...

随机推荐

  1. JSP慕课网之application、page、pageContext、config、exception

    接下来使用getSession().forward().include()方法. 跳转的include.jsp页面:

  2. 常用Git操作

    --------------------git-------------------- 1.简介     1.Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目.[1]  ...

  3. css:box-sizing什么作用

    css3 box-sizing属性 box-sizing属性可以为三个值之一:content-box(default),border-box,padding-box. content-box,bord ...

  4. Java jdk 快速配置

    JAVA_HOME C:\Program Files\Java\jdk1.8.0_92   Path %JAVA_HOME%\bin;%JAVA_HOME%\jre\bin;   CLASSPATH ...

  5. Swiper 滑动

    1.http://www.swiper.com.cn/download/  下载Swiper.JS  Swiper.CSS 2.引入项目,添加html <div class="cont ...

  6. C语言程序设计课程设计自查表格

    课程设计自查表格 序号 项目 完成与否(完成打勾) 1 格式是否符合标准(缩进是否规范) 2 是否模块化设计(使用函数分解系统功能) 3 函数名否易懂(不得使用f1(int a1,int a2)这样的 ...

  7. 1st_homework_SE--四则运算题目生成器

    0x00 Code 查询源代码及README请点此 0x01 需求分析 实现一个自动生成小学四则运算题目的命令行程序. 0x02 功能设计 主要功能为: 接受用户输入以便知道要出多少道题目python ...

  8. 扫雷游戏制作过程(C#描述):第五节、菜单操作(续)

    前言 这里给出教程原文地址. 该项目已经放在github上托管. 发布版已经分享到百度网盘 菜单操作(续) 接着节前一章节的内容,我们继续完善菜单栏的功能. 我们首先,先完善Rank的选项,我们希望我 ...

  9. 201521123063 《Java程序设计》 第7周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 ArrayList代码分析 1.1 解释ArrayList的contains源代码 public boole ...

  10. 201521123109 《java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...