摘要:二逻辑判断中的引用通常我们会把理解为值相同,把理解为值相同且类型相同。但是这种理解不是完全准确的。只能确保定义的变量的引用地址不会被改变。
一: 函数中的引用传递Author: bugall
Wechat: bugallF
Email: 769088641@qq.com
Github: https://github.com/bugall
我们看下下面的代码的正确输出是什么
function changeStuff(a, b, c) { a = a * 10; b.item = "changed"; c = {item: "changed"}; } var num = 10; var obj1 = {item: "unchanged"}; var obj2 = {item: "unchanged"}; changeStuff(num, obj1, obj2); console.log(num); // 10 console.log(obj1.item); // changed console.log(obj2.item); // unchanged
在javascript中除了基础类型采用的是值(值类型有哪些)传递,而对象采用是引用传递。这就好理解为什么a的值没有被修改。
那为什么obj1的值修改了,但是obj2的值却没有被覆盖?当我们调用changeStuff函数的时候,参数b,c的值分别是obj1,obj2的引用。
当我们去修改的b的值的时候,因为b->obj1的引用关系没有变,所以实际修改的是obj1的值。但是参数c的情况就不同了,因为我们在函数中对c进行了引用的重新绑定,c = {item: "changed"} 这时候的c中的对象引用已经改变,这里要清楚引用和指针的关系。
二: 逻辑判断中的引用通常我们会把==理解为值相同,把===理解为值相同且类型相同。
但是这种理解不是完全准确的。0=="" //true,直观理解上0怎么会等于""空字符串呢?因为在做==逻辑判断的时候js会把==两边的值做类型转换,然后再比较。
另外在javascript中比较奇葩的就是关于null,我很难理解为什么null支持比较呢?比如在SQL中我们是不能对null值直接比较的,通常都会使用is null or is not null来做判断。
如果我们把===理解为值相同,且类型相同那么就无法理解[1] === [1] // false的情况,因为[1]值相同,类型也相同。
我们应该怎么理解======不会判断值是否相同,只会判断===左右两边的变量保存的引用地址是否相同,我们一起看下例子
var a = [1,2,3]; var b = [1,2,3]; var c = a; var ab_eq = (a === b); // false 因为a,b的引用不同, // 或者理解为a,b引用的对象在堆上不是同一个对象。 var ac_eq = (a === c); // true 因为a保存了一份对象的引用, // `c=a` c会把a的值copy一份,这是a,c的值(保存对象的引用)相同。 其实对于一个变量来说,包含了`左值`和`右值` 后面我会整理文章
类似的例子
var a = { x: 1, y: 2 }; var b = { x: 1, y: 2 }; var c = a; var ab_eq = (a === b); // false type) var ac_eq = (a === c); // true
var a = { }; var b = { }; var c = a; var ab_eq = (a === b); // false var ac_eq = (a === c); // true总结===的三种情况
对于整型 (numbers): a === b // 如果值相同返回true 对于引用类型来说: a === b // 如果a,b保存的是同一个对象的引用返回true 对字符串来说: a === b // 左右两边的字符相同返回true
var1 == var2 结果图
我们首先看下官方的定义:
constant cannot change through re-assignment constant cannot be re-declared
简单翻译就是:const定义的变量不能被重新定义,不能被重新赋值。
const 只能确保定义的变量的引用地址不会被改变。但是如果引用指向的
是一个对象的话,你是可以对对象里的值进行修改的,因为没有改变对象
自身的地址。
const x = {}; x = {foo: "bar"}; // error - re-assigning const y = ["foo"]; const y = ["bar"]; // error - re-declaring const foo = "bar"; foo = "bar2"; // error - can not re-assign var foo = "bar3"; // error - already declared function foo() {}; // error - already declared
但是对于值的修改是允许的
const x = {}; x.foo = "bar"; console.log(x); // {foo : "bar"} const y = []; y.push("foo"); console.log(y); // ["foo"];
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/87036.html
JavaScript在创建变量(数组、字符串、对象等)是自动进行了分配内存,而且当它没有被使用的状态下,会自动的释放分配的内容;其实这样基层语言,如C语言,他们提供了内存管理的接口,比如malloc()用于分配所需的内存空间、free()释放之前所分配的内存空间。 释放内存的过程称为垃圾回收,例如avaScript这类高级语言可以提供了内存自动分配和自动回收,其实这个自动储存不会占用太多空间...
摘要:对比较返回是因为这个字符串在执之前已经出现过,字符串常量池中已经有它的引用了,不符合首次出现的原则,而计算机软件这个字符串则是首次出现的,因此返回。 在《深入理解Java虚拟机》书中,提到在jdk1.7的版本中用String.intern()返回引用。 public class RuntimeConstantPoolOOM { public static void main(S...
摘要:一是如何工作的在上是这样描述的运算符用于测试构造函数的属性是否出现在对象原型链中的任何位置换句话说,如果,那么必须是一个对象,而必须是一个合法的函数。下面我们举一个例子一步步来说明第一步每一个构造函数都有一个属性。 在 JavaScript 中,我们通常用 typeof 判断类型,但是在判断引用类型的值时,常常会遇到一个问题:无论引用的是什么类型的对象,都会返回 object(当然还有...
摘要:简单的函数调用显而易见,一直用调用函数将会非常烦人。规范说几乎总是被传递,但不在严格模式下时被调用函数应该将其更改为全局对象。实际上,规范有一个和都使用的原语内部称为。 过去很多年里,我看到过太多关于JavaScript函数调用的混淆。尤其是,很多人抱怨函数调用中this的语义令人困惑。在我看来,通过理解核心函数调用原语,然后将其他所有调用函数的方法视为在原语之上的语法糖,如此便可澄清...
摘要:是上一次加载资源时,服务器返回的,是对该资源的一种唯一标识,只要资源有变化,就会重新生成。同源限制如果非同源以下三种行为将受到限制和无法读取。Js相关执行环节和作用域执行环节定义了函数或者变量可以访问的其它数据,决定了他们各自的行为。每个执行环境都有一个与之关联的变量对象,在环境中定义的所有变量和函数都保存在这个变量中,并且是我们无法访问。每个函数都有自己的执行环境,当执行流进入一个函数的时...
阅读 743·2021-07-25 21:37
阅读 3657·2019-08-30 15:55
阅读 2573·2019-08-30 15:54
阅读 1720·2019-08-30 15:44
阅读 3124·2019-08-30 15:44
阅读 860·2019-08-30 15:43
阅读 1026·2019-08-29 15:36
阅读 3038·2019-08-29 10:58