美文网首页菲麦前端
JS入门难点解析1-JS的数据类型和按值传参

JS入门难点解析1-JS的数据类型和按值传参

作者: love丁酥酥 | 来源:发表于2017-10-29 17:46 被阅读47次

(注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章

相关文章

  • JS入门难点解析1-JS的数据类型和按值传参

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

  • js基础(一)

    1-js中的数据类型 js中的原始数据类型有6中,其中基本数据类型有4种(string、number、boolea...

  • 19-3-18 python函数传参方式

    python函数传参跟js很像: 直接传参方式: 形参实参按顺序一一对应,跟js一样 指定传参 参数顺序不用一一对...

  • js函数参数

    函数参数的传递的方式无非两种,传值和传址。js中基本数据类型的传递方式很明显就是传值。例子: Number 的值复...

  • 2018-12-01

    js中括号操作属性 js函数 js换肤 变量和函数预解析 匿名函数 函数传参 函数return关键字 流程控制语句...

  • Java基础

    值传递和引用传递 基本数据类型传值,对形参的修改不会影响实参 引用类型传引用,形参和实参指向同一个内存地址(同一个...

  • JavaScript基础—简单数据类型与复杂数据类型

    简单数据类型的基本包装 简单数据类型和复杂数据类型 简单类型传参 复杂类型传参

  • JS原生引用类型解析

    经过前一个系列JS入门难点解析的学习,想必大家对JS的原理有了更清晰的把握和认识。这个系列,我们不做原理分析,而是...

  • 引用传递和值传递

    Java (1)基本数据类型传值,对形参的修改不会影响实参; (2)引用类型传引用,形参和实参指向同一个内存地址(...

  • JS传参是按值传递还是按引用传递?

    发现对js传参是值传递还是引用传递这个问题的认识不是很清晰,在这里做下探究。 首先要清楚的是,什么是按值传递?什么...

网友评论

  • coffee_e50b:大佬,我的理解是实际上值是分两种的,一种是基本类型值复制传递,另一种是指向实参对象地址值复制传递,所以本质上都是值传递,而后一种被称为共享传递,call by share;而所谓的引用传递是将实参的引用真正的传递进入,而不是复制引用传递。所以感觉大佬其实不用解释那么复杂。
    coffee_e50b:@love丁酥酥 有道理,非英语母语,计算机最头疼的永远是概念。虽然我觉得看书其实是学习最好的方法,而不是视频,w3cscool等地方。就像大佬引用的js高级程序设计,其实很多知识点讲解很详细了。
    love丁酥酥:哈哈,不是大佬哈~~嗯,没听说过call by share这个词,特意查了下,其实对一个知识点来讲,懂的人可以精炼成自己的总结,可是不懂的人很难从纯概念的话来进行理解。如果懂的人可能不需要看这篇文章,但是不懂的人如果只看了这段概念他还是不懂。我的理解是,博客应该把自己懂的知识用浅显易懂的话告诉别人,让别人也理解~这篇文章除了传递一个概念,也是想传递一个概念理解的过程,另外也帮读者区分对于引用地址的操作和对实际引用操作的不同~~:smirk:
  • Love小六六:很棒,浅显易懂~✧*。٩(ˊᗜˋ*)و✧*。给男神点赞

本文标题:JS入门难点解析1-JS的数据类型和按值传参

本文链接:https://www.haomeiwen.com/subject/odyypxtx.html