Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >javascript高级程序设计(4-5)章笔记

javascript高级程序设计(4-5)章笔记

作者头像
空空云
发布于 2018-09-27 03:58:36
发布于 2018-09-27 03:58:36
47400
代码可运行
举报
文章被收录于专栏:大前端_Web大前端_Web
运行总次数:0
代码可运行

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://cloud.tencent.com/developer/article/1347593

之前看过一遍js高程,有些基础还不牢固,单身狗周末又没地方去,开始重新撸一遍JS高程,写点笔记,防止以后忘了!

4.变量 作用域和内存问题

ECMAScript中所有函数的参数都是按值传递的(不区分基本类型和引用类型)

引用类型是按引用传递的,函数的参数全部按值传递,有点蒙逼,看代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//基本类型值没问题
function add(num) {
    num += 10;
    return num;
}
var count =20 ;
console.log(add(count));//30

//看不出来
/*高程给的解释:在这个函数内部,obj和person引用的是同一个对象。
 *换句话说,即使这个对象是按值传递的,obj也会按引用来方位同一个对象*/
function setName (obj) {
    obj.name = 'kenny';
}
var person = new Object();
setName(person); // 'kenny'

//函数内部重新定义obj对象
function setName (obj) {
    obj.name = 'kenny';
    obj = new Object();
    obj.name = 'gaga';
}
var person = new Object();
setName(person); // 'kenny'

高程:函数内部重写obj时,这个变量引用的就是一个局部对象,而局部对象会在函数执行完毕后立即被销毁。个人理解就是函数作用域,外部环境无法访问内部的私有变量 ,包括arguments,其实相当于参数被重新定义成对象,但是外部的对象未变化,所以是按值传递,即对象的深度复制。

执行环境及作用域

1.每个执行环境都有一个与之关联的变量对象(variable object),环境中定义的所有变量和函数都保存在这个对象中, 虽然无法访问此对象,但js解析器会在后台使用它,(chorme 控制台js断点的时候,当前作用定义的变量和函数都能在当前执行环境查看,soga)。

2.每个函数都有自己的执行环境 ,当执行流进入一个函数时,函数的环境就会给推入一个环境栈中(后进先出)。当代码在一个环境中执行时,会创建变量对象的一个作用域链(scope chain)。每个环境多都可以向上搜索作用域链,以查询变量和函数名,(访问局部变量比访问全局变量要快,javascript引擎在优化标识符查村做的很ok,可以忽略不计)。

垃圾收集

标记清除(大部分浏览器以此来实现)和引用计数

管理内存

一旦数据不再引用,最好通过将其设置为null来释放引用——俗称解除引用。适用于大多数全局变量和全局对象的属性,局部变量会在他们离开执行环境时自动解除引用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//执行完毕,person函数内的对象会自动销毁,
function person (name) {
    var localPerson = new Object();
    localPerson.name = name;
    return localPerson;
}
var gloablPerson = person('kenny');
gloablPerson = null;

解除值的引用不会马上自动回收该值所占用的内存,是让值脱离执行环境,以便垃圾收集器下次运行将其回收。

小结

  • 基本类型值占据固定大小的空间,因此保存在栈中,引用类型的值是对象,保存在堆内存中。
  • 从一个变量向另一个变量复制引用类型的值,复制的其实是指针,因此两个变量指向同一个对象。
  • 每次进入一个新的执行环境,都会创建一个用于搜索变量和函数的作用域链

5.引用类型

对象字面量

通过对象字面量定义对象时,实际上不会调用Object构造函数(Firefox2及更早版本会),即不会调用new实例化对象。【ES3之前的正则字面量存在bug,循环test某个字符串,一次为真一次为假,ES5已修正(P105页)】

安全的类型检测

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var isArray = value instanceof Array;

以上代码要返回true就,value必须是数组,而且还必须与Array构造函数在同个全局作用域中,(切记,Array是window的属性),如果value在另个frame定义的数组,那么以上代码就会返回false。

在任何值上调用Object原声的toString()方法,都会返回一个object NativeConstructorName格式的字符串,由于原生数组的构造函数与全局作用域无关,因此toString()就能保证返回一致的值。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
function isArray(value) {
    return Object.prototype.toString.call(value) === '[object Array]';
}
function isFunction(value) {
    return Object.prototype.toString.call(value) === '[object Function]';
}
function isRegExp(value) {
    return Object.prototype.toString.call(value) === '[object RegExp]';
}

在Web开发中能够区分原生与非原生javascript对象非常重要,这样才能确切知道某个对象到底有哪些功能,但是Object.prototype.toString()本身也能被重写。

Function类型

每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。由于函数是对象,函数名实际上也是一个指向函数对象的指针,不会与某个函数绑定。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//函数是对象,函数名是指针
function sum(num1, num2) {
    return num1 + num2;
}
console.log(sum(10,10)); //20
var anotherSum = sum; //使用不带圆括号的函数名是访问函数指针,而非调用函数
console.log(anotherSum(10,10)); //20
sum = null; //设置其他值也一样
console.log(anotherSum(10, 10))//20

so要访问函数的指针而不执行函数的话,必须去掉函数名后面的那对圆括号。

  • 函数声明与函数表达式

js解析器会率先读取函数声明(function declaration hosting),并使其在执行任何代码之前可用,至于函数表达式,则必须等到解析器执行到它所在的代码行,才会真正被解析执行。

  • 作为值的函数
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        function createComparisonFunction(propertyName) {

            return function(object1, object2){
                var value1 = object1[propertyName];
                var value2 = object2[propertyName];

                if (value1 < value2){
                    return -1;
                } else if (value1 > value2){
                    return 1;
                } else {
                    return 0;
                }
            };
        }

        var data = [{name: "Zachary", age: 28}, {name: "Nicholas", age: 29}];

        data.sort(createComparisonFunction("name"));
        alert(data[0].name);  //Nicholas

        data.sort(createComparisonFunction("age"));
        alert(data[0].name);  //Zachary     
  • 函数内部属性

函数内部有两个特殊对象:arguments和this,arguments.callee指向拥有arguments对象的函数(ES6已弃用)。

this引用的是函数据以执行的环境对象,即函数调用,蝴蝶书上讲过有四种调用模式

1.方法调用模式,this指向当前方法的对象;

2.函数调用模式,this被绑定到全局对象,客户端即window;

3.构造器调用模式,this被绑定到实例化的新对象上;

4.apply/call调用模式,第一个参数都是要被绑定给this,第二个参数apply是数组,call([thisObj[,arg1[, arg2[, ,.argN]]]])。

  • 函数属性和方法

每个函数都包含两个属性: length(函数希望接收的命名参数的个数) 和 prototype。

对于ECMAScript中的引用类型而言,prototype是保存她们所有实例方法的真正所在。在ES5中,prototype属性是不可枚举的,(非原生的prototype属性可枚举,即人为添加上去的,在google测试过)因此使用for-in无法发现。

ES5还定义了一个方法: bind()。这个方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。

基本包装类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var s1 = 'some text';
var s2 = s1.substring(2);

上述可以解析成三个步骤

1.创建String类型的一个实例;

2.在实例上调用指定的方法;

3.销毁这个实例

执行代码类似如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var s1 = new String('some text');
var s2 = s1.substring(2);
s1 = null;

引用类型与基本包装类型的主要区别就是对象的生存期。使用new操作符创建的引用类型实例,在执行流离开当前作用域之前都一直保存在内存中。而自动创建的基本包装类型,则只存在于一行代码的执行瞬间,然后理解被销毁。

小结

在所有代码执行之前,作用域中就已经存在两个内置对象:Global 和Math。在大多数ECMAScript视线中都不能直接访问Global对象;不过WEB浏览器实现了承担该角色的window对象。全局变量和函数都是Global对象的属性。Math对象提供了很多属性和方法,用于辅助完成复杂的数学计算。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016年04月24日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
夯实JS系列--变量、作用域和内存问题
在ECMAScript中,变量分为基本类型和引用类型两种。 基本类型就是存储简单的数据段。而引用类型指的是那些可能由多个值构成的对象。 在ECMAScript中,基本类型包括:Undefined、Null、Boolean、Number和String。 这些基本类型的对象都是按值访问的。所以js中我们可以直接操作他们。 但是引用类型如Object等,是按照引用来操作的。并非直接操作其值。 并且我们可以动态的为引用类型变量添加属性和方法。而基本类型则不可以。
Nealyang
2019/09/29
7510
javascript 基础_JavaScript高级编程
1.分类: -基本类型 -String:任意字符串 -Number:任意的数字 -boolean: true/false -undefined:未定义 -null:空
全栈程序员站长
2022/09/24
1.6K0
javascript 基础_JavaScript高级编程
《JavaScript高级程序设计(第四版)》学习笔记(四)第4章
对于引用值而言,复制值得操作可以理解为复制了内存的引用,两个变量指向的是同样一块内存空间
小丞同学
2021/08/16
5560
3《JavaScript高级程序设计》__ 语言基础(上)
大家好,我是HoMeTown,web领域有一本神书大家应该都有看过,这本书我看过两遍,但是每次看都是粗粗的略过一些重要的知识点,甚至一些面试过程中的问题,在这本书里都能找到答案。
HoMeTown
2022/10/26
6800
3《JavaScript高级程序设计》__ 语言基础(上)
JavaScript高级程序设计(读书笔记)(七)[通俗易懂]
本笔记汇总了作者认为“JavaScript高级程序设计”这本书的前七章知识重点,仅供参考。
全栈程序员站长
2022/09/24
6600
JavaScript高级程序设计(读书笔记)(七)[通俗易懂]
《JavaScript高级程序设计》读书笔记
script 脚本中不要嵌入出现"" 字符串,会被错误识别为结束标签。正确写法是:"<\/script>"。
心谭博客
2020/04/20
1.2K0
浅习一波JavaScript高级程序设计(第4版)p4
持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第4天,点击查看活动详情
掘金安东尼
2022/09/19
3600
浅习一波JavaScript高级程序设计(第4版)p4
js程序设计02——变量、作用域问题
首先,ECMAScript中的数据类型分为基本类型、引用类型,基本类型的访问操作是按值的。引用类型的值是保存在内存中的对象,操作对象时,实际上操作的是对象的引用,而非对象自身。“javascript高
用户1141560
2017/12/26
9870
js程序设计02——变量、作用域问题
《JavaScript高级程序设计》学习笔记(3)——变量、作用域和内存问题
欢迎关注本人的微信公众号“前端小填填”,专注前端技术的基础和项目开发的学习。 本节内容对应《JavaScript高级程序设计》的第四章内容。 1、函数:通过函数可以封装任意多条语句,而且可以在任何地方、任何时候调用执行。ECMAScript中的函数用function关键字来进行声明,后面跟一组参数以及函数体。不必指定是否有返回值。 function functionName(args0,args1,...argsN){ //statements }  2、函数的重载:为一个函数
mukekeheart
2018/02/28
8150
重读《JavaScript高级程序设计》
ECMAScript 函数不能像传统意义上那样实现重载。而在其他语言(如Java)中,可以为一个函数编写两个定义,只要这两个定义的签名(接受的参数类型和数量)不同即可[p66]。ECMAScript的类型是松散形的,没有签名,所以是没有重载的。
Jimmy_is_jimmy
2019/07/31
1.1K0
《JavaScript高级程序设计》学习笔记(5)——面向对象编程
 欢迎关注本人的微信公众号“前端小填填”,专注前端技术的基础和项目开发的学习。   本节内容对应《JavaScript高级程序设计》的第六章内容。 1、面向对象(Object-Oriented, OO)的语言有一个标志,那就是它们都有类的概念,而通过类可以创建任意多个具有相同属性和方法的对象。前面提到过,ECMAScript中没有类的概念,因此它的对象也与基于类的语言中的对象有所不同。 ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。”严格来讲,这就相当于说对象是一组没有
mukekeheart
2018/03/01
7400
《JavaScript高级程序设计》读书笔记
数据传送率的单位.意思是每秒钟多少千字节.比如20Kbit/s就是每秒钟20000个字节.一般上网、下载的速度用这个单位.adsl宽带上网下载速度大概为30-50Kbit/s.
用户3880999
2023/04/13
6720
《JavaScript高级程序设计》读书笔记
一篇文章带你了解JavaScript中的变量,作用域和内存问题
引用类型的值是保存在内存中的对象,JavaScript不允许直接操作对象的内存空间,实际上操作对象的引用而不是实际对象。
达达前端
2020/01/02
5170
JavaScript 高级程序设计(第 4 版)- 函数
函数实际上是对象。每个函数都是Function类型的实例,Function也有属性和方法。函数名就是指向函数对象的指针。 # 箭头函数 只有一个参数可以不用括号,只有没有参数、或多个参数的情况下,才需要使用括号 箭头函数可以不用大括号,会隐式返回箭头后面那行代码的值 箭头函数不能使用arguments、super和new.target,也不能作为构造函数 箭头函数没有prototype属性 # 函数名 函数名就是指向函数的指针 使用不带括号的函数名会访问函数指针,而不会执行函数 所有函数对象都会暴露一个只读
Cellinlab
2023/05/17
4020
JavaScript 高级程序设计(第 4 版)- 函数
JavaScript高级程序设计-性能整理(一)
当然,在把 HTMLElement 元素添加到 DOM 且执行到这段代码之前不会发送请求。默认情况下,以这种方式创建的<script>元素是以异步方式加载的,相当于添加了 async 属性。不过这样做可能会 有问题,因为所有浏览器都支持 createElement()方法,但不是所有浏览器都支持 async 属性。因此,如果要统一动态脚本的加载行为,可以明确将其设置为同步加载:
草帽lufei
2022/07/29
7110
Javascript基础回顾 之(二) 作用域
参数传递的问题   在Javascript中所有的参数传递都是按值传递的。也就是说把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。基本类型值的传递如同基本类型变量的复制一样,而引用类型值的传递,就如同引用类型变量的复制一样。   —— 《Javascript 高级程序设计》 第三版 function addTen(num) { num += 10; return num; } var count = 20; var result = addTen(count)
用户1153966
2018/03/14
7200
Javascript基础回顾 之(二) 作用域
《JavaScript高级程序设计》学习笔记(4)——引用类型
  欢迎关注本人的微信公众号“前端小填填”,专注前端技术的基础和项目开发的学习。   本节内容对应《JavaScript高级程序设计》的第五章内容。   在ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起,通常也被称为类,有时候也被成为对象定义,因为他们描述的是一类对象所具有的属性和方法。对象是某个特定引用类型的实例,新对象是使用new操作符后跟一个构造函数来创建的, var person = new Object() ; 创建了一个object对象。构造函数本身就是一个函数,只不
mukekeheart
2018/03/01
1.6K0
20道精选的面试题附答案,进来看看能答对多少(二)
以下题目,本人验证无误,查阅了相关资料,得出解析部分并做了相关总结,希望对正准备跳槽或找工作的你有帮助!
前端达人
2021/06/16
5530
原 四、变量、作用域和内存问题
作者:汪娇娇 时间:2017年11月5日 一、基本类型和引用类型的值 基本类型指的是简单的数据段,引用类型指那些可能由多个值构成的对象。 基本类型的值保存在变量中,所以是按值访问。 引用类型的值保存在内存中的对象,JavaScript不允许直接访问(操作)内存中的位置,为此,只能按引用访问。 1、动态的属性 创建一个变量并为该变量赋值,当这个值保存到变量中以后,对于引用类型的值,我们可以为其添加属性和方法,也可以改变和删除其属性和方法。 2、复制变量值 (1)基本类型 如果一个变量向另一个变量复制基本类型的
jojo
2018/05/03
7730
《javascript高级程序设计》核心知识总结
浮点数值的最高精度是17位小数,但在进行算术计算时精度远远不如整数。例如 0.1 + 0.2 === 0.300000000000004(大致这个意思,具体多少个零请实际计算) 所以永远不要测试某个特定的浮点数值
徐小夕
2019/10/08
2.4K0
推荐阅读
相关推荐
夯实JS系列--变量、作用域和内存问题
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验