prototype的类定义与继承

避开爬虫坑:手把手教你合法获取百度地图POI边界数据(以学校为例) 本文详细介绍了如何合规获取百度地图POI边界数据的方法论,特别以学校为例。通过解析POI数据结构、合法使用百度地图API接口、优化请求策略以及数据处理技巧,帮助开发者和研究者在遵守平台规则的前提下高效获取地理信息。适用于学术研究、商业分析等多种场景,确保数据采集的合法性与准确性。 阅读详情

转自:http://www.cnblogs.com/ghostgift/p/3257963.html

由于工作需要项目中要用prototype框架,所以这几天捣鼓了一下,研究了一下prototype 创建对象和类以及继承的一些源码,其实早在很久以前就接触prototype,然后直接看源码, 看着太蛋疼,里面的牵连太多太深, 绕来绕去,脑袋都绕晕了, 所以索性直接看prototype官方教程里面Class.create()这个函数的使用方式,了解了它的使用方式以后我们再来一步一步的反推它是怎么实现的,这里注意一下我不是直接讲的prototype源码实现这一块的内容,说穿了源码我看着也晕, 上面都说了东西太多牵连太深。好了, 废话就不多说了,我们直接进入主题

 

我们先来看一段基于prototype来创建对象以及继承的一段代码

复制代码
//创建一个动物类
var Animal = Class.create({
    //初始化构造函数
    initialize: function(name, type) {
        this.name = name;
        this.type = type;
    },
    //动物类的方法
    speak: function() {
        alert("my name is "+name);
    }
});
复制代码

上面这段代码描述一个基于prototype写的动物类, 不得不佩服在面向对象这一块prototype设计的非常整洁和优雅,既然创建了一个类,下面我们来使用这个,如果有过java背景或者面向对象高级语言的同学是不是觉得调用方式有点相似,这样就体现出javascript在实现面向对象这一块还是很有优势的。

//下面我们来使用这个动物类
var animal = new Animal('小白', 'dog');
animal.speak();

但是现在问题来了,光能创建类就不能对刚刚创建的类进行扩展或者继承嘛, 答案是肯定的,要不然怎么说是大名鼎鼎的prototype嘛,好, 下面我们就来实现继承这个Animal类

复制代码
//创建人类,继承自动物类
var Person = Class.create(Animal, {
    initialize: function($super, name, type) {
        $super(name, type);
    },
    work: function() {
        alert(this.name+"今天工作了一整天,虽然有点累但很开心");
    }
});
复制代码

好到这里面我们已经看到prototype的强大之处了吧,那现在我们来说说这种方式创建类的一些特性,以便我们在后面来实现这样写面向对象做一些铺垫,那到底有什么一些特性或者特点呢

1.是通过Class.create()这个函数来创建类的,接受一个或者两个参数,这个函数重载了的

2.这个函数返回一个类,这个类又可以通过new的方式给为我们创建对象

3.每个类都有一个initialize方法,这个是一个构造器可以用于初始化构造对象

4.如果Class.create(base, child)方法重载了两个参数,那么base就是基类,child类是继承自base类的

上面说了prototype创建对象时的一些基本特点,下面我们就要来详细分析一下prototype创建到底是怎么来实现的,首先声明我不是看prototype框架源码来分析,我是根据这些写对象的一些特性来进行的,我们都知道如果声明一个函数,这个函数就是一个构造器,可以把它new出来的,看看下面的代码思路会更清晰

复制代码
//这样也能创建一个类,至于它与prototype的优劣只有自己体会了
function Animal(name, type) {
    this.name = name;
    this.type = type;
    
    this.speak = function() {
        alert("my name is"+this.name);
    };
}
var animal = Animal("小黄", "dog");
animal.speak();
复制代码

现在大家知道如果要采用new的方式肯定要有构造器,说白了就是一个函数,那现在我们知道Class.create()这个方法返回的是一个函数了吧,但是这到底是个怎么样的函数呢,接着在进行挖掘,首先我们来分析当传入一个参数也就是创建一个类没有继承的时候是这样一种情况

复制代码
var Animal = Class.create({
    //初始化构造函数
    initialize: function(name, type) {
        this.name = name;
        this.type = type;
    },
    //动物类的方法
    speak: function() {
        alert("my name is "+name);
    }
});
复制代码

其实就是传入的了json参数,里面放了两个函数,一个构造函数和一个成员函数,刚刚我们讲了这个Class.create()方法返回的是一个函数,传入的又是一个json, 那我们肯定要将json里面的函数复制到返回出来的这个函数里面,请看下面代码

 

复制代码
var Class = {
    create: function(object) {
        var fn = function() {};
        fn.prototype = object;
        return fn;
    }
};
//好了, 现在我们可以用上面的这个Class.create()方法来创建一个类
var Animal = Class.create({
    initialize: function(name) {
        this.name = name;
    },
    speak: function() {
        alert("my name is "+this.name);
    }
});
//下面我来new一下创建这个动物类
var animal = new Animal();
animal.initialize("dog");
animal.speak();
复制代码

上面这段代码是不是和prototype创建对象有点不一样,细心的同学会发现我们在new Animal()这个动物类的时候没有参数, 构造参数是通过animal.initialize()来初始化的,这样就不对了, prototype不是通过构造函数的时候就直接调用initialize()函数来进行初始化的吗,没错,所以我们要将上面的代码做一些小小的修改,上代码吧

复制代码
var Class = {
    create: function(object) {
        var fn = function() {
            this.initialize.apply(this, arguments);
        };
        fn.prototype = object;
        return fn;
    }
};

var Animal = Class.create({
    initialize: function(name) {
        this.name = name;
    },
    speak: function() {
        alert("my name is "+this.name);
    }
});
//下面我来new一下创建这个动物类
var animal = new Animal("dog");
animal.speak();
复制代码

到这里大家应该能看清楚到底是哪儿做了改动吧,this.initialize.apply(this, arguments); 就是在这儿做了手脚,fn这个函数在创建类的时候是会被返回的,所以在new这个被返回的函数里面可以做初始换的一些东西,就是调用我们的initialize()函数来进行初始化了, 这里声明一些哈,如果没有对javascript, this, 闭包,作用域,原型链方面的知识理解就非常痛苦了,不过我还是会大概说一下,this.initialize.apply(this, arguments);我们对这句话进行分解, this 其实指的是{init:functdion(), speak:function() {}}这个传进去的对象,apply(this, arguments), apply是将当前函数的上下文改变也就是把this改变,arguments就是一个函数运行时的参数,这样说可能有点同学不是很明白,如果实在看不明白javascript基础知识需要补补课了。现在我们能实现向prototype的语法一样来创建一个了类, 但仅仅是创建一个类,如果需要继承怎么办呢, 就像这样Class.create(base, object); 这个object要继承base, 大家都知道如果在继承的话肯定是要将base里面的成员和方法copy到object里面来,就这么简单吗, 我们来仔细想一下吧,应该有以下几点

首先将基类的成员copy到子类里面

  a. 如果子类的成员变量和积累的同名,会覆盖基类的

  b.子类的成员方法和基类的同名会覆盖积累的

  c.能不能子类和基类的成员方法进行重载呢,答案是肯定的

  d.手动控制调用基类的构造方法进行初始化会更灵活

以上这些就是prototype创建类的一些特性, 可能还不完善,欢迎大家讨论。 下面我们就用代码具体的实现,我会尽量用多的注释来标注方便大家理解和传播

复制代码
var Class = {
    /*
     *功能:创建一个类
     *参数:
     *    1.base 表示基类,但一定要是functdion类型的
     *    2.object 表示要创建的子类,json数据格式类型的
     */
    create: function(base, object) {
        var fn = null;
        //这个判断主要是创建有没有继承的类
        //一般情况其实就是检测create()方法是一个参数还是两个参数
        if(typeof base == "function") {
            //这个就是创建要返回的函数
            fn = function() {
                var args = [];
                //这个判断是检测子类initialize($super, ...)方法里面参数
                //如果有$super这个参数就是传了基类的构造函数可以调用,反之就没有
                if(object.initialize.length > arguments.length) {
                    //这里就是把基类的构造函数加入到args函数里面
                    //这里大家可以仔细体会一下这儿为什么要用一个闭包,还有
                    //apply(fn.prototype, arguments)方法里面两个参数的意义
                    args.push(function() {
                        base.prototype.initialize.apply(fn.prototype, arguments);
                    });
                }
                //将构造函数里面的参数加入到这个args数组
                for(var i = 0 ; i < arguments.length ; i++) {
                    args.push(arguments[i]);
                }
                //执行构造函数的初始化参数
                this.initialize.apply(this, args);
            };
            //先将积累里面的成员变量和方法copy到返回函数fn里面
            for(var property in base.prototype) {
                if(property != "initialize") {
                    fn.prototype[property] = base.prototype[property];
                }
            }
            //在将子类里面成员变量和方法copy到返回函数fn里面
            //注意这里为什么要先拷贝基类在拷贝子类,原因是
            //基类和子类的成员变量和方法重名的话优先的是子类的
            for(var property in object) {
                fn.prototype[property] = object[property];
            }
        }
        //这个是没有继承的情况就非常简单了, 上面有讲到,
        //这里就不再细细叙述了
        else {
            fn = function() {
                this.initialize.apply(this, arguments);
            }
            fn.prototype = base;
        }
        return fn;
    }
}

//下面就可以像prototype语法一样写出优雅的代码,
//这段是prototype官方Class.create()APi的源码实例

//创建一个动物类
var Animal = Class.create({
    initialize: function(name, sound) {
        this.name = name;
        this.sound = sound;
    },
    
    speak: function() {
        alert(this.name+"says:"+this.sound+"!");
    }
});
//实例化调用
var dog = new Animal('gogo', "wangwang");
dog.speak();

//创建一个人类,继承自动物类
var Snake = Class.create(Animal, {
    initialize: function($super, name) {
        //alert($super);
        $super(name, 'hisssssssssssssss');
    }, 
    say: function() {
        alert("my name is "+this.name);
    }
});

//实例化调用
var ringneck = new Snake("Ringneck");
ringneck.speak();
ringneck.say();
复制代码

说到这里prototype的 Class.create()方法的内核源码基本上就告一段落了,当然还有一些其他的方式,也各有千秋,大家可以看一下

复制代码
var Class = {
    create: function() {
        return function() {
            this.initialize.apply(this, arguments);
        }
    }
};

var Animal = Class.create();
Animal.prototype = {
    initialize: function(name) {
        this.name = name;
    },
    say: function() {
        alert("my name is "+this.name);
    }
};
复制代码

 


【第2章>第10节】深度学习DenseNet模型分析与matlab仿真 本文介绍了基于DenseNet深度学习模型的图像分类MATLAB实现方法。主要内容包括:1. DenseNet模型原理,详细解析了初始卷积层、密集块、过渡层等核心结构;2. 在MATLAB环境下完成DenseNet工具箱安装和测试样本准备;3. 实现图像预处理(统一缩放为224×224)、模型训练和测试的完整流程;4. 提供了混淆矩阵和准确率等测试结果分析。文章附带完整的MATLAB程序代码和操作视频教程,适合深度学习初学者快速掌握DenseNet模型的图像分类应用。通过实际测试,验证了该方案的有效性。 阅读详情

相关推荐

5G协议栈逆向工程:基于开源模拟器的核心网信令分析实战

本文详细介绍了基于开源模拟器Free5GC和UERANSIM的5G协议栈逆向工程实战,涵盖核心网信令分析、环境搭建、认证协议解析及安全漏洞验证。通过NGAP/NAS信令交互解密和异常流量注入测试,帮助研究人员深入理解5G网络安全机制,并提供实用的安全加固建议。

weixin_29250573的博客 672

JavaScript 特殊之-prototype __proto__ class

其实,对于一个函数对象来说,他的prototype属性和他的__proto__属性其实一点关系都没有,但是对于用这个函数产生的对象来说就有和这个函数的prototype属性有关系了,有一个关系就是对象的__proto__属性==函数对象的prototype属性.

no ACMer 1021

YOLOv8环境搭建+训练自己的数据详细项目

直接按照路径会有问题,找到自己 requirements.txt 文件路径,我这里是pip install -r D:\ultralytics-main\ultralytics-main\requirements.txt。首先去自己的anaconda的安装的envs(虚拟环境),在导航栏输入cmd,进入命令窗口。到官方网站下载yolo模型 ,下载好后解压,里面有个文件requirements.txt。然后安装ultralytics ,这是必须的。

m0_63172128的博客 2万+

设计模式:原型模式(Prototype)

设计模式:原型模式(Prototype)

ProgramNovice的博客 1166

【寄存器模型】一、一个简单的寄存器模型

在描述寄存器模型之前,首先来了解一下实际寄存器的组成结构:如下图所示的DUT内部真实的寄存器寄存器中最小的一个单位是域(field),域是由一个或多个bit拼接而成的。一个或多个域就构成了一个寄存器(reg)。一个或多个寄存器就构成了一个块(block)。将DUT中的寄存器抽象出来,建立寄存器模型,如下图所示:uvm library已经定义好了field、reg、block等相关的概念,构建寄存器模型时,只需要继承这些类即可。:构建寄存器模型中的域段。uvm_reg。...

carrotbanana的博客 5368

MS1030超声波流量计电路实战:如何用15ps精度优化水表设计(附配置代码)

本文深入探讨了如何利用MS1030超声波流量计芯片实现15ps高精度测量,以优化水表设计。文章从系统误差分配出发,详细解析了硬件电路设计要点、SPI通信配置及核心优化技巧,如利用可编程偏置电压和8回波累加功能来提升抗干扰能力与测量稳定性,并附有实用的配置代码示例。

svm4gardener的博客 330

prototype详解及prototype、new之间的关系

1.prototype解释 在JavaScript中,prototype对象是实现面向对象的一个重要机制。 每个函数就是一个对象(Function),函数对象都有一个子对象 prototype对象,类是以函数的形式来定义的。prototype表示该函数的原型,也表示一个类的成员的集合。 在通过new创建一个类的实例对象的时候,prototype对象的成员都成为实例化对象的成员

Turnhead的专栏 4216

黑猫带你学UFS协议第12篇:UFS标志(Flags)和属性(Atrributes)详解

UFS中的标志其实就是一些开关,布尔型,非0即1,打开或者关闭。这些标志可以用来使能或者禁止UFS设备的一些功能、模式或者状态。 简单来说,flag和attribute、discriptor一样,都是ufs的寄存器罢了。只不过spec将这些寄存器分类了,分成这三种大的类型了而已。 标志可以被清除、复位、设置、触发、读。 主机也是通过设备管理器的Query Request UPIU来读取或者写标志。

黑猫奥利奥的博客 2082

深入prototype源码之--Class

由于工作需要项目中要用prototype框架,所以这几天捣鼓了一下,研究了一下prototype 创建对象和类以及继承的一些源码,其实早在很久以前就接触prototype,然后直接看源码, 看着太蛋疼,里面的牵连太多太深,绕来绕去,脑袋都绕晕了,所以索性直接看prototype官方教程里面Class.create()这个函数的使用方式,了解了它的使用方式以后我们再来一步一步的反推它是怎么实现的...

weixin_33912445的博客 168

深度学习注意力机制新突破:YOLOv8结合SimAM无参数注意力模块,让目标检测更精准!

在计算机视觉领域,注意力机制已成为提升模型性能的关键技术。然而,传统的注意力模块如SENet、CBAM等往往引入大量额外参数,增加了模型的复杂度和计算负担。本文介绍一种创新的无参数注意力机制——SimAM(Simple Parameter-Free Attention Module),并将其成功应用于YOLOv8目标检测框架。SimAM基于神经科学理论,通过定义能量函数为特征图计算3D注意力权重,无需任何额外参数即可显著提升模型性能。本文详细阐述了SimAM的理论基础、实现原理,并提供了完整的YOLOv8集

YOLO 97

保姆级教程!Python爬虫爬取知乎回答,保存为Markdown文件

本教程实现了知乎公开回答的完整爬取与Markdown保存,核心流程为「请求页面→解析作者/时间/正文/图片→下载图片→保存MD文件」,步骤清晰,代码可直接复用关键特性:支持合并/单文件两种保存模式、自动下载图片并引用、中文乱码防护、非法文件名过滤,满足日常整理知乎回答的需求新手友好:无需复杂配置,仅需修改知乎问题URL即可运行,全程无坑,5分钟内可看到运行结果灵活扩展:支持进阶优化(登录、分页、格式完善),可根据个人需求调整功能。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1232

深入了解JavaScript中基于原型(prototype)的继承机制

在翻阅JavaScript语言精粹看到了一句令我感觉诧异的话–**每个对象都连接到一个原型对象,并且它可以从中继承属性。**类似的话在MDN-对象原型也出现过。 ES5 Object.create 2009 JavaScript语言精粹 版次:2009年4月第一版 2012年9月第二版 MDN : Last modified: 2020年7月17日, by MDN contributors ...

前端学习笔记 1030

Oracle EBS FA 创建成批增加执行时间长且报错

摘要 Oracle EBS系统在执行"创建成批增"请求时出现长时间运行并报错(ORA-00603和ORA-03114)。

陈显平的专栏-Oracle EBS 173

类的定义与继承

类的定义 类定义有三种基本方法, 1、创建并能返回特定类型的对象的函数(工厂函数),例如:function Co(){ var o = new Object; o.a = 1 return o}; 用这种方式创建对象: var o = Co() 2、创建构造函数,用new 实例化,例如 function Co(){this.a = 1} 用这种方式创建对象:var o = new Co

knifewei的专栏 1184

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

javascript中类的创建和继承

类的定义 类定义有三种基本方法, 1、创建并能返回特定类型的对象的函数(工厂函数),例如:function Co(){ var o = new Object; o.a = 1 return o}; 用这种方式创建对象: var o = Co() 2、创建构造函数,用new 实例化,例如 function Co(){this.a = 1} 用这种方式创建对象:var o = new

WebWalker 1504

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Prototype使用Class

1.前言 Class对象主要提供如下的两个方法。 1)        create([superclass][,methods…]):定义一个新类,该新类继承superclass类里所有方法。 2)        addMethod(methods):扩展已有的类,该方法为一个已有的类新增方法,或者覆盖原有的方法。 2.例子  使用Class // 定义一个

owen_william的博客 720

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

javascript中类的定义和继承

类的定义 类定义有三种基本方法, 创建并能返回特定类型的对象的函数(工厂函数),例如:function Co(){ var o = new Object; o.a = 1 return o}; 用这种方式创建对象: var o = Co() 创建构造函数,用new 实例化,例如 function Co(){this.a = 1} 用这种方式创建对象:var o = new Co() 原型方式,利用...

yring 168

JavaScript类和继承:prototype属性

JavaScript类和继承:prototype属性 2009-07-08 17:48 sanshi 博客园 我要评论(0) 字号:T | T 本文介绍了JavaScript里面的prototype属性。这个属性是理解JavaScript类和继承的重要基础。 AD: 我们已经在第一章中使用prototype属性模拟类和继承的实现。 p

01040201的专栏 532

es5中继承和es6中class继承

es5中的类 es5中想要生成一个实例对象的话需要先定义一个构造函数,然后通过new操作符来生成实例对象。 当你定义了构造函数并且new 构造函数()了,后台就会隐式执行new Object()创建对象。并将构造函数的作用域给到新对象,即实例对象的this直接指向构造函数, es6中的类 es6中引入了class类的概念,通过class关键字可以直接定义一个类。 注意事项: 1.定义方法不能使用function关键字 2.方法之间不能用逗号隔开,不然会发生报错 class定义的类实质上就是一个函数,她指向自

weixin_47208955的博客 406

用prototype属性来模拟一下类的继承

用prototype属性来模拟一下类的继承:首先定义一个Circle类作为父类,然后定义子类PositionCircle. Js代码 functionCircle(radius){//定义父类Circle this.radius=radius; } Circle.prototype.area=function(){//定义父...

weixin_30363817的博客 84

Javascript prototype 原型链

<br />prototype源自法语,软件界的标准翻译为“原型”,代表事物的初始形态,也含有模型和样板的意义。JavaScript中的prototype概念恰如其分地反映了这个词的内含,我们不能将其理解为C++的prototype那种预先声明的概念。 <br /><br />     JavaScript 的所有function类型的对象都有一个prototype属性。这个prototype属性本身又是一个object类型的对象,因此我们也可以给这 个prototype对象添加任意的属性和方法。既然

在路上... 643

JavaScript中对象继承

类的继承有两种基本方法 对象冒充 基本原理: 构造函数使用this关键字给所有属性和方法赋值(构造函数实际上仅仅是赋值函数),所以可以利用一种方式,在类内部直接运行赋值函数,把其this关键字传递给新类。例如: Java代码    1. var a = function(){     2.     this.a = 1;     3.     this.b = 2;     4.     alert(this);     5. }     6.      7. var b =

Jinuxwu的专栏 770

浅析Javascript中继承和Prototype的关系http://www.cnblogs.com/meil/archive/2007/06/22/792895.aspx

     JavaScript中支持类的定义,而且定义的方式与函数基本上也相同。1function out(val){2  document.write(val+"");3};45function BaseClass() {6  this.a="Im BaseClass.a .";7};第一行的内容可以看成是一个函数,第五行可以看成是一个类。     我们继续,现在我们来看看Javasc

专栏 758

Prototype的学习笔记

转自:http://javautils.iteye.com/blog/162660 一般JS类都如下方式写 Java代码 var MyClass = Class.create(); MyClass.prototype = { initialize : function(){ }, method_1: func...

wsy2801 161

js原型prototype,proto与function之间的关系图

原文地址:http://peihexian.iteye.com/blog/2147079美工人员一般是用js写个function校验表单数据的合法性,例如 function checkAndSubmit(){ if (document.getElementById('username').value=='') { alert('请输入登录用户名!'); r...

程序员记事本 706

用prototype 方式来创建客户端组件类

用prototype mode有以下好处:1、相对于那种把所有的方法定义都放在类的构造函数中的方式,这种方式的效率更高;   采用prototype方式定义的类更容易理解,代码更好重用。一般来说比较推荐这种方式。当然了,这样的方式不是必须的,javascript的语法是十分的灵活的,正是由于他的灵活导致了许多代码的难以理解;下面的代码是一个简单的prototype方式大示例: // Declar...

weixin_34205076的博客 113
上一篇: ajax post 后台收不到数据
下一篇: spark kafka 零数据丢失-----java版
join_null
博客等级 码龄11年 25粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值