一、对象
1、对象是一个复杂数据类型
- 数组就是一个 `{}`
- 在 `{}` 里面存储着各种各样的数据,按照顺序依次排好
*** 对象就是一个键值对的集合***
键名 键值
var obj = { name:“张三”} var str = “name”
① 键名会自动转换为字符串
②键名可以是变量 var obj = { 【str】:“张三” }
①键值可以是任何类型
2、面对对象的编程思路
- 面向过程
- 用多少面粉
- 用多少水
- 怎么和面
- 怎么切面条
- 做开水
- 煮面
- 吃面
- 面向对象
- 找到一个面馆
- 叫一碗面
- 等着吃
- 面向对象就是对面向过程的封装 就是创建一个“”面馆“”,然后用面馆创建一个“”面“”
2、对象的创建方式
①字面量的创建 var obj = {name:'张三',age:23}
②构造函数创建 var obj = new Object()
3、使用工厂函数的方式创建对象
性能不好,占用内存 每次都会创建一个函数
①、创建一个 工厂函数 function createObj(){
②、手动向对象中添加成员 var obj = new Object()
obj.name="张三" return obj }
③、使用这个工厂函数创建对象 var o1 =createObj()
4、使用构造函数方式创建对象
**一摸一样的函数出现了两次,占用了两个空间地址**
①、自动创建对象 function Person(name){
②、手动添加成员 this.name = name } 添加属性
③、自动返回对象 Person.prototype.fn=function( ){ } 添加方法
let o2 = New Person(“张三”) o2.fn()
构造函数:提供一个公共的空间来存放,复杂数据类型(函数)
构造函数 : constructor
构造函数的调用 :new
①创建了一个空对象
②把创建的空对象和函数内的this 绑定
③隐式返还这个对象
④可以执行函数
公共空间就是 :原型 prototype
注意:1.构造函数里的this指向实例化之后的对象
// 2.会把属性放在构造函数内部 把方法放在构造函数的原型上;
5、原型
是为了提供了一个给对象添加函数的方法
**一摸一样的函数出现了两次,占用了两个空间地址**
prototype
- **每一个函数天生自带一个成员,叫做 prototype,是一个对象空间**
- 重点: **在函数的 prototype 里面存储的内容,不是给函数使用的,是给函数的每一个实例化对象使用的**
原型链
**构造函数的 prototype** 里面的 `__proto__` 属性又指向哪里呢?
\_\_proto\_\_
- **每一个对象都天生自带一个成员,叫做 `__proto__`,是一个对象空间**
- **属性我们直接写在构造函数体内**
- **方法我们写在原型上**
constructor
- 对象的 `__proto__` 里面也有一个成员叫做 **`constructor`**
- 这个属性就是指向当前这个对象所属的构造函数
4、原型链
①、原型是有自身和原型组成,原型又是一个对象
##对象的属性或者方法查找顺序
①、对象先在自身查找属性和方法,如果没有找到就在原型上查找,又因为对象的原型是和构造函数的prototype空间,构造函数也是一个对象,会在构造函数的原型上找,一直找到Object.prototype.__proto__返回null
3、for in 循环
因为 **对象** 是没有索引的,所以我们没有办法使用 for 循环来遍历
- 这里我们使用 for in 循环来遍历对象
```javascript
var obj = {
name: 'Jack',
age: 18
}
for (var key in obj) {
console.log(key)
}
// 会在控制台打印两次内容,分别是 name 和 age
```
- for in 循环的遍历是按照对象中有多少成员来决定了
- 有多少成员,就会执行多少次
- `key` 是我们自己定义的一个变量,就和 for 循环的时候我们定义的 i 一个道理
- 在每次循环的过程中,key 就代表着对象中某一个成员的 **属性名**