为什么会有原型这个概念;

1、优雅的创建对象;

2、继承;

先看js 之前创建对象的方式存在的问题;

创建对象方式

1、字面量

var obj={name:"join",age:18}

var obj1={name:"Tom",age:88}

当我们需要创建多个属性只有值不一样的对象时,这种方式就悲剧来了,会造成大量的冗余代码,最重要的是代码不能复用;

2、工厂模式

这种工厂模式并不是设计模式中的工厂方法,代码如下:

    function createObj(name, age) {
        var o = new Object();
        o.name = name;
        o.age = age;
        o.sayHello= function() {
            alert("Hello Word!");
        }
        return o;
    }

    var obj = createBlog("Tom", "88");

这种方式好多了,但是也存在一个问题,就是没办法知道一个对象是什么类型;console.log(typeof obj);//object

3、构造函数模式


function Person(name,age,job){    this.name=name;    this.age=age;    this.job=job;    this.sayNmae=function(){        alert(this.name);    }}var persong1=new Person("Join",18,"农民");var persong2=new Person("Join",18,"地主");

构造函数模式看起来oop(面向对象)多了,上面两种模式存在的问题在构造模式中都不存在了(创建对象的代码可以复用、对象类型可以识别)看起来世界挺美好,遗憾的是

这种还是存在一个问题;

1、每一个方法都要在每个实例上重新创建一次(问题不大);

2、从上面例子可以看出每个person 实例都包含一个不同的function 实例;不要忘了ECMAScript中的函数也是对象,所以上面的代码与下面的代码等价(主要会造成不同的作用域和解析问题)

    function Person(name,age,job){
        this.name=name;
        this.age=age;
        this.job=job;
        this.sayNmae=new function(){
            alert(this.name);
        }
    }
alert(person1.sayNmae==person2.sayNmae)// false

当然这个问题也是能解决的,就是把方法移到外面,让他成为全局的函数,但是这样一来该函数就只能由widows对象调用了,而且如果存在多个方法,就会存在多个全局函数,那我们自定义的的引用类型就丝毫没有封装可言了。好在这些问题都可言通过原型模式来解决;说了一大堆废话进入正题:原型,他是一个对象;

function特征

在js中一切都是对象,当我们写function 时js 就会同时创建它的prototype对象(原型对象),这个对象包含一个属性prototype(原型),这个属性是一个指针,该指针指向原型对象,

该对象的作用是特定类型(该类型实例的对象)的所有实例共享属性和方法;

function Person(name,age,job){

    this.name=name;    this.age=age;    this.job=job;}Person.prototype.sayNmae=function(){    alert(this.name);}var persong1=new Person("Join",18,"农民");var persong2=new Person("Join",18,"地主");

alert(persong1.sayNmae==persong2.sayNmae)// true

Prototype对象

在默认情况下所有原型对象都会自动获得一个属性Constructor(构造函数属性)这个属性包含一个指向prototype属性所在的函数指针;

实例之New 操作符

创建一个实例通常会经历以下4步:

1、创建一个新的对象;

2、将构造函数的作用域赋给新对象(this指针指向这个新的对象);

3、执行构造函数中的代码(还会将该对象的__proto__指向了函数的prototype对象);

4、返回该对象;

需要注意的地方是当调用构造函数创建一个新对象后,该对象内部将包含一个指正(内部属性 _proto_),指向构造函数的原型对象(prototype 对象),该属性在ES6中貌似规范化了;

实例、构造函数、原型对象关系

创建的每个实例都会有一个内部属性_proto_ 指向构造函数的原型对象;

构造函数存在prototype 属性指向该函数的原型对象;

上面person代码如图:

图画的不好下次试试思维导图这个工具;

注意实例只跟原型对象有关系;

查找原理

当代码读取某个对象的属性或者方法时都会执行一次搜索,首先从从对象本身开始,如果存在则返回给定的属性名或者方法名,不存在继续搜索指针(_proto_)指向的原型对象,如上面的代码 persong1.sayNmae。首先解析器会问:"对象实例person1有sayName吗?",答:没有,然后继续搜索,问person1的原型有"sayName 吗?",答:有,读取原型对象中的函数;这就是多个实例共享原型中属性、方法的基本原理;

由此可知当实例中与原型中存在相同的属性名时会读取实例的属性名,但是他们之间不存在引用问题,即你设置了实例的属性为null,并不会影响到原型中的属性,他们终究是属于不同的对象;

更简单的原型语法

当我们要添加多个方法时,没必要每次都写类似这样的代码 Person.Prototype.XXX=function(){//doing something}

Person.Prototype={

constructor:Person,//注意这里要重写

sayAge:function(){ alert(this.age);},

sayJob:function(){ alert(this.job);}

}

这里为什么要重写constructor呢,很简单每创建一个函数,就会同时创建它的prototype对象(原型对象),这个对象也会获得constructor属性,

而上面我们重写了默认的prototype对象,因此constructor这时并没有指向Person,而是指向新object构造函数,所以这里要重写constructor让他指向Person;

原型动态性

原型是对象,对象是引用类型,所以当在原型中干了些什么事情,都能立即在实例对象上反应出来;

原生对象的模型

JS 原生的引用类型,都是采用这种模式创建的。如 在Array.prototype.sort(),可以找到sort()方法。

原型模式的问题

当我们把引用类型属性添加到原型对象时,会造成数据共享的问题,如 在person 中把一个数组放到原型对象中,此时所有的对象都会共享这个数组:

friedns:["tom","Join","Elie"];

当我们其中一个实例对这个对象进行push("Tem");

所有的实例都可以访问到"Tem";

组合使用构造函数与原型模式

基于上面数据共享的问题,解决方案通常是:属性写在构造函数中,方法写在原型中,这样每个实例都会有自己属性,同时又共享着方法的引用,这样既能最大限度的节省了内存;

总结

1、创建function 就会同时创建它的prototype对象(原型对象),function也是对象其实在原型对象中也存在一个默认的_proto_ 指向函数的原型对象(Function.prototype);

2、JS 每个对象中都存在_proto_,函数对象才存在prototype 属性,所以会看到一些博客说JS 对象分为两种:一种是Object(自定义),一种是function;

3、实例话对象就会把function中的prototype属性值赋给对象实例的_proto_;

4、原型是一个对象,我们可以重写该对象;

本人JS新手有误之处还请谅解,顺便指出错误,让我们这些新手有进步!

javaScript-原型、继承-01的更多相关文章

  1. 再谈javascript原型继承

    Javascript原型继承是一个被说烂掉了的话题,但是自己对于这个问题一直没有彻底理解,今天花了点时间又看了一遍<Javascript模式>中关于原型实现继承的几种方法,下面来一一说明下 ...

  2. 彻底理解Javascript原型继承

    彻底理解Javascript原型继承 之前写过一篇Javascript继承主题的文章,这篇文章作为一篇读书笔记,分析的不够深入. 本文试图进一步思考,争取彻底理解Javascript继承原理 实例成员 ...

  3. [转]Javascript原型继承

    真正意义上来说Javascript并不是一门面向对象的语言,没有提供传统的继承方式,但是它提供了一种原型继承的方式,利用自身提供的原型属性来实现继承.Javascript原型继承是一个被说烂掉了的话题 ...

  4. JavaScript原型继承工作原理

    原型继承的定义 当你阅读关于JS原型继承的解释时,你时常会看到以下这段文字: 当查找一个对象的属性时,JavaScript 会向上遍历原型链,直到找到给定名称的属性为止.——出自JavaScript秘 ...

  5. 【读书笔记】读《编写高质量代码—Web前端开发修炼之道》 - JavaScript原型继承与面向对象

    JavaScript是基于原型的语言,通过new实例化出来的对象,其属性和行为来自于两部分,一部分来自于构造函数,另一部分是来自于原型.构造函数中定义的属性和行为的优先级比原型中定义的属性和优先级高, ...

  6. JavaScript 原型继承开端

    1.原型继承本质       就javascript对象系统的实现来讲,对象并没有原型,而构造器有原型(构造器.prototype指向其原型).对象只有构造自某个原型的说法,并没有持有某个原型的说法. ...

  7. 浅析Javascript原型继承(转)

    引自: http://blog.csdn.net/kittyjie/article/details/4380918 原作者解释的浅显易懂,非常不错的JavaScript prototype总结 JS没 ...

  8. Javascript原型继承容易忽略的错误

    编写Javascript的开发者都知道,JS虽然没有类(ES6添加了class语法),但是可以模拟出OOP语言的类和面向对象的概念,比如我们都知道的一句话,Javascript中处处是对象,而面向对象 ...

  9. javascript原型继承圣杯模式

    javascript纯面向对象开发需要使用到的一个模式,来对对象之间原型继承做中间层代理避免重复继承与代码杂乱 <!DOCTYPE html> <html lang="en ...

  10. javascript原型继承

    在传统的基于Class的语言如Java.C++中,继承的本质是扩展一个已有的Class,并生成新的Subclass. 由于这类语言严格区分类和实例,继承实际上是类型的扩展.但是,JavaScript由 ...

随机推荐

  1. K2 K2Blackpearl安装步骤详解(服务端)

    转:http://www.cnblogs.com/dannyli/archive/2011/11/30/2269485.html 以下是K2 Blackpearl的安装步骤,本人亲测可用哦. 1.安装 ...

  2. 跨平台移动开发工具:PhoneGap与Titanium全方位比拼

    PhoneGap和Appcelerator Titanium,对于封装和配置移动应用程序而言,二者都是非常受欢迎的开源JavaScript框架.本文为Appcelerator开发者Kevin Whin ...

  3. 对 HTTP 304 的理解

    最近和同事一起看Web的Cache问题,又进一步理解了 HTTP 中的 304 又有了一些了解. 304 的标准解释是: Not Modified 客户端有缓冲的文档并发出了一个条件性的请求(一般是提 ...

  4. JdbcTemplate与事务

    JdbcTemplate操作采用的是JDBC默认的AutoCommit模式,也就是说我们还无法保证数据操作的原子性(要么全部生效,要么全部无效),如: JdbcTemplate jdbcTemplat ...

  5. cocoa NSFileManager

    NSFileManager中包含了用来查询单词库目录.创建.重命名.删除目录以及获取/设置文件属性的方法(可读性,可编写性等等). 每个程序都会有它自己的沙盒,通过它你可以阅读/编写文件.写入沙盒的文 ...

  6. [转]Linux之type命令

    转自:http://codingstandards.iteye.com/blog/831504 用途说明 type命令用来显示指定命令的类型.一个命令的类型可以是如下之一 alias 别名 keywo ...

  7. 整合git与wingIDE(代码下载)

    通过多次被IDE的闪退崩溃甚至无教程调教后,我深刻认识到开发wingIDE这种IDE的小公司,在很多功能方面就是个坑…… 所以,如果你的电脑比较好,运行pycharm无压力,建议略过此文,直接去用py ...

  8. C#缓存的一点想法及测试

    项目开发中,用到了缓存,其中的一个列表项,可能要多线程处理,就有了下面的想法,具体的问题在代码中有详细说明,见下文. static void Main(string[] args) { 测试缓存的想法 ...

  9. 机器学习&数据挖掘笔记(常见面试之机器学习算法思想简单梳理)

    机器学习&数据挖掘笔记_16(常见面试之机器学习算法思想简单梳理) 作者:tornadomeet 出处:http://www.cnblogs.com/tornadomeet 前言: 找工作时( ...

  10. keyCode 与charCode

    键盘事件拥有两个属性,keyCode和CharCode,他们之间有一些不一样之处.keyCode表示用户按下键的实际的编码,而charCode是指用户按下字符的编码. IE下 keyCode:对于ke ...