目录

JavaScript面向对象

# 对象的创建和使用

# 对象的创建方法

  • 对象字面量(Object Literal),通过{}创建
  • new Object + 动态添加属性创建
  • new 其它类
  • 主要使用对象字面量创建的方式

# 对象使用

  • 访问对象的属性
  • 修改对象的属性
  • 添加对象的属性
  • 删除对象的属性 delete 对象.属性名

# 使用[]访问对象属性

使用[]的原因:对于多层次访问的属性来说,JavaScript是无法理解的,例如

info.good friend = 'zs'
1

因为.符号要求key是有效的变量标识符,不包含空格、不以数字开头、也不包含特殊字符(允许使用$和_),这种情况下可以使用[][]符号在定义或者操作属性时更加灵活

var message = 'Hello World'
var obj = {
    'good friend': 'zs',
    [message]: 'Hello World'
}
console.log(obj['good friend'])
console.log(obj[message])
1
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}`)
}
1
2
3
4
5
6

# 方式二 for in 遍历

for(var key in info){
    var value = info[key]
    console.log(`key: ${key}, value: ${value}`)
}

1
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
1
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'}
1
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')
    }
}
1
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()
1
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, '上海')
1
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操作符调用了,那么它会执行如下操作

  1. 在内存中创建一个新的对象(空对象)
  2. 这个对象内部的[prototype]属性会被赋值为该构造函数的prototype属性
  3. 构造函数内部的this会指向创建出来的新的对象
  4. 执行函数的内部代码(函数体代码)
  5. 如果构造函数没有返回非空对象,则返回创建出来的新的对象。

# 创建对象的方案---构造函数(类)

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是操作符
1
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()
1
2
3
上次更新: 2022/08/31, 08:39:00
最近更新
01
防抖和节流
02-06
02
正则表达式
01-29
03
async_await函数
12-30
更多文章>