一、对象的概念
对象: 无序的名值对的集合(键值对的集合)
在JS当中,可以说一切皆对象:
-
如果存储一个简单的数据(一个数字,一个字符串)直接var a = 10。 -
如果存储一堆的数据,此时我们想到数组,数组就是专门用来存储多个数据用的。 -
如果我们想要执行一段代码,或者让这段代码有功能,此时我们需要函数。 -
如果我想描述一个复杂的事物,比如说一个人、一台电脑(需要用到多个属性或者方法才能描述清楚),此时就要用到对象。
二、对象的创建方法
一般我们说的对象都是Object的实例对象(万能,通用的,可以表示任何事物的)
1.字面量创建(常用)
var obj = {};
我们来创建一个手机对象:
var obj = {
name:'iphoneX',
color:'black',
call:function()
{
console.log('打电话');
}
}
console.log(obj);
它的结果如下图所示:

我们来调用对象obj的call方法:
obj.call();
成功输出“打电话”。
**注意:**属性之间用逗号分隔,不能用分号。
2.构造函数定义(new Object)
var obj = new Object();
如上述代码所示,就是使用构造函数的方法定义了一个对象。
需要注意的是:
- 如果带了
new,证明在把这个函数当做构造函数来用。 - 如果不带
new,证明在把这个函数当做普通函数来用。
举个例子:
var obj1 = new Object();
var obj2 = new Object({name:'杨幂',age:18});
console.log(obj2);
var obj3 = {
name:'杨幂',
age:18
}
console.log(obj3);
3.工厂函数定义(本质上还是使用构造函数)(几乎不用)
function createObject(name,age)
{
var obj = new Object();
obj.name = name;
obj.age = age;
return obj;
}
console.log(createObject('热巴',18));
三、对象的操作(增删改查)及遍历
字面量定义对象与构造函数定义对象其实是一回事
我们来定义一个对象obj,后续操作都是对它进行操作。
var obj = {};
1.增
直接增加属性:
obj.name = '小黄';
obj.age = 1;
console.log(obj);
我们说对象里面就是一个个名值对,类似于Python中的字典。所以操作属性还有另外一种方法:
obj["color"] = 'yellow';
obj["category"] = '阿拉斯加';
如果用的是上面这种[ ]的方式,那么[ ]当中加引号是在往对象当中添加名或者键(名值对也叫键值对)。
如果不加[ ],则[ ]当中的内容就会被当作变量处理,没有定义过这个变量就会报错。
举个例子:
var obj = {};
var cry = 'call';
obj[cry] = function()
{
console.log('汪');
}
2.改
改的操作与增的操作一样,不过它遵循的是“无则增加,有则更改”的原则。
obj.color = 'black';
obj["name"] = '小黑';
var a = 'category';
obj[a] = '金毛';
3.查
查的操作,直接写即可,有则查找成功,无则undefined。
console.log(obj.name);
console.log(obj["color"]);
var a = 'category';
console.log(obj[a]);
console.log(obj.haha);
4.删
删的操作简单粗暴,使用delete关键字就可以搞定。
delete obj.category;
delete obj["color"];
var a = 'age';
delete obj[a];
5.遍历
遍历也算是查操作,查对象当中所有的属性。
注意: 遍历数组用for,遍历对象用for in。
定义一个对象:
var obj =
{
name:'car',
category:'劳斯莱斯',
color:'hotpink',
money:10000000,
run:function()
{
console.log('跑的很快!');
}
}
使用for in进行遍历:
for(var key in obj)
{
console.log(key,obj[key]);
}
注意点:
- 如果是在
遍历对象的时候,取值只能使用[ ]的方式,因为key是一个变量。 - 如果写成
obj.key,则拿到的会是undefined,因为这样写,key会被认为是对象里面的属性。 obj[key],key被解析为变量,使用变量的值进行替换。
思考
我们平时使用的输出语句console.log()与上面例子中的obj.run()为何两者如此相似?答案——console也是一个对象。
验证:
console.log(console)
结果:

四、构造函数创建特定实例对象
1.构造函数的基本概念
构造函数
构造函数本质上也是一个函数,只不过通常我们把构造函数的名字写成大驼峰。在ES5版本的JS当中,没有类的概念,构造函数可以理解为类。
在Python中,对象是由类实例化生成的,所以JS这里可以将构造函数当成类来看(可以把类理解为生对象的模子)。如果我创建一个构造函数叫做Person,这个模子就定好了,它就只能产生人对象,不可能产生一条狗对象出来。构造函数是为了让我们更方便的创建多个具有相同特征的对象。
构造函数用法和普通的函数用法是一样的,直接可以调用,只不过它比普通函数多了一种用法—— new。
案例
定义一个“人”的构造函数,所以这个构造函数是产生人这个对象的模子。
function Person(name,age,gender)
{
this.name = name;
this.age = age;
this.gender = gender;
this.eat = function()
{
console.log('吃饭');
}
console.log(this);
}
this是个啥?
通常情况下在任何函数当中都会有this这个关键字。
this代表着调用这个函数或者方法的那个对象(注意是对象),这个函数或者说这个方法这个时候是谁的,this的结果就是谁。如果函数是在全局环境,那么结果就是window,将在下面(2.window对象)中进行讲解。
注意: this指向谁得分情况进行考虑,将在下面(3.对this的讲解)中进行讲解。
我们先把这个构造函数当做普通函数调用:
var a = Person('zs',23,'2');
console.log(result);
我们来看看此时函数Person中“console.log(this)”的结果:

name属性在最下面,不便截图查看,它也存在于window对象中。
我们现在把这个函数当做构造函数调用生成对象(加new)。
调用构造函数加了个new,就是在实例化对象。就相当于让Person这个妈妈赶紧生一个对象(孩子),让它生对象的时候给它传生出来的娃叫啥(name),年龄多大(age),是男是女(gender)。而且当加了new以后,它的返回值就是实例化出来的那个对象。
var per1 = new Person('zs','23','male');
console.log(per1);
让我们来看看此时函数内“console.log(this)”与外部“console.log(per1)”的结果:

两者结果一模一样,this此时就是per1对象。
什么点什么,前边的东西肯定是对象,对象点什么,其实就是往对象当中要么添加属性要么更改属性。
所以,调用构造函数实例化对象时,其中的this.xx就是往this当前所指代的对象当中添加或更改属性。
new关键字实例化对象的过程:
- 开辟内存空间
- this指向该内存
- 执行函数
- 生成实例对象并返回(虽然我们没有写返回值,但它相当于自动添加了
return this)
2.window对象(全局对象)
全局对象,全名为浏览器窗口对象,代码执行的时候所有的一切,都是包含在全局对象下的。
我们在全局环境下直接定义的函数或者变量,都是全局对象下的一个属性。
所以我们一般将window对象下的方法称为函数,其他对象下的方法就只称为方法。
3.对this的讲解
通常情况下在任何函数当中都会有this这个关键字。
this本质是一个对象,代表着调用这个函数或者方法的对象(这个函数的执行者)。这个函数或者说这个方法是谁的,this就代表谁。
this指向谁得分情况进行考虑,一般有以下四种情况:
-
this在函数当中,函数也可以叫做是window对象的方法,this永远代表window; var a = 10;
function add(a,b)
{
console.log(this);
return a + b;
}
console.log(window.add(10,20));
-
this在事件当中,回调函数当中的this,代表的是事件对象; -
this在对象的方法当中,this代表的是这个对象; obj{
add:function()
{
console.log(this);
}
}
-
this在构造函数当中,代表的是实例化出来的那个对象;
4.构造函数实例化对象过程及内存展现
案例:歌手
function Singer(name,gender,age)
{
this.name = name;
this.gender = gender;
this.age = age;
this.sing = function(){
console.log('我什么都能唱!');
}
}
我们来实例化出两个实力派歌手:
var singer1 = new Singer('邓紫棋','famale',28);
singer1.sing();
console.log(singer1.name);
console.log(singer1['age']);
var singer2 = new Singer('腾格尔','male',50);
singer2.sing();
console.log(singer2.name);
console.log(singer2['age']);
内存展现:

过程:
首先把全局环境押入栈区,从上到下收集变量(函数也属于变量)。
然后在堆区当中开辟内存,函数体放入内存当中,假设地址为100,将此地址绑定给Singer,即让Singer指向地址为100的内存空间。
调用构造函数Singer来实例化对象(new),我们知道new的第一步就是开辟内存空间,假设第一个new出来的空间内存地址为80,那么就会将此地址绑定给singer1,即让singer1指向地址为80的内存空间。此时this也会指向内存地址为80的内存空间,这也是new的第二步。new的第三步是执行函数体代码,给当前this指向的内存空间中添加属性。因为singer1绑定的是内存地址为80的内存空间,所以函数体代码给内存空间中添加属性之后,这个空间就是实例化出来的对象。
所以我们说:this的指向随操作而变化,根本作用就是帮助操作空间。
|