JS中的对象及其他概念

 

JS 的其他重要概念!

万物皆对象?

1,说法原因

历史因素:
JS 的诞生是参考了 js 的;在 Java 中一切皆对象,但基本类型却不是对象,为了解决这个问题,Java 让每个基本类型都对应了一个包装器类型。包装器类型将基本类型包装起来,添加了属性和方法,包装器类型即为对象,所以可以这么说 Java 中的一切都可以充当对象,不会说的那么绝对。

​ 我们可以把对象看作是一个属性的集合,每一个属性都有一个名称和值(键值对)。

​ 在 JS 这门面向对象编程的语言,几乎所有的东西都可以是对象;但除开直接书写的原始数据类型,其它东西都是对象;基本数据也可以通过内置构造函数书写,如利用 toString(),改变数据类型为 string,这样它就是一个对象了;

所以在 js 中并非所有内容都是对象,而是所有内容都可以充当对象;

2,原始类型和对象

​ 在 JS 中值可以分为两大类,原始类型和对象,基本上就区分了对象和其它;

六类原始数据类型:

​ Boolean,null,undefined,number,string,symbol(ES6);

对象:

​ 1,原始值的包装类型,通过系统包装构建出来的原型类型对象:如 Boolean,Number,String;

​ 2,函数和数据是对象的一等公民,是对象里使用和功能最强大的两个;

​ 3,通过构造函数 new 出来的值,都是对象;

​ 4,正则表达式也是对象;/\s*/ 类同与 new RegExp(“\s”)

不同点:

​ 1,是否可变:原始类型没有附加方法,所有你永远看不到 undefined.toString(),因此原始类型是不可变的;对象在默认情况下是可变的,可以添加方法;

​ 2,储存方式:原始类型按值存储,对象通过引用存储;存储地址也不同,原始类型直接存在栈中,对象存放在堆中;

数据的储存

​ 在 jave 中原始数据类型一般储存在栈里,对象一般储存在堆里;

JS 内存存放机制:

1)基本数据类型:string number boolean undefined null

如果变量后面的值是基本数据,就直接存在栈内存。栈里面要求变量不能重名,如果重名就会覆盖前者

2)引用数据类型:object array function

如果变量后面是引用数据类型,将后面的代码块存在堆内存中,然后将堆内存中的内存地址赋值给前面的变量

js 内存中,保存变量根本不是用栈和堆的。存储任何变量和数据,用的都是对象。而 js 中对象底层其实都是一种叫关联数组的数据结构。对象或关联数组的存储结构内部都是由多组”属性名:属性值”这种名值对儿组成的。js 中,连作用域也都是一个个的对象。其中,担当全局作用域的对象其实名为 window。window 对象在你刚一打开网页,就自动创建了。

this 关键字

​ this 的本质是在对象创建时,指向对象的一个地址;

​ 有关 this 的方法,函数(对象)的方法;

bind(),改变对象的 this 指向,无参;
call(),改变对象的 this 指向,自动调用,多个参数;
apply();改变对象的 this 指向,自动调用,参数为数组;

深拷贝和浅拷贝

都创建了一个新对象;
let a = {};
let b = a; //使用的是浅拷贝 相当于把对象地址给b
a.name = 10; //a的地址和b的地址指向同一个内容  a里面添加一个name b也添加
console.log(b.name); //10

1,深拷贝:创建一个新对象,拷贝所拷贝对象的所有内容(跟原本的内容无关系也不影响)

​ 深拷贝是把储存在堆里的数据全部拷贝了一份新的出来,不引用地址;

实现方法:

​ a,递归遍历到没有对象后结束;

​ b,JSON.parse(常用)

let a = [1, 2, 3, { name: 1, age: 2, list: [1, 2] }];
let str = JSON.stringify(a);
let aCopy = JSON.parse(str);
console.log(a == aCopy); //false

2,浅拷贝:只拷贝第一层内容(对于里层的内拿到的都是地址)

​ 浅拷贝在对储存在堆里的数据进行拷贝时,是引用复制了其地址,堆中的数据还是只有一份;

//浅拷贝
let arr = [];
for (let key in a) {
  arr[key] = a[key];
}
console.log(arr[3] === a[3]); //true 拷贝的是对象的地址