个人JS体系整理(一)

一. 原型

JS每声明一个Function,都有Prototype原型,Prototype原型是函数的一个默认属性,在函数的创建过程中由JS编译器自动添加,也就是说每当生产一个Function对象的时候,就有一个原型Prototype。按照Javascript的说法,Function定义的Object(对象),是一个很特殊的对象,这个使用Function定义的对象与使用New操作符生成的对象之间有一个重要的区别,这个区别就是Function定义的对象有一个Prototype属性,称之为函数对象,而使用New生成的对象就没有这个Prototype属性,称之为普通对象。

图1.1

如上图所示,第一个Console结果为Undifined,证明了New的对象是没有原型Prototype的;第二个Console结果为增加原型Name以后的原函数,证明了只有函数对象才具有原型Prototype;第三个Console的结果为’hangzhou’,证明了通过原型增加的属性是存在的;第四个Console的结果为’hangzhou’,证明了通过原型增加的属性,是可以在该对象所具有的方法里面进行调用获取到的。

图1.2

如上图所示,如果原函数本身的属性或方法与利用原型增加的属性或方法重名时,默认调用的依旧是该函数对象本身的属性或者方法,即函数本身的属性或者方法的优先级高于原型的属性或者方法。

二. 原型链

官方对于原型链的解释是原型链是实现继承的主要方法,其基本思想是利用原型让一个引用类型继承另一个应用类型的属性和方法。通俗一些理解,每个对象都会在其内部初始化一个属性,就是Prototype(原型),当我们访问一个对象的属性时, 如果这个对象内部不存在这个属性,那么他就会去Prototype里找这个属性,这个Prototype又会有自己的Prototype, 于是就这样一直找下去,也就是我们平时所说的原型链的概念。

提到原型链,就要提一个词_proto_,它是基本对象的属性,相对应的就是每一个函数对象都有一个自己的Prototype原型,由于函数对象也属于基本对象,所以函数对象也有_proto_,每当去定义一个Prototype的时候,就相当于把该实例的__proto__指向一个结构体,那么这个被指向结构体就称为该实例的原型。

图2.1

当你定义一个函数对象的时候,其内部就有这样一个链表关系。声明foo对象,自带了_proto_的属性,而这个属性指向了Prototype,从而实现对象的扩展(例如继承等操作)。

图2.2

如上图所示,一个没有继承操作的函数的_proto_都会指向Object.Prototype,而Object.Prototype都会指向Null。

图2.3

如上图所示,定义两个函数对象A和B,每个对象分别具有一个属性和方法。他们两个函数对象的区别是B继承了A,而继承是通过创建A的实例,并将实例赋给B.Prototype实现的。实现的本质是重写原型的对象,代之以一个新的类型的实例。换句话说,原来存在于A的实例中的所有属性和方法,现在也存在于B.Prototype中了。在确立了继承关系之后,我们给B.Prototype添加了一个方法,这样就继承A的属性和方法的基础上又添加了一个新方法。然后继续创建一个B的实例C,这样C就具有了B的全部方法和属性,所以Console的结果分别是111与222。

前端面试拓展:

图2.4

p没有b属性,会一直通过__proto__向上查找,最后当查找到Object.Prototype时找到,最后打印出b,向上查找过程中,得到的是Object.Prototype,而不是Function.Prototype,所以找不到a属性,所以结果为Undefined,这就是原型链,通过__proto__向上进行查找,最终到Null结束。最终逻辑即下图:

图2.5

三. 对象简介

对象的定义:对象是Javascript的一个基本数据类型,是一种复合值,它将很多值(原始值或者其他对象)聚合在一起,可通过名字访问这些值。即属性的无序集合。

第一:Javascript对象是基本数据类型之一,是复合类型;

第二:Javascript中几乎所有事物都是做对象;

第三:Javascript的对象是拥有属性和方法的数据;

第四:Javascript 中的对象可以简单理解成"名称:值"对(name:value)。名称(name):"名称"部分是一个 Javascript 字符串

图3.1

第一种创建对象方式如上图所示,直接创建一个对象,或者叫做对象直接量、字面量。

图3.2

第二种创建对象方式如上图所示,通过new.object创建对象,该方法只能创建系统自带的对象,如:new Object(), Array(), Number(),Boolean(), Date()...

图3.3

第三种创建对象方式如上图所示,通过构造函数的形式创建对象,构造函数一般使用驼峰式命名方法命名。

图3.4

第四种创建对象方式如上图所示,创建一个继承该原型的实例对象。

四. 数据类型和内存图

栈:原始数据类型(Undefined,Null,Boolean,Number、String)。

堆:引用数据类型(对象、数组和函数)。

两种类型的区别是:存储位置不同。原始数据类型是直接存储在栈(stack)中的简单数据段,占据空间小、大小固定,属于被频繁使用数据,所以放入栈中存储;引用数据类型是存储在堆(heap)中的对象,占据空间大、大小不固定。如果存储在栈中,将会影响程序运行的性能;引用数据类型在栈中存储了指针,该指针指向堆中该实体的起始地址。当解释器寻找引用值时,会首先检索其在栈中的地址,取得地址后从堆中获得实体。

图4.1

五. 作用域

变量的作用域无非就是两种:全局变量和局部变量。

全局作用域:最外层函数定义的变量拥有全局作用域,即对任何内部函数来说,都是可以访问的。

局部作用域:和全局作用域相反,局部作用域一般只在固定的代码片段内可访问到,而对于函数外部是无法访问的,最常见的例如函数内部。需要注意的是,函数内部声明变量的时候,一定要使用var或者let命令。如果不用的话,你实际上声明了一个全局变量!

图5.1

只要函数内定义了一个局部变量,函数在解析的时候都会将这个变量“提前声明”。另外Javascript并没有所谓的块级作用域,Javascript的作用域是相对函数而言的,可以称为函数作用域:

全局函数无法查看局部函数的内部细节,但局部函数可以查看其上层的函数细节,直至全局细节。当需要从局部函数查找某一属性或方法时,如果当前作用域没有找到,就会上溯到上层作用域查找,直至全局函数。

本文参考链接:

1、https://www.cnblogs.com/libin-1/p/5911190.html

2、https://www.cnblogs.com/foodoir/p/5971686.html

3、https://github.com/markyun/My-blog/tree/master/Front-end-Developer-Questions/Questions-and-Answers

个人JS体系完善(一)的更多相关文章

  1. 个人JS体系整理(三)

    一. 严格模式 JavaScript 严格模式(strict mode)即在严格的条件下运行.首先声明,严格模式是ES5中提出来的,准确来说就是一句指令Use strict,它的目的是指定代码在严格条 ...

  2. 个人JS体系整理(二)

    一. eval eval()函数计算JavaScript字符串,并把它作为脚本代码来执行.如果参数是一个表达式,eval()函数将执行表达式.如果参数是Javascript语句,eval()将执行Ja ...

  3. 我为什么选择采用node.js来做新一代的EasyDarwin RTSP开源流媒体服务器

    在去年我们还未开始开发基于node.js的新版本EasyDarwin RTSP开源流媒体服务器的时候,我写了一篇博客<对EasyDarwin开源项目后续发展的思考:站在巨人的肩膀上再跳上另一个更 ...

  4. h5 录音 自动生成proto Js语句 UglifyJS-- 对你的js做了什么 【原码笔记】-- protobuf.js 与 Long.js 【微信开发】-- 发送模板消息 能编程与会编程 vue2入坑随记(二) -- 自定义动态组件 微信上传图片

    得益于前辈的分享,做了一个h5录音的demo.效果图如下: 点击开始录音会先弹出确认框: 首次确认允许后,再次录音不需要再确认,但如果用户点击禁止,则无法录音: 点击发送 将录音内容发送到对话框中.点 ...

  5. Node.js入门:包结构

        JavaScript缺少包结构.CommonJS致力于改变这种现状,于是定义了包的结构规范(http://wiki.commonjs.org/wiki/Packages/1.0 ).而NPM的 ...

  6. RPG JS:免费开源的跨平台RPG游戏引擎

    RPG JS是一个2D RPG游戏制作引擎,目前版本基于Ease|JS游戏引擎,基于Canvas Engine的新版本即将发布. RPG JS是免费且开源的. RPG JS有着完善的文档支持. RPG ...

  7. Sea.js提供简单、极致的模块化开发体验

    为什么使用 Sea.js ? Sea.js 追求简单.自然的代码书写和组织方式,具有以下核心特性: 简单友好的模块定义规范:Sea.js 遵循 CMD 规范,可以像 Node.js 一般书写模块代码. ...

  8. 从面向对象的角度重新认识JS世界

    一. 背景  距离上一篇JS文章已经20天,经重新总结发现,上一篇概况的有点浅显,适合初学js的入门了解,但对于已经学习js一段时间的人,或者是想系统的了解JS体系,接下来的文章可能会更有帮助. 该系 ...

  9. eclipse 修改js文件无法编译到项目中

    1.场景重现 在今天修改js文件完善功能时,发现在eclipse中修改了文件后,刷新页面功能无法同步: 2.分析原因 查看编译路径,文件没有修改: 2.1 可能是缓存问题: 2.2 项目未编译: 3. ...

随机推荐

  1. jenkins插件

    构建maven项目:Maven Release Plug-in Plug-in

  2. 检测一个DLL文件是x64还是x86

    对于一个DLL,我们如何判定其是32位的还是64位的,或者是any cpu的platform? Visual Studio提供了一个很好的工具:corflags,这个是内嵌到Developer Com ...

  3. MyBatis的高级映射之多对一

    使用传统方式的形式 使用MyBatis的方式 这样会产生两条语句 使用ResultMap的方式,对结果进行映射和转换,自己控制 两条语句变成一条语句,然后进行映射,这时Student类中包含一个 Cl ...

  4. Python编码(encode)和解码(Decode)常见的两个错误

    项目地址:https://git.io/pytips 0x07 和 0x08 分别介绍了 Python 中的字符串类型(str)和字节类型(byte),以及 Python 编码中最常见也是最顽固的两个 ...

  5. 0ctf签到题

    签到题: 题目提示: flag在IRC聊天室里 开启weechat ┌─[root@sch01ar]─[~] └──╼ #weechat 创建服务器 /server add freenode8001 ...

  6. 第十七章 Velocity优化实践(待续)

    现实存在的问题 优化的理论基础 一个高效的模版引擎实现思路 优化成果 其他优化手段

  7. CentOS 7.2 部署Rsync + Lsyncd服务实现文件实时同步/备份 (二)

    发送端配置: 一.配置密钥 1. 主/从服务器之间启用基于密钥的身份验证.登录发送端服务器并用 " ssh-keygen " 命令生成公共或私有的密钥. 2. 使用 " ...

  8. 正则表达式 notes

    nfs 网络文件系统 存储类型:块存储,对象存储,文件存储 nfs属于文件存储 crond 分钟小时日月周 命令:绝对路径 命令是由crond解释 /bin/bash a.sh */2 * * * * ...

  9. bitcode编译错误

    xcode编译引用的静态库可能会出现编译错误: does not contain bitcode. You must rebuild it with bitcode enabled (Xcode se ...

  10. DAY13-前端之JavaScript

    JavaScript概述 JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中),后将其改名ScriptEase(客 ...