JavaScrip对象
基本概念
对象是什么?
对象是管理复杂代码、理解浏览器对象模型和组织数据的关键,还是许多javascript库的基本组织方式。
对象由什么组成
属性和行为
何为面向对象呢?
我们解决问题,都使用一系列的变量声明、条件、for/while语句和函数调用。这是过程型思维:先这样做,再那样做,等等。在面向对象的编程中,我们从对象的角度考虑问题,而对象有状态和行为,面向对象能让你从更高的角度思考问题。
属性
就拿汽车来说,汽车对象应该有哪些属性:
就拿汽车来说,汽车有很多属性,不仅仅是前面说的那几个,但就编码而言,我们只在软件中记录这几个属性。下面来看看这些属性的数据类型。
(汽车有很多属性,但是你想想在对象中记录它们真的有意义吗?)
这些属性在代码中如何体现?
对象如何创建
你创建了一个包含一系列属性的对象,并将其赋给了一个变量,以便使用它来访问和修改这个对象的属性。
var car={
make:"Chevy",
model:"Bel Air",
year:1957,
color:"red",
passengers:2,
convertible:false,
milage:1021
};
你可以传递这个对象,获取其中的值,修改其中的值,添加属性或删除属性
- 务必将对象定义放在花括号内
- 用冒号分割属性名和属性值
- 属性名可以是任何字符串,但通常遵循变量命名规则
- 在同一个对象中,不能包含两个同名的属性
- 用逗号分割属性名和属性值对
- 在最后一个属性值后面,不添加逗号
访问属性
car.make
修改属性:
只需要为属性赋新值就可
car.year=2000;
添加属性:添加新的属性并赋值。如果属性不存在,则创建新属性;如果属性存在,则修改该属性的值
car.needWashing=true;
如何将属性用于计算
删除属性
使用delete,删除属性时,不仅删除了属性的值,还删除了属性本身。如果成功删除了属性,delete表达式返回true.仅当属性无法删除的时候,delete才返回false.
delete car.convertible;
变量是如何存储对象的
- 变量就像是容器,用于存储值。数字、字符串和布尔值都很小,对象怎么样呢?变量可存储任何规模的对象,不管它包含多少属性吗?
- 变量并不实际存储对象
- 变量存储指向对象的引用
- 引用就像指针,是对象的存储地址
- 换句话说,变量并不存储对象本身,而是存储类似于指针的东西。在JavaScript中,我们并不知道引用变量存储的到底是什么,但我们知道,不管它存储的是什么,它可定指向对应的对象。
- 当我们使用句点表示法时,JS解释器将负责根据引用获取对象并访问其属性。
对象变量存储的是指向对象的引用。基础变量类型表示的是实际值,而对象变量表示一种获取对象的途径。当使用句点表示法(.)用来引用变量时,相当于这样说:请使用句点前的引用来获取相应的对象,再访问句点后指定的代码。如car.color:访问变量car所引用的对象属性color.
使用对象
假设你要物色一辆好车,供你在web镇使用。你的要求是什么?下面的要求怎样?
1960年生产
里程不超过10000英里
你还想要利用新学到的编码技能来简化挑选工作。因此你想编写一个函数,帮你对车辆进行预检,即如果车辆合乎要求,这个函数返回true;如果车辆不值得你浪费时间,这个函数就返回false
具体的说,你要编写一个函数,它将一个汽车对象座位参数,对其进行检查,并返回一个布尔值。这个函数可用于对任何汽车对象进行预检。
function prequal(car){ if(car.milage>10000){ return false; }else if(car.year>1960){ return false; } return true; } var worthAlook=prequal(car); if(worthAlook){ cnsole.log("you gotta check out this"+taxi.make+""+taxi.model); }else{ console.log("这辆车不符合要求"); }
向函数传递对象
实参是如何传递给对象的:实参是按值传递的,这意味这传递的是实参的副本。因此,如果我们传递的是一个整数,相应的函数形参将获得该整数值的副本,以便在函数中使用它。
这意味着什么呢?一个最大的不同是,如果你在函数中修改对象的属性,修改的将是原始对象的属性。因此,函数结束时,在函数中对对象所作的修改都依然有效。
函数中添加行为
<script> var car={ make:"Chevy", model:"Bel Air", year:1957, color:"red", passengers:2, convertible:false, milage:1021, drive:function(){ console.log("这辆车可以跑,对象可以添加行为"); } }; car.drive();
封装
使用方法来修改属性是另一种封装方式,它让对象决定如何完成工作,通常可以改善代码的可维护性和可扩展性。通过让方法start负责启动发动机,再次使用的时候,你就无需知道以下细节:为启动发动机,需要获取属性started,并将其设置为true。通过将细节放进一个方法中,让你只需要向对象发出指令,由对象去操心如何执行这些指令。
var car={ make:"Chevy", model:"Bel Air", year:1957, color:"red", passengers:2, convertible:false, milage:1021, started:false, stop:function(){ this.started=false; }, start:function(){ this.started=true; }, drive:function(){ if(this.started){ console.log("这辆车可以跑,对象可以添加行为"); }else{ this.start(); console.log("这辆车需要启动发动机才能开"); } } }; car.drive();
关键字:this,
告诉你当前所处的对象。对于使用对象内部自己的方法和属性时,都需要加一个this关键字。
如果不加this关键字,引用的变量会被解析城局部变量,函数形参或全局变量。
关键字this的工作原理
可将this视为一个变量,指向其方法被调用的对象。
构造对象的函数
对象构造函数(简称构造函数)让你能够更好地创建对象。构造函数犹如一个小型工厂,能够创建无数类似的对象。
从
代码的角度看,构造函数很像返回对象的函数:定义后,每当需要创建新对象时都可调用它。要了解构造函数的工作原理,最佳方式是创建一个。
我们需要找到一种方法,创建任何包含品牌、里程、生产时间等属性的车对象。为此我们将编写一些代码,它类似于函数,同时在语法上又有点像对象。
如何创建构造函数
接下来我们要声明构造函数以及使用它来创建对象。要使用构造函数,分两步走:
- 一是先定义一个构造函数
- 二是使用构造函数来创建对象
function Car(make,model,year){ this.make=make; this.model=model; this.year=year; } var baoma=new Car("BMW","Bel Air",2020);
我们需要的是一个可用于创建小狗对象的构造函数,更具体的说是用于创建一个包含品牌,型号,出厂时间的车对象。因此我们定义了一个被称为构造函数的函数,他知道如何创建小狗对象。
要创建一个名为baoma,型号是"Bel Air",出厂时间为2020年的车,需要使用关键字new,再使用合适的实参调用构造函数baoma.这条语句执行完毕后,变量baoma将指向一个新车
对象的引用。
构造函数的工作原理
要理解构造函数的工作原理,关键在于了解运算符new都作了什么。
- new首先创建一个空对象
- 接下来,new设置this,使其指向这个新对象
- 设置this后,调用构造函数Car,并将baoma,"Bel Air"和2020作为实参传递给它
- 接下来,执行这个函数的代码。与大多数构造函数一样,Car给新创建的this对象的属性赋值
- 最后Car函数执行完毕后,运算符返回this——指向新创建的对象引用。请注意,它会自动为你返回this,你无需在代码中显示地返回。指向新对象的引用被返回后,我们将其赋值给baoma
构造函数中添加方法
function Car(make,model,year){ this.make=make; this.model=model; this.year=year; this.drive=function(){ console.log("构造函数还能定义方法"); } } var baoma=new Car("BMW","Bel Air",2020); console.log(baoma.year); baoma.drive();
对象字面量代替所有实参
function Car(params) { this.make = params.make; this.model = params.model; this.year = params.year; this.color = params.color; this.passengers = params.passengers; this.convertible = params.convertible; this.mileage = params.mileage; this.started = false;
this.drive = function() { if (this.started) { console.log(this.make + " " + this.model + " goes zoom zoom!"); } else { console.log("Start the engine first."); } }; } var cadiParams = {make: "GM", model: "Cadillac", year: 1955, color: "tan", passengers: 5, convertible: false, miles: 12892};
var cadi = new Car(cadiParams);
/*在对象创建后增删其属性,使其具有独特的属性和方法*/
cadi.owner='eric';
cadi.stop=function(par){
console.log("this car can stop");
};
将所有的实参都放在一个对象字面量中,再将这个对象字面量传递给函数。这将通过一个容器(对象字面量)传递所有的值,从而不必担心实参与形参的顺序问题。
对象是一个动态的结构,无论对象包含那些属性和方法,其类型都是Object.实际上,创造对象时,运算符new再幕后存储了一些信息,让你随时都能确定对象是由哪个构造函数创建的。运算符instanceof就是根据这些信息来确定对象是否是指定构造函数的实例。
内置构造函数