-
prototype
2018-05-27 19:33:26什么是prototype我们创建的每个函数都有一个prototype属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。对普通函数来说这个属性没什么用,只有在构造函数创建实例的时候该属性...什么是prototype
我们创建的每个函数都有一个prototype属性,这个属性是一个对象,它的用途是包含可以由特定类型的所有实例共享的属性和方法。对普通函数来说这个属性没什么用,只有在构造函数创建实例的时候该属性有用。
prototype用处
举个例子:
var Student=function(n,a){ this.name=n; this.age=a; } Student.prototype.show=function(){ console.log(this.name+this.age); } var s1=new Student('tom',15); s1.show();
你创建了一个学生类,你发现这个学生类创建出的所有实例的show这个方法是完全一样的,如果你把show这个方法绑定到this上,那么每次创建实例的时候都会新建一个show方法出来,这是没有必要的,所以你把该类实例共享的这类属性给放在prototype对象中,所有实例是共用一个原型的。这样既保证了每个实例都有show这个方法,又不必每次创建实例的时候都新建这个方法。
在说原理之前你得懂这些知识点,每个实例对象都有一个__proto__指针,指向构造该实例的构造函数的prototype。因为任何一个对象,都可以充当其他对象的原型,所以实例对象也可以作为构造函数去创建自己的实例。然后当一个对象寻找某个属性的时候,他会先看自己有没有这个属性,如果没有就看自己的原型有没有这个属性,如果没有再去__proto__指向的构造函数的prototype里面看有没有,依次向上追溯,直至Object.prototype。因为所有对象都是Object对象的实例。这就是原型链。
所以上面的例子中,s1在调用show的时候,先在自己内部找show这个方法,没找到,就去自己的原型里面找,也没有,就沿着__proto__指针找到了Student.prototype,然后就找到了。
(注意IE浏览器不支持__proto__打印)
prototype原形对象中有一个属性叫做constructor构造属性,指向prototype对象所在的构造函数。作用是得知某个实例对象到底是哪个构造函数创建出来的。
接下来介绍一些运算符instanceof
使用方法:
var Student=function(n,a){ this.name=n; this.age=a; } var s1=new Student('tom',15); console.log(s1 instanceof Student);//true
console.log('str' instanceof String);//false console.log(12 instanceof Number);//false
左边操作数为对象(如果不小心写成基本类型 比如数字啥的,就会返回false),右边操作数是函数构造器,否则抛出TypeError。 实质就是:instanceof操作符判断左操作数对象的原型链上是否有右边这个构造函数的prototype属性,也就是说指定对象是否是某个构造函数的实例,最后返回布尔值。
in使用方法:
左边是字符串形式的属性名,右边是对象。作用是判断右边对象是否含有该属性名。无论该属性在实例中还是,原型中。var Student=function(n,a){ this.name=n; this.age=a; } Student.prototype.show=function(){}; var s1=new Student('tom',15); console.log('name' in s1);//true console.log('show' in s1);//true
Object对象的方法Object.prototype.isPrototypeOf()
举个例子:
var Student=function(n,a){ this.name=n; this.age=a; } Student.prototype.show=function(){}; var s1=new Student('tom',15); console.log(Student.prototype.isPrototypeOf(s1));//true
用以判断调用此方法的对象是否为,作为参数的对象的原型。
Object.prototype.hasOwnProperty()
借用上面那个例子:
这个方法用来判断该对象属性,是定义在对象自身,还是在原型链上。如果是在自身,返回true。console.log(s1.hasOwnProperty('name'));//true console.log(s1.hasOwnProperty('show'));//false
-
Prototype
2016-08-19 19:07:44Prototype 描述 Prototype 提供的函数可使 HTML DOM 编程更容易。 与 jQuery 类似,Prototype 也有自己的 $() 函数。 $() 函数接受 HTML DOM 元素的 id 值(或 DOM 元素),并会向 DOM 对象添加新的功能。 与 jQuery...Prototype 描述
Prototype 提供的函数可使 HTML DOM 编程更容易。
与 jQuery 类似,Prototype 也有自己的 $() 函数。
$() 函数接受 HTML DOM 元素的 id 值(或 DOM 元素),并会向 DOM 对象添加新的功能。
与 jQuery 不同,Prototype 没有用以取代 window.onload() 的 ready() 方法。相反,Prototype 会向浏览器及 HTML DOM 添加扩展。
在 JavaScript 中,您可以分配一个函数以处理窗口加载事件:
JavaScript 方式:
function myFunction()
{
var obj=document.getElementById("h01");
obj.innerHTML="Hello Prototype";
}
οnlοad=myFunction;
等价的 Prototype 是不同的:
Prototype 方式:
function myFunction()
{
$("h01").insert("Hello Prototype!");
}
Event.observe(window,"load",myFunction);
Event.observe() 接受三个参数:
您希望处理的 HTML DOM 或 BOM(浏览器对象模型)对象
您希望处理的事件
您希望调用的函数
与 jQuery 相同,Prototype 允许链式语法。
链接(Chaining)是一种在同一对象上执行多个任务的便捷方法。 -
帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
2018-07-25 22:50:47作为一名前端工程师,必须搞懂JS中的prototype、__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞懂它们。这里说明一点,__...提示:不要排斥,静下心来,认真读完,你就搞懂了!(可以先看一下最后的总结部分再回过头来完整看完)
1. 前言
作为一名前端工程师,必须搞懂JS中的
prototype
、__proto__
与constructor
属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞懂它们。这里说明一点,__proto__
属性的两边是各由两个下划线构成(这里为了方便大家看清,在两下划线之间加入了一个空格:_ _proto_ _
,读作“dunder proto”,“double underscore proto”的缩写),实际上,该属性在ES标准定义中的名字应该是[[Prototype]]
,具体实现是由浏览器代理自己实现,谷歌浏览器的实现就是将[[Prototype]]
命名为__proto__
,大家清楚这个标准定义与具体实现的区别即可(名字有所差异,功能是一样的),可以通过该方式检测引擎是否支持这个属性:Object.getPrototypeOf({__proto__: null}) === null
。本文基于谷歌浏览器(版本 72.0.3626.121)的实验结果所得。
现在正式开始! 让我们从如下一个简单的例子展开讨论,并配以相关的图帮助理解:function Foo() {...}; let f1 = new Foo();
以上代码表示创建一个构造函数
Foo()
,并用new
关键字实例化该构造函数得到一个实例化对象f1
。这里稍微补充一下new操作符将函数作为构造器进行调用时的过程:函数被调用,然后新创建一个对象,并且成了函数的上下文(也就是此时函数内部的this是指向该新创建的对象,这意味着我们可以在构造器函数内部通过this参数初始化值),最后返回该新对象的引用,详细请看:详解JavaScript中的new操作符。虽然是简简单单的两行代码,然而它们背后的关系却是错综复杂的,如下图所示:
看到这图别怕,让我们一步步剖析,彻底搞懂它们!
图的说明:右下角为图例,红色箭头表示__proto__
属性指向、绿色箭头表示prototype
属性的指向、棕色实线箭头表示本身具有的constructor
属性的指向,棕色虚线箭头表示继承而来的constructor
属性的指向;蓝色方块表示对象,浅绿色方块表示函数(这里为了更好看清,Foo()仅代表是函数,并不是指执行函数Foo后得到的结果,图中的其他函数同理)。图的中间部分即为它们之间的联系,图的最左边即为例子代码。2. _ _ proto _ _ 属性
首先,我们需要牢记两点:①
__proto__
和constructor
属性是对象所独有的;②prototype
属性是函数所独有的。但是由于JS中函数也是一种对象,所以函数也拥有__proto__
和constructor
属性,这点是致使我们产生困惑的很大原因之一。上图有点复杂,我们把它按照属性分别拆开,然后进行分析:
第一,这里我们仅留下__proto__
属性,它是对象所独有的,可以看到__proto__
属性都是由一个对象指向一个对象,即指向它们的原型对象(也可以理解为父对象),那么这个属性的作用是什么呢?它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__
属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存在这个属性,则继续往父对象的__proto__
属性所指向的那个对象(可以理解为爷爷对象)里找,如果还没找到,则继续往上找…直到原型链顶端null(可以理解为原始人。。。),再往上找就相当于在null上取值,会报错(可以理解为,再往上就已经不是“人”的范畴了,找不到了,到此结束,null
为原型链的终点),由以上这种通过__proto__
属性来连接对象直到null
的一条链即为我们所谓的原型链。
其实我们平时调用的字符串方法、数组方法、对象方法、函数方法等都是靠__proto__
继承而来的。3. prototype属性
第二,接下来我们看
prototype
属性:
prototype
属性,别忘了一点,就是我们前面提到要牢记的两点中的第二点,它是函数所独有的,它是从一个函数指向一个对象。它的含义是函数的原型对象,也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象,由此可知:f1.__proto__ === Foo.prototype
,它们两个完全一样。那prototype
属性的作用又是什么呢?它的作用就是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法。任何函数在创建的时候,其实会默认同时创建该函数的prototype对象。4. constructor属性
最后,我们来看一下
constructor
属性:
constructor
属性也是对象才拥有的,它是从一个对象指向一个函数,含义就是指向该对象的构造函数,每个对象都有构造函数(本身拥有或继承而来,继承而来的要结合__proto__
属性查看会更清楚点,如下图所示),从上图中可以看出Function这个对象比较特殊,它的构造函数就是它自己(因为Function可以看成是一个函数,也可以是一个对象),所有函数和对象最终都是由Function构造函数得来,所以constructor
属性的终点就是Function这个函数。
感谢网友的指出,这里解释一下上段中“每个对象都有构造函数”这句话。这里的意思是每个对象都可以找到其对应的constructor,因为创建对象的前提是需要有constructor,而这个constructor可能是对象自己本身显式定义的或者通过__proto__
在原型链中找到的。而单从constructor这个属性来讲,只有prototype对象才有。每个函数在创建的时候,JS会同时创建一个该函数对应的prototype对象,而函数创建的对象.__proto__ === 该函数.prototype,该函数.prototype.constructor===该函数本身
,故通过函数创建的对象即使自己没有constructor属性,它也能通过__proto__
找到对应的constructor,所以任何对象最终都可以找到其构造函数(null如果当成对象的话,将null除外)。如下:
5. 总结
总结一下:
- 我们需要牢记两点:①
__proto__
和constructor
属性是对象所独有的;②prototype
属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__
和constructor
属性。 __proto__
属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__
属性所指向的那个对象(父对象)里找,一直找,直到__proto__
属性的终点null,再往上找就相当于在null上取值,会报错。通过__proto__
属性将对象连接起来的这条链路即我们所谓的原型链。prototype
属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,即f1.__proto__ === Foo.prototype
。constructor
属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function。
本文就此结束了,希望对那些对JS中的
prototype
、__proto__
与constructor
属性有困惑的同学有所帮助。最后,感谢这两篇博文,本文中的部分内容参考自这两篇博文:
若对你有帮助,可以支持一下作者创作更多好文章哦,一分钱也是爱~
- 我们需要牢记两点:①
-
Design Pattern - Prototype(C#)
2019-02-02 17:29:01分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!... Definition Specify the kind of objects to create using a prototypical instance, and create new objects by ...分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请点击http://www.captainbed.net
Definition
Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype.
Participants
The classes and/or objects participating in this pattern are:
- Prototype (ColorPrototype)
- Declares an interface for cloning itself
- ConcretePrototype (Color)
- Implements an operation for cloning itself
- Client (ColorManager)
- Creates a new object by asking a prototype to clone itself
Sample Code in C#
This structural code demonstrates the Prototype pattern in which new objects are created by copying pre-existing objects (prototypes) of the same class.
/* * Structural Prototype Design Pattern. */ namespace Prototype.Sample { using System; /// <summary> /// Startup class for Structural Prototype Design Pattern. /// </summary> internal static class Program { #region Methods /// <summary> /// Entry point into console application. /// </summary> private static void Main() { // Create two instances and clone each. var p1 = new ConcretePrototype1("I"); var c1 = (ConcretePrototype1) p1.Clone(); Console.WriteLine("Cloned: {0}", c1.Id); var p2 = new ConcretePrototype2("II"); var c2 = (ConcretePrototype2) p2.Clone(); Console.WriteLine("Cloned: {0}", c2.Id); } #endregion } /// <summary> /// The 'Prototype' abstract class. /// </summary> internal abstract class Prototype { #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Prototype"/> class. /// </summary> /// <param name="id"> /// The id. /// </param> protected Prototype(string id) { Id = id; } #endregion #region Public Properties /// <summary> /// Gets the id. /// </summary> public string Id { get; } #endregion #region Public Methods and Operators /// <summary> /// Clone. /// </summary> /// <returns> /// The <see cref="Prototype"/>. /// </returns> public abstract Prototype Clone(); #endregion } /// <summary> /// A 'ConcretePrototype' class. /// </summary> internal class ConcretePrototype1 : Prototype { #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="ConcretePrototype1"/> class. /// </summary> /// <param name="id"> /// The id. /// </param> public ConcretePrototype1(string id) : base(id) { } #endregion #region Public Methods and Operators /// <summary> /// Clone. /// Returns a shallow copy. /// </summary> /// <returns> /// The <see cref="Prototype"/>. /// </returns> public override Prototype Clone() { return (Prototype) MemberwiseClone(); } #endregion } /// <summary> /// A 'ConcretePrototype' class. /// </summary> internal class ConcretePrototype2 : Prototype { #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="ConcretePrototype2"/> class. /// </summary> /// <param name="id"> /// The id. /// </param> public ConcretePrototype2(string id) : base(id) { } #endregion #region Public Methods and Operators /// <summary> /// Clone. /// Returns a shallow copy. /// </summary> /// <returns> /// The <see cref="Prototype"/>. /// </returns> public override Prototype Clone() { return (Prototype) MemberwiseClone(); } #endregion } } // Output: /* Cloned: I Cloned: II */
This real-world code demonstrates the Prototype pattern in which new Color objects are created by copying pre-existing, user-defined Colors of the same type.
/* * Real-World Prototype Design Pattern. */ namespace Prototype.RealWorld { using System; using System.Collections.Generic; /// <summary> /// Startup class for Real-World Prototype Design Pattern. /// </summary> internal static class Program { #region Methods /// <summary> /// Entry point into console application. /// </summary> private static void Main() { var colorManager = new ColorManager { ["red"] = new Color(255, 0, 0), ["green"] = new Color(0, 255, 0), ["blue"] = new Color(0, 0, 255), ["angry"] = new Color(255, 54, 0), ["peace"] = new Color(128, 211, 128), ["flame"] = new Color(211, 34, 20) }; // User clones selected colors. var color1 = colorManager["red"].Clone() as Color; var color2 = colorManager["peace"].Clone() as Color; var color3 = colorManager["flame"].Clone() as Color; } #endregion } /// <summary> /// The 'Prototype' abstract class. /// </summary> internal abstract class Prototype { #region Public Methods and Operators /// <summary> /// Clone. /// </summary> /// <returns> /// The <see cref="Prototype"/>. /// </returns> public abstract Prototype Clone(); #endregion } /// <summary> /// The 'ConcretePrototype' class. /// </summary> internal class Color : Prototype { #region Fields /// <summary> /// The blue. /// </summary> private readonly int _blue; /// <summary> /// The green. /// </summary> private readonly int _green; /// <summary> /// The red. /// </summary> private readonly int _red; #endregion #region Constructors and Destructors /// <summary> /// Initializes a new instance of the <see cref="Color"/> class. /// </summary> /// <param name="red"> /// The red. /// </param> /// <param name="green"> /// The green. /// </param> /// <param name="blue"> /// The blue. /// </param> public Color(int red, int green, int blue) { _red = red; _green = green; _blue = blue; } #endregion #region Public Methods and Operators /// <summary> /// Clone. /// </summary> /// <returns> /// The <see cref="Prototype"/>. /// </returns> public override Prototype Clone() { Console.WriteLine("Cloning color RGB: {0,3},{1,3},{2,3}", _red, _green, _blue); return MemberwiseClone() as Prototype; } #endregion } /// <summary> /// Prototype manager. /// </summary> internal class ColorManager { #region Fields /// <summary> /// The colors. /// </summary> private readonly Dictionary<string, Prototype> _colors = new Dictionary<string, Prototype>(); #endregion #region Public Indexers /// <summary> /// This. /// </summary> /// <param name="key"> /// The key. /// </param> /// <returns> /// The <see cref="Prototype"/>. /// </returns> public Prototype this[string key] { get { return _colors[key]; } set { _colors.Add(key, value); } } #endregion } } // Output: /* Cloning color RGB: 255, 0, 0 Cloning color RGB: 128,211,128 Cloning color RGB: 211, 34, 20 */
- Prototype (ColorPrototype)
-
Javascript Prototype And Prototype Chain
2018-01-28 22:45:58Javascript Prototype -
Prototype教程(prototype框架和js中的prototype对象的区别)
2020-10-28 14:53:40http://prototypejs.org/learn/ http://api.prototypejs.org/ https://github.com/prototypejs/prototype -
Javascript function prototype and object prototype
2018-08-10 08:27:22Object.setPrototypeOf...Object.setPrototypeOf(object, prototype) could change the prototype of the object directly, but only IE 10 and below do not support the method Function.prototype Every funct... -
Prototype模式
2017-05-04 23:58:55Prototype模式Prototype模式(原型模式)是为了让对象自我复制的功能,即可以通过已有对象来创建新对象.Prototype提供了在一个现有对象创建新对象的接口Clone,它的实现和具体语言相关,在C++中通过拷贝构造函数实现... -
prototype.js教程及prototype中文手册
2018-06-28 17:08:50http://topmanopensource.iteye.com/blog/382425收集了网上的prototype.js教程及prototype中文手册,方便大家使用prototype.js 1.4中文教程doc格式http://www.dayanmei.com/upload/prototype1.4.docprototype.js 1.4... -
js prototype
2015-12-09 10:38:47function定义的对象有一个prototype属性,prototype属性又指向了一个prototype对象,注意prototype属性与prototype对象是两个不同的东西,要注意区别。在prototype对象中又有一个constructor属性,这个constructor... -
理解 prototype
2017-02-15 23:21:31不用等咱们去试验,javascript自己就先做了表率,人家就默认的给函数一个属性——prototype。对,每个函数都有一个属性叫做prototype。这个prototype的属性值是一个对象(属性的集合,再次强调!),默认的只有一个... -
JS中prototype介绍
2019-06-19 20:41:22用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性, 可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级... -
Prototype 模式
2015-03-23 10:03:06Prototype 模式提供了一个通过已存在对象进行新对象创建的接口(Clone) ,Clone()实现和具体的实现语言相关,在 C++中我们将通过拷贝构造函数实现之。 ////////////////Prototype.h/////// #ifndef _... -
prototype javascript
2014-03-04 15:39:21prototype javascript prototype可以方便你想对象中添加属性和方法 -
Object.prototype
2019-08-16 17:20:49Object.prototype Object.prototype 属性表示 Object 的原型对象。 Object.prototype 属性 属性特性 writable true enumerable false configurable true 描述 几乎所有的 JavaScript 对象都是 Object ... -
子类的prototype=父类的prototype错误点
2017-09-13 20:21:01Dog.prototype=Animal.prototype;//引用类型赋值,赋的是引用(即内存地址) 引用同一个内存地址 指向同一个对象,可通过任一引用修改该prototype对象 console.log(Dog.prototype.constructor); //Animal Dog.... -
prototype简介
2015-03-26 15:40:52每一个构造函数都有一个属性叫做原型(prototype,下面都不再翻译,使用其原文)。这个属性非常有用:为一个特定类声明通用的变量或者函数。 prototype的定义 你不需要显式地声明一个prototype属性,因为在每一个构造... -
JavaScript prototype
2015-02-14 10:06:01用过JavaScript的同学们肯定都对prototype如雷贯耳,但是这究竟是个什么东西却让初学者莫衷一是,只知道函数都会有一个prototype属性,可以为其添加函数供实例访问,其它的就不清楚了,最近看了一些 JavaScript高级...
-
微信支付2021系列之扫码支付一学就会java版
-
30+岁、没转管理、加不动班,我的竞争力从哪里来?
-
搭建自己的 SSR
-
Unity游戏开发之数字华容道
-
本地navicat设置通过linux跳板机访问数据库
-
redis-6.0.10.sh
-
基于机器学习的P2P网络流问题的研究
-
如何搭建个人博客网站
-
Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错).docx
-
室内可见光通信中接收光功率均匀性优化方法
-
仿众人帮蚂蚁帮扶牛帮悬赏任务平台源码 短视频抖音点赞发布源码.zip
-
转行做IT-第9章 常用类-Scanner、Random等
-
tianqiyubao.py
-
Spark:常用transformation 转换操作 及action 行动操作
-
JAVAEE主流框架之Spring框架实战开发教程(源码+讲义)
-
async和await 实现同步请求
-
云计算基础-Linux系统管理员
-
MySQL 中文完全参考手册
-
Java Web开发之Java语言基础
-
element ui select选中问题