JavaScript面向对象
# 对象的创建和使用
# 对象的创建方法
- 对象字面量(Object Literal),通过
{}
创建 - new Object + 动态添加属性创建
- new 其它类
- 主要使用对象字面量创建的方式
# 对象使用
- 访问对象的属性
- 修改对象的属性
- 添加对象的属性
- 删除对象的属性 delete 对象.属性名
# 使用[]
访问对象属性
使用[]
的原因:对于多层次访问的属性来说,JavaScript是无法理解的,例如
info.good friend = 'zs'
因为.
符号要求key是有效的变量标识符,不包含空格、不以数字开头、也不包含特殊字符(允许使用$和_),这种情况下可以使用[]
,[]
符号在定义或者操作属性时更加灵活
var message = 'Hello World'
var obj = {
'good friend': 'zs',
[message]: 'Hello World'
}
console.log(obj['good friend'])
console.log(obj[message])
2
3
4
5
6
7
# 对象遍历
通过对对象的遍历(迭代)获取对象中所有的属性和方法。Object.keys()
方法返回由一个给定对象的自身可枚举属性组成的数组
# 方式一 普通for循环
var infoKeys = Object.keys(info)
for(var i = 0; i < infoKeys.length; i++){
var key = infoKeys[i]
var value = info[key]
console.log(`key: ${key}, value:${value}`)
}
2
3
4
5
6
# 方式二 for in 遍历
for(var key in info){
var value = info[key]
console.log(`key: ${key}, value: ${value}`)
}
2
3
4
5
对象不支持for...of遍历
# 栈内存和堆内存
程序运行时需要加载到内存中执行,可以将内存划分为两个区域:栈内存、堆内存
原始类型占据的空间是在栈内存中分配的。
对象类型占据的空间是在堆内存中分配的
# 值类型和引用类型
原始数据类型值的保存方式:在变量中保存的值是值本身,因此原始数据类型也称为值类型。
对象类型的保存方式:在变量中保存的是对象的“引用”,因此对象类型也被称为引用类型
案例一:对象之间的比较
var a = 123;
var b = 123
console.log(a === b) // true
var m = {}
var n = {}
console.log(m === n) // false
var x = {}
var y = x
console.log(x === y) // true
2
3
4
5
6
7
8
9
10
11
案例二:引用传值和值传递的内存区别
function foo(info){
info.name = 'kobe'
}
var obj = {
name: 'zs'
}
foo(obj)
console.log(obj) // kobe
function foo(a){
// 这里a指向了一个新的地址
a = {
name: 'zs'
}
}
var obj = {
name: 'ls'
}
foo(obj)
console.log(obj) // {name: 'ls'}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# this
在所有的编程语言中几乎都存在一个关键字this
,JavaScript中的this
更加灵活
编写一个对象,有this和没有this的情况
// 没有this的情况
var obj = {
name: 'zs',
running: function(){
console.log(obj.name+ 'running')
},
eating: function(){
console.log(obj.name+ 'eating')
},
studying: function(){
console.log(obj.name + 'studying')
}
}
// 有this的情况
var obj = {
name: 'zs',
running: function(){
console.log(this.name+ 'running')
},
eating: function(){
console.log(this.name+ 'eating')
},
studying: function(){
console.log(this.name + 'studying')
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# this指向
目前掌握
- 在全局环境下以默认的方式调用函数,this指向的是window
- 通过对象调用,this指向的是调用的对象
function foo(){
console.log(this) // this指向window
}
foo()
var obj = {
bar: function(){
console.log(this) // this指向obj
}
}
obj.bar()
2
3
4
5
6
7
8
9
10
11
12
# 类和对象
在开发过程中如果需要创建一系列相似的对象,使用字面量的方式创建对象存在一个很大的弊端,在创建同样的对象时需要编写大量重复的代码
# 创建对象的方案---工厂函数
封装一个公共的函数,这个函数帮助我们创建一个对象,当需要创建实际的对象时只需要调用这个函数即可,这种方式称之为工厂模式,工厂模式也是一种常见的设计模式
function createPerson(name, age, height, address){
var p = new Object()
p.name = name
p.age = age
p.height = height
p.address = address
p.eating = function(){
console.log(this.name+'eating')
}
p.running = function(){
console.log(this.name + 'running')
}
return p
}
var p1 = createPerson('zs', 18, 1.88, '北京')
var p2 = createPerson('ls', 20, 1.68, '上海')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 构造函数
工厂模式创建对象有一个比较大的问题:在打印对象时,对象的类型都是Object类型,从某些角度来说这些对象是他们的公共类型。因此需要使用另外一种模式---构造函数
# 构造函数定义
- 构造函数也称之为构造器,通常是在创建对象的时候会调用的函数
- 在其他编程语言中,构造函数是存在于类中的一个方法,称之为构造方法
- 但是在JavaScript中,构造函数扮演了其它语言中类的角色。
在JavaScript中,构造函数其实就是类的扮演者
- 比如系统默认给我们提供的Date就是一个构造函数,也可以看成是一个类
- 在ES5之前,都是通过function来声明一个构造函数(类)的,之后通过new关键字来对其调用
- 在ES6之后,JavaScript可以像其它语言一样通过
Class
来声明一个类
# 类和对象的关系
# 什么是类
- 现实生活中往往是根据一个模板来创建一个实体对象的
- 在编程语言中,也必须先有一份模板,在模板中说明将来创建的对象有哪些属性和行为
# JavaScript中的类
在JavaScript中,类的表示形式就是构造函数。
JS中的构造函数也是一个普通的函数,从表现形式上来说和其它函数没有任何区别;如果一个普通函数被使用new
操作符来调用了,那么这个函数就被称为是一个构造函数
当一个函数被使用new操作符调用了,那么它会执行如下操作
- 在内存中创建一个新的对象(空对象)
- 这个对象内部的[prototype]属性会被赋值为该构造函数的prototype属性
- 构造函数内部的this会指向创建出来的新的对象
- 执行函数的内部代码(函数体代码)
- 如果构造函数没有返回非空对象,则返回创建出来的新的对象。
# 创建对象的方案---构造函数(类)
function Person(name, age, height, address){
this.name = name
this.age = age
this.height = height
this.address = address
this.eating = function(){
console.log(this.name + 'eating')
}
this.running= function(){
console.log(this.name + 'running')
}
}
var person = new Person('zs', 20, 180, '') // new是操作符
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
这个构造函数可以确保创建的对象是Person类型的(实际是constructor的属性)
构造函数还有很多其它的特性
- 原型、原型链、实现继承的方案
- ES6中的类,继承的实现
# 全局对象Window
作用
- 查找变量时,最终都会找到Window身上
- 将一些浏览器全局提供的变量/函数/对象,放在window对象上
- 使用var定义的变量会被默认添加到window上面
# 函数其实也是对象
函数也是对象,创建时是在堆内存中创建的
# 类方法
function Dog(){}
Dog.running = function(){} // 构造函数上面添加的函数,称之为类方法
Dog.running()
2
3