个人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. Jet Brains家族XX方法

    声明:本文转载自 https://www.jianshu.com/p/f404994e2843 2018/11/23

  2. FPGA 竞争与冒险

    一,概念 在数字电路设计时,无论是组合.时序,还是FPGA电路中,都需要考虑竞争冒险现象(Race and Competition). 竞争:由于信号在传输和处理过程中经过不同的逻辑门.触发器或逻辑单 ...

  3. 解决 ASP.NET Chart 控件出错 为 ChartImg.axd 执行子请求时出错

        今天在做一个关于MVC的MSChart时,本以为很简单的一个东西,后面把数据什么的都绑定好后,满以为OK了,一运行就报错“ ASP.NET Chart 控件出错 为 ChartImg.axd ...

  4. (转)C#特性详解

    本文转载自:http://www.cnblogs.com/rohelm/archive/2012/04/19/2456088.html 特性提供功能强大的方法,用以将元数据或声明信息与代码(程序集.类 ...

  5. java继承实例基础

    总结:多态.重写.构造方法调用 package com.a; public class fsd { int a = 23; public fsd() { System.out.println(4444 ...

  6. 应用HTMLTestRunner整合测试报告

    为了便于测试脚本的维护,以及更多测试用例的管理,于是根据上次学习的HTMLTestRunner生成的测试报告,今天将对其进行整理.我们之前使用 TestSuite 只是在一个.py 文件里添加多个测试 ...

  7. 问题:不支持Dictionary;结果:在Web Service中傳送Dictionary

    在Web Service中傳送Dictionary 有個需求,想在Web Service中傳遞Dictionary<string, string>參數,例如: 排版顯示純文字 [WebMe ...

  8. 问题:PLS-00204: 函数或伪列 'EXISTS' 只能在 SQL 语句中使用;结果:PL/SQL中不能用exists函数?

    怎么写了一个语句带出这样的结果. 语句: if exists (select * from sysdatabases where name='omni') then 结果: ERROR 位于第 4 行 ...

  9. JS写一个简单的程序,判断年份是平年还是闰年

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. Java was started but returned exit code=13 问题解决

    我在安装完jdk后,也对环境进行了配置,且环境的配置是没有问题的.最后我下载了eclipse,然后打开之后就发现了以下图所示的错误: Java was started but returned exi ...