草庐IT

js原型(重点理解)

博睚 2023-03-28 原文

  网络上很多关于JS原型的理解,写了很多,我也看了很多,但总是云里雾里,很多文章一上来就说Object是一切对象的根对象,这句话非常误导人的思维,后来自己在控制台,自己分析出来了比较好理解的方式,下面我来详细屡屡关于js原型的正确理解方式。

主要是理解js中的对象,函数,函数对象,函数实例

首先我们来聊聊这四个概念

对象

对象是什么呢,对象就是使用json格式表示的代码块,用这种方式表示js中的对象如下:

{ "name":"runoob", "alexa":10000, "site":null }

JSON 对象使用在大括号 {...} 中书写。

对象可以包含多个 key/value(键/值)对。

key 必须是字符串,value 可以是合法的 JSON 数据类型(字符串, 数字, 对象, 数组, 布尔值或 null)。

key value 中使用冒号 : 分割。

每个 key/value 对使用逗号 , 分割。

函数

函数就是function关键字定义的一段代码块,就是自己定义的看得到的那一块代码,称之为函数,js中内置了一些基础函数比如(Object,Date等等),其实质就是带有构造器constructor的对象,js中可以将一个带有构造器constructor的对象表示为为函数,函数是json对象的变体表现形式

(注意:永远不要忘记js中的对象就是json格式的代码块,函数是这个json格式对象的变体)

如下为Object函数的原型Object.prototype,也是一个json键值对对象:

{
{constructor: ƒ, __defineGetter__: ƒ, __defineSetter__: ƒ, hasOwnProperty: ƒ, __lookupGetter__: ƒ, …}
constructor: ƒ Object()
hasOwnProperty: ƒ hasOwnProperty()
isPrototypeOf: ƒ isPrototypeOf()
propertyIsEnumerable: ƒ propertyIsEnumerable()
toLocaleString: ƒ toLocaleString()
toString: ƒ toString()
valueOf: ƒ valueOf()
__defineGetter__: ƒ __defineGetter__()
__defineSetter__: ƒ __defineSetter__()
__lookupGetter__: ƒ __lookupGetter__()
__lookupSetter__: ƒ __lookupSetter__()
__proto__: null
get __proto__: ƒ __proto__()
set __proto__: ƒ __proto__()
}

函数有两种作用:一是执行特定功能的代码块,二是构造对象

函数对象

函数对象就是函数的原型,要与函数本身区分开来,比如Date函数的函数对象为Date.prototype,后面我在说特定函数对象的时候都会加上.prototype,因为这个函数原型才真正表述为函数对象

函数实例

函数实例就是通过函数构造器创造的对象,一个函数可以构造出多个不同的但相似的函数实例对象,例如:

function myFunction(a, b) {
return a * b;
}
var x = myFunction (3, 3);
var y = myFunction (4, 3); 
从控制台可以分析出函数实例x,y是函数对象Number的子对象,其_proto_属性指向的是Number.prototype,而不是我们通常认为的x,y为myFunction.prototype的子对象
当然这里也不能绝对,因为函数实例的父对象是不确定的,如下实例
function myFunction2()
{
    console.log('nihao');
}
var z=myFunction2();
var m= new myFunction2();

对象与函数的基本认识

对象的_proto_属性指向的是当前对象的父对象

只有函数有constructorprototype属性

函数中的prototype属性字面意思是原型,指的是当前函数的对象原型,函数只是这个对象原型的变体形式

按照我的理解是这样的,创造js这门语言的时候是定义这是一个面向对象的语言,所有首要任务就是指定对象的格式,就有json对象表示法,然后就是构造执行代码块的结构,即函数 表示法,再就是对象与函数的关联,想象js一切皆为对象,函数的定义本身也是在构造对象,即定义的函数可以表示为带有constructor的对象,这就是函数原型,然后通过函数定义法着手定义根对象就是Object.prototype以及其他的一些内置对象

关于Object与Object.prototype的理解

js中所有的对象继承自Object.prototype这个原型对象,这个原型对象用函数表示就是Object,所以很多文章都Object为根对象,这也没错,因为Object表示的就是根,只是这个根是以函数的形式表示出来,而这个函数的原型就是真正的根对象,即Object.prototype:{…}(这个里我省略了对象中的内容),这个Object.prototype派生了函数对象和普通对象(如Math,JSON等,因为这些对象中没有构造器,可自行在控制台查看),永远不要忘记Object这个函数是通过函数构造器构造出来的函数模样的一块代码,其本质是Object.prototype这个原型,这才是根对象。

Object是一个函数,其属性指针_proto_指向的是函数根对象ƒ () { [native code] },而函数根对象的_proto_则指向Object.prototype,应该有这样的关系:Object._proto_._proto_===Object.prototype;

不过js在_proto_属性后面就不让指针跟踪了,不过我们也可以通过变通的方式来查到,从这里可以看出来:

Object._proto_===Function.prototype  //返回值都为ƒ () { [native code] };

Function.prototype.__proto__=== Object.prototype //返回值为true

Object.prototype._proto_则为null。

以上可以看出,JS中的一切对象都是Object.prototype的子对象,函数根对象ƒ () { [native code] }是Object.prototype的子对象,函数是函数根对象ƒ () { [native code] }的子对象,Object函数也不列外。(注意Function函数是函数根对象的显式函数声明,代表着函数根对象,函数根对象ƒ () { [native code] }是在js运行时已经定义好了的对象)

很多文章都说所有函数都派生自这个Function对象,准确的来说应该是所有函数对象派生自Function.prototype,而Function.prototype就是ƒ () { [native code] },那么问题来了,Object也是函数,那它也是派生自这个对象吗,是的,前面我已经说了,Object在js中写的时候是个函数不是根对象,而这个函数的原型Object.prototype才是真正的根对象,其形式为:这个在函数概念那里已经表述出来了,可以返回去巩固巩固。

关于JS Function函数理解

JS内置对象中,Function函数(注意我这里表述的是函数而不是函数对象,因为Function的函数对象准确来说应该为Function.prototype)较为特殊,这个理解起来就比较困难,因为Function.prototype===Function._proto_,很多人很疑惑为什么会等于,其实这里还缺少了一个重要的信息,那就是ƒ () { [native code] },这个才是根函数对象,这个根函数对象的父对象指向的是Object.prototype这个根对象,这是在js运行时中就已经定义好的,而Function.prototype这个函数对象原型恰好就是这个根函数对象ƒ () { [native code] },而这个Function._proto_这个属性指针恰好就指向了ƒ () { [native code] },这都是在js运行时中定义好了, Function这个函数的作用就是为了创建函数实例的另外一种方法,其父类对象还是Object.Prototype,只是显式定义函数的多一种选择。

 

好了,文章结束,希望对各位有所帮助!

有关js原型(重点理解)的更多相关文章

  1. CAN协议的学习与理解 - 2

    最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总

  2. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  3. ruby - 易于初学者理解的 Ruby 库 - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭3年前。Improvethisquestion我正处于学习Ruby的阶段,我想查看一些小型库的源代码以了解它们是如何构建的。我不知道什么是小型图书馆,但希望SO能推荐一些易于理解的图书馆来学习。因此,如果有人知道一两个非常小的库,这是新手Rubyists学习的好例子,请推荐!我想使用Manveru'sInnatelib,因为它试图保持在2000LOC以下,但我还不熟悉其中经常使用的Ruby速记。也许大约100-5

  4. ruby - 无法理解 `puts{}.class` 和 `puts({}.class)` 之间的区别 - 2

    由于匿名block和散列block看起来大致相同。我正在玩它。我做了一些严肃的观察,如下所示:{}.class#=>Hash好的,这很酷。空block被视为Hash。print{}.class#=>NilClassputs{}.class#=>NilClass为什么上面的代码和NilClass一样,下面的代码又显示了Hash?puts({}.class)#Hash#=>nilprint({}.class)#Hash=>nil谁能帮我理解上面发生了什么?我完全不同意@Lindydancer的观点你如何解释下面几行:print{}.class#NilClassprint[].class#A

  5. ruby - 如何理解 Ruby 中的发送者和接收者? - 2

    我很难理解Ruby中sender和receiver的实际含义。它们一般是什么意思?到目前为止,我只是将它们理解为方法调用和获取其返回值的调用。但是,我知道我的理解还远远不够。谁能给我一个Ruby中发送者和接收者的具体解释? 最佳答案 面向对象中的一个核心概念是消息传递和早期概念化,这在很大程度上借鉴了计算的Actor模型。艾伦·凯(AlanKay)创造了面向对象一词并发明了最早的OO语言之一SmallTalk,他拥有voicedregretatusingatermwhichputthefocusonobjectsinsteadofo

  6. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  7. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

    rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

  8. node.js - 如何在 Travis CI 上的一个项目中运行 Node.js 和 Ruby 测试 - 2

    我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每

  9. jquery - 在 Rails 中从原型(prototype)切换到 jquery,助手呢? - 2

    我目前从prototype切换到jquery主要是为了支持简单的ajax文件上传。我使用:https://github.com/indirect/jquery-rails95%的javascript代码是由railshelper编写的,例如:-remote_function-render:updatedo|page|-page.replace_html'id',:partial=>'content'-page['form']['name']=something-page.visual_effect:highlight,'head_success'...我知道我必须为Jquery重写5%

  10. node.js - 从未编写过任何自动化测试,我应该如何开始行为驱动开发? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。多年来,我一直在使用多种语言进行编程,并且认为自己总体上相当擅长。但是,我从未编写过任何自动化测试:没有单元测试,没有TDD,没有BDD,什么都没有。我已经尝试开始为我的项目编写适当的测试套件。我可以看到在进行任何更改后能够自动测试项目中所有代码的理论值(value)。我可以看到像RSpec和Mocha这样的测试框架应该如何使设置和运行所述测试变得相当容易

随机推荐