对象

JS 中的所有事物都是对象,如:字符串、数值、数组、函数等,每个对象带有属性和方法。
对象的属性:反映该对象某些特定的性质的,如:字符串的长度、图像的长宽等;
对象的方法:能够在对象上执行的动作。例如,表单的“提交”(Submit),时间的“获取”(getYear)等;
JavaScript 提供多个内建对象,比如 String、Date、Array 等等,使用对象前 先定义,如下使用数组对象:

  1. var myarray=new Array(6);//定义数组对象
  2. var myl=myarray.length;//访问数组长度length属性 以上代码执行后,myl的值将是:6

原始类型

boolean null undefined number string symbol

引用类型

在 JS 中,除了原始类型其他的都是引用类型

区别

原始类型存储的是值
引用类型存储的是地址(指针)。
当创建一个引用类型的时候,计算机会在内存中开辟一个空间来存放值,这个空间会拥有一个地址(指针)。

函数传参

例1:

  1. function test(person) {
  2. person.age = 26
  3. person = { //因为这里想要重新定义 p1 ,
  4. name: 'yyy', //按照规则,p1内部的参数可以被改变,但 p1 本身是不可以被改的
  5. age: 30 //所以,p1 与 person 的连接断开
  6. }
  7. return person
  8. }
  9. const p1 = {
  10. name: 'yck',
  11. age: 25
  12. }
  13. const p2 = test(p1)
  14. console.log(p1) // -> ?
  15. console.log(p2) // -> ?

执行过程
p1 的值在 堆 中,地址在栈中,假设 为 00x1。
当执行 console.log(p1) 动作 时,调用 test(person) {} 函数,person 是形参,p1 是实参。
p1.age = 26 —>地址 00x1 指向的堆中 age 的值变为 26.
在函数test(person){} 中,p1 与 person 的地址断开,给 person 重新分配地址

对象 地址
p1 00x1 { name: ‘yck’, age: 26}
p2 00x2 { name: ‘yyy’, age: 30 }

例2:

  1. function setName(obj) {
  2. obj.name = "Nicholas";
  3. obj = new Object(); //因为这里想要重新定义 person ,
  4. //按照规则,person 内部的参数可以被改变,但 person 本身是不可以被改的
  5. //所以person 与 obj 的连接断开
  6. obj.name = "Greg";
  7. console.log(person.name) //"Nicholas"
  8. console.log(obj.name) //"Greg"
  9. console.log(person) //{name: "Nicholas"}
  10. console.log(obj) //{name: "Greg"}
  11. }
  12. var person = new Object();
  13. setName(person);
  14. console.log(person.name); //"Nicholas"

执行过程:
执行 setName(person) 动作 时,obj 是形参,person 是实参。
person 添加了 name 属性 —> person.name = “Nicholas”;
然后 执行 obj = new Object(); ——>person 与 obj 的连接断开——->内存给 obj 一个新的地址 00x2 ,指向堆中新开辟的空间,然后由于 obj 是 局部变量,所以在函数执行结束后被销毁。

对象 地址
person 00x1 new Object(){name: “Nicholas”}

总结

原始类型存储的是值
引用类型存储的是地址(指针)。
函数传参是传递对象指针的副本。
局部变量在执行结束后会被销毁。
函数 传参 时的 参数本身是不可以被更改的,一旦要被更改,则会断开 形参 与 实参 的联系。