JS入门难点解析

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

1. JS的数据类型

JS变量的数据类型的值有两种:基本类型值和引用类型值。基本类型值指简单的数据段,而引用类型值指那些可能由多个值构成的对象。

基本类型值有以下五种:Undefined、Null、Boolean、Number和String。引用类型值即保存在内存中的对象。

var num1 = 1;
var str1 = '1';

1.1基本类型

var obj1 = {a: 1};

1.2引用类型

2. JS的变量复制

JS对基本类型的复制和引用类型的复制并不相同。基本类型值的复制实际上将变量和其存储的内容重新复制了一份,而引用类型的复制只是将其保存的指针复制了一份,实际存储对象的堆并没有复制。

var num1 = 6;
var num2 = num1;

2.1基本类型复制

var obj1 = {a: 1};
var obj2 = obj1;

2.2引用类型复制

3. JS的参数传递是按值传参

JS的参数是按值传递,即将函数外部的值复制给函数内部的参数,其复制过程如前所述。那么对内部变量值的改变是否会影响外部变量呢,这里我们用具体的例子来分析一下。

function addTen(num) {
    num += 10;
    return num; 
}
var count = 20;
var result = addTen(count); 
alert(count); //20 没有改变   
alert(result); //30

我们可以看到,基本类型变量的传参对原变量并无影响,这一点大家也容易理解。可是对引用类型的传参呢?

// eg3.1
function setName(obj) {
    obj.name = "Nicholas";
}
var person = new Object();
setName(person);
alert(person.name);    //"Nicholas"

我们发现原始变量person对象的name属性被改变了,这具有很强的迷惑性,会让人以为引用类型的传参是将整个引用对象存储的内容复制传递了。是否如此呢?我们看下面这个例子。

// eg3.2
function setName(obj) { 
    obj.name = "Nicholas";
    obj = new Object(); 
    obj.name = "Greg";
}
var person = new Object();
setName(person);
alert(person.name);    //"Nicholas"

如果真的是按引用传递,那么最后person.name应该是'Greg'才对,但事实上却是'Nicholas',说明这里是并不是按引用传递。下面我们来一步步分析这两段代码的实际过程。

对于eg3.1和eg3.2:

step1: var person = new Object();执行完如下:

step1

step2: 进入setName(person);如下:

step2

step3: obj.name = "Nicholas";执行完如下:

step3

eg3.1的setName函数调用到此已结束,此时,person.name从图中可以看出是'Nicholas'。而对于eg3.2,其setName函数增加了两个步骤,如下:

step4: obj = new Object();执行完如下:

step4

step5: obj.name = "Greg";执行完如下:

step5

可以看到,此时person.name仍然是'Nicholas'。

现在,我们明白了,其实JS函数参数的传递始终是按值传递。但是在函数调用的过程中,我们到底是对该值指向的堆地址进行了操作,还是对该值进行了操作,决定了我们是否会对原变量产生影响。

4. 测试一下

看到这里,你应该已经掌握了JS的数据类型和按值传递。来做一个小测验,下面是两个对数组进行拼接并返回拼接后数组的函数,哪个函数在拼接的同时对传入的参数也产生了影响呢?(顺便学习一下es6的知识吧b( ̄▽ ̄)d)

var fillArray = (arr, ...values) => {arr.push(...values);return arr;}
var fillArray = (arr, ...values) => {arr = arr.concat(...values);return arr;}

参考

BOOK-《JavaScript高级程序设计(第3版)》 第3章

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏WindCoder

JavaScript字符串数组排序

思考路线:需要区分数字字符和非数字字符,故可知数字字符为此条件中的”特殊字符“,即特殊情况,需单独处理。数字字符的ASCII值为48-57。每次比较两个字符串(...

24610
来自专栏xingoo, 一个梦想做发明家的程序员

【面试虐菜】—— JAVA面试题(1)

今天参加笔试,里面有设计模式,和一些基础题! 印象最深的是:什么不是Object的函数,我蒙的finalize,哎,无知! 还问了,接口与抽象类的不同,还...

21590
来自专栏轮子工厂

6. 简单又复杂的“运算符”,建议你看一哈

昨天的《5. 很“迷”的字符与字符串》初稿本来很短的,但是我觉得内容太少了,就加了一些,结果好像就变得特别多〒▽〒。

9430
来自专栏C语言C++游戏编程

有人@我,你有一份C语言基础大全手册要领取,快来拿!

前两天,有网友问了我一个关于C语言的问题,本着认真装逼的态度,我把大学时学过的C语言课本翻了一遍,终于找到了答案。整理后,现分享给大家!

16920
来自专栏take time, save time

初级程序员面试不靠谱指南(三)

二、指针的好基友的& 1.&的意义。说&是指针的好基友其实不恰当,因为&这个符号在C/C++不止有一种含义,但是因为其经常会和指针一起出现在被问的问题列表上,所...

33890
来自专栏marsggbo

python大小写转换函数

1.全部转换成大写:upper() 用法: str = ‘marsggbo’     print str.upper() 结果:MARSGGBO 2....

31990
来自专栏从零开始学自动化测试

python笔记2-冒泡排序

前言 面试的时候经常有面试官喜欢问如何进行冒泡排序?这个问题相信能难倒一批英雄好汉,本篇就详细讲解如何用python进行冒泡排序。 一、基本原理 1.概念: 冒...

38460
来自专栏C/C++基础

C++11 变参模板

版权声明:感谢您对博文的关注!校招与社招,有需要内推腾讯的可以QQ(1589276509)or 微信(louislvlv)联系我哈,期待您的加入。 ...

42720
来自专栏一“技”之长

Swift讲解专题九——枚举 原

        在Objective-C语言中,没有实际上是整型数据,Swift中的枚举则更加灵活,开发者可以不为其分配值类型把枚举作为独立的类型来使用,也可以...

7020
来自专栏芋道源码1024

Java 函数式编程和 lambda 表达式

函数式编程更多时候是一种编程的思维方式,是种方法论。函数式与命令式编程的区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做。说白了,...

11510

扫码关注云+社区

领取腾讯云代金券