对象的概念

「对象」

在JavaScript中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,例如字符串、数值、数组、函数等。

对象是由属性和方法组成的

  1. 属性:事物的特征,在对象中用属性来表示(常用名词)
  2. 方法:事物的行为,在对象中常用方法来表示(常用动词)

「为什么需要对象」

  • 保存一个值时,可以使用变量,保存多个值(一组值)时,可以使用数组,如果保存一个的完整信息呢?
  • 为了更好地存储一组数据,对象应用而生;对象中为每项数据设置了属性名称,可以访问数据更语义化,数据结构清晰,表意明显,方便开发者使用。
1
2
3
4
5
6
var obj = {
"name":"fan",
"sex":"male",
"age":18,
"height":155
}

创建对象的三种方式

  • 利用字面量创建对象
  • 利用 new object 创建对象
  • 利用构造函数创建对象

「1. 利用字面量创建对象」

使用对象字面量创建对象:

  • 就是花括号 { } 里面包含了表达这个具体事物(对象)的属性和方法

  • { } 里面采取键值对的形式表示

    -:相当于属性名
    -:相当于属性值,可以是任意类型的值(数字类型、字符串类型、布尔类型,函数类型等)

1
2
3
4
5
6
7
8
9
10
// star 就是创建的对象
var star = {
name : 'pink',
age : 18,
sex : '男',
sayHi : function() {
alert('大家好啊');
}
};
// 方法冒号后面跟的是一个匿名函数

对象的的两个概念

  1. 对象的属性:对象中存储具体数据的“键值对”中的‘键’称为对象的属性,即对象中存储具体数据的项。
  2. 对象的方法:对象中存储函数的“键值对”中的“键”称为对象的方法,即对象中存储函数的项。(这里方法是名词)

对象的使用

  • 访问对象的属性(两种方式):
  1. 对象里面的属性调用:对象.属性名
  2. 对象里面属性的另一种调用方式:对象['属性名'],注意方括号里面的属性必须加上引号。
  • 调用对象的方法: 对象.方法名();
1
2
3
4
5
6
// 调用属性
console.log(star.name) // 调用名字属性
console.log(star['name']) // 调用名字属性

// 调用方法
star.sayHi(); // 调用对象方法

变量、属性、函数、方法总结

①变量:单独声明赋值,单独存在
②属性: 对象里面的变量称为属性,不需要声明,用来描述该对象的特征。
③方法:方法是对象的一部分,函数不是对象的一部分,函数是单独封装操作的容器。对象里面的函数称为方法,方法不需要声明,使用” 对象.方法名() “的方式就可以调用,方法用来描述该对象的行为和功能。
④函数: 单独存在的,通过” 函数名() “的方式就可以调用。

「2. 利用new Object创建对象」

  • 创建空对象
1
2
// 通过内置构造函数Object创建对象,此时andy变量已经保存了创建出来的空对象
var andy = new Object();
  • 给空对象添加属性和方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 通过对象操作属性和方法的方式,来为对象增加属性和方法
// (1)我们利用等号 = 赋值的方法,添加对象的属性和方法
// (2)每个属性和方法之间用分号结束
andy.name = 'pink';
andy.age = 18; // andy.age = 19修改对象属性
andy.sex = '男'; // andy.phoneNum = 110 添加属性
andy.sayHi = function() {
alert('大家好');
}
obj.sayHi();// 调用对象的方法
//第二种写法 obj['sayHi']();

// Object()第一个字母大写;
//new Object() 需要new关键字,使用的格式:对象.属性 = 值

案例:工厂函数创建对象 这个把创建好的对象返回给函数调用处

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 工厂函数创建对象 这个把创建好的对象返回给函数调用处
function createPerson(name, age, job) {
//new Object创建对象
var person = new Object();
person.name = name;
person.age = age;
person.job = job;
person.sayHi = function(){
console.log('Hello,everyBody');
}
//此函数返回的是一个对象
return person;
}
var p1 = createPerson('张三', 22, 'actor');

「3. 利用构造函数创建对象」

构造函数是一种特殊的函数,主要用来初始化对象,即为对象成员变量赋初始值,它总与new运算符一起使用,我们可以把对象中一些公共的属性和方法抽出来,然后封装到这个函数里面。

1
2
3
4
5
6
7
8
9
10
// 利用构造函数创建对象
// 构造函数的语法格式
function 构造函数名() {
this.属性 = 值;
this.属性 = 值;
this.方法 = function() {

}
}
new 构造函数名();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 构造函数的封装格式
function 构造函数名(形参1,形参2,形参3...) {
this.属性名1 = 参数1;
this.属性名2 = 参数2;
this.属性名3 = 参数3;
this.方法名 = 函数体;
}
// 构造函数的调用格式
var obj = new 构造函数名(实参1,实参2,实参3); // 以上代码中,obj即接收到构造函数创建出来的对象。
注意事项:
1.构造函数约定首字母大写
2.函数内的属性和方法前面需要添加this,表示当前对象的属性和方法
3.构造函数中不需要retrun返回结果
4.但我们创建对象的时候,必须用new 来调用构造函数

1.其他:构造函数如Stars(),抽取了对象的公共部分,封装到了函数里面,它
泛指某一大类(class)
2.创建对象,如new Stars();特指某一个,利用new关键字创建对象的过程
我们也称为对象实例化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 我们需要创建四大天王的对象 相同的属性:名字,年龄,性别,相同的方法:唱歌
function Star(uname, age, sex) {
this.name = uname;
this.age = age;
this.sex = sex;
this.sing = function(sang) {
console.log(sang);
}
}
var ldh = new Star('刘德华', 18, '男'); // 调用函数返回的是一个对象
console.log(typeof ldh);
console.log(ldh.name);
console.log(ldh['sex']);
ldh.sang('冰雨');
var zcy = new Star('张学友', 19, '男');
console.log(zxy.name);
console.log(zxy.age);
zxy.sing('春兰');

构造函数和对象

  • 构造函数:如Stars(),抽象了对象的公共部分,封装到了一个函数里面,它泛指某一大类(class)
  • 创建对象:如new Stars() ,特指某一个,通过new关键字创建对象的过程我们也称为对象实例化

new关键字的作用(面试题)

  1. 在构造函数代码开始执行之前,创建一个空对象;
  2. 修改this的指向,把this指向创建出来的空对象;
  3. 执行构造函数内的代码,给这个新对象添加属性和方法
  4. 在函数完成之后,返回这个创建出来的新对象(所以构造函数里面不需要return)

遍历对象

1
2
3
4
5
6
7
8
9
10
11
// for...in 语句用于对数组或者对象的属性进行循环操作。
// 其语法如下:
for (变量 in 对象名字) {
// 在此执行代码
}
//语法中的变量是自定义的,它需要符合命名规范,通常我们会将这个变量写为 k 或者 key。

for (var k in obj) {
console.log(k); // 这里的 k 是属性名
console.log(obj[k]); // 这里的 obj[k] 是属性值
}

简单数据类型和复杂数据类型

「简单类型(基本数据类型、值类型)」:在存储时变量中存储的是值本身,包括string ,number,boolean,undefined,null

「复杂数据类型(引用类型)」:在存储时变量中存储的仅仅是地址(引用),通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等;

「堆栈」

堆栈空间分配区别:

  • 1、栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;简单数据类型存放到栈里面

  • 2、堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

简单数据类型的存储方式

  • 值类型变量的数据直接存放在变量(栈空间)中

复杂数据类型的存储方式

  • 引用类型变量(栈空间)里存放的是地址,真正的对象实例存放在堆空间中

「简单类型传参」

函数的形参也可以看做是一个变量,当我们把一个值类型变量作为参数传给函数的形参时,其实是把变量在栈空间里的值复制了一份给形参,那么在方法内部对形参做任何修改,都不会影响到的外部变量。

1
2
3
4
5
6
7
8
9
function fn(a) {
a++;
console.log(a);
}
var x = 10;
fn(x);
console.log(x);
// 11
// 10

「复杂数据类型传参」

函数的形参也可以看做是一个变量,当我们把引用类型变量传给形参时,其实是把变量在栈空间里保存的堆地址复制给了形参,形参和实参其实保存的是同一个堆地址,所以操作的是同一个对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
  function Person(name) {
this.name = name;
}
function f1(x) { // x = p
console.log(x.name); // 2. 这个输出什么 ?
x.name = "张学友";
console.log(x.name); // 3. 这个输出什么 ?
}
var p = new Person("刘德华");
console.log(p.name); // 1. 这个输出什么 ?
f1(p);
console.log(p.name); // 4. 这个输出什么 ?
//刘德华
//刘德华
//张学友
//张学友