面向对象的四个核心概念
Encapsulation封装Abstraction抽象Inheritance继承Polymorphism多态
如何创建一个对象
既然面向对象,那么核心一定是对象,那么如何创一个对象就是一个必须面对的问题
对象创建的方法
- 直接创建一个
const dog1 = {
name: 'wangwang',
eat: function() {
console.log('eat...');
}
}
问题: 一个对象怎么声明无所谓,假设是有一百个变量呢?如果只是靠复制,就意味着开始错了,就要修改一百处,工作量太大,就引出了下面两种方法
- 工厂函数
function createObj(name) {
return {
name, // ES6语法,当 key === value 是可以只写一个
eat: function() {
console.log('eat...');
}
}
}
cosnt dog1 = createObj('wangwang'); // 生成一个
const dog2 = creatObj('Coco'); // 生成第二个
- 构造函数
function Dog(name) {
this.name = name;
this.eat = function() {
console.log('eat...');
}
}
const dog1 = new Dog('wangwang');
const dog2 = new Dog('Coco');
!!!背后的逻辑 ( 以dog1为例 )
1. new 起作用生成一个空对象 {}
2. 将 new 创建的对象地址传入 Dog 构造函数给 this this--->{}
3. this.name = name; 是向空对象添加值 this--->{name: 'wanwang'}剩余一致
4. 将 this 返回给声明的值 dog1--->{name: 'wanwang'...}
工厂函数和构造函数没有优劣之分,如果仅仅是创建对象,两者都可以
引用类型 VS 值类型
在 JavaScript 将变量分为引用类型和值类型,那么我们既然构建了对象及引用类型,那么它和值类型又有哪些区别呢?
JavaScript 中的所有变量类型
- Number
- String
- Boolean
- Symbol
- undefined
- null
- Objeadt
let a = 10;
fuction f(a) {
a++;
}
f(a);
console.log(a); // 10
let x = {a: 10};
function f(x) {
x.a++;
}
f(x);
console.log(x); // {a: 11};
1. 值传递,将外部 a 的值传递入给函数中的 a 两者只是同名,实际不是同一个地址
2. 引用传递,传入 x 是地址,将其赋值给同名的 x 传的是地址,改的是同一个空间中的对象