使用对象

JavaScript是基于简单的基于对象的范例设计的。对象是属性属性是名称(或钥匙)和一个值。属性的值可以是函数,在这种情况下,该属性称为方法.

与许多其他编程语言一样,JavaScript中的对象可以与现实生活中的对象进行比较。在JavaScript中,对象是一个独立的实体,具有属性和类型。例如,将其与杯子进行比较。杯子是一个具有特性的物体。杯子有颜色、设计、重量、材质等。同样,JavaScript对象也可以有定义其特征的属性。

除了在浏览器中预定义的对象外,您还可以定义自己的对象。本章介绍如何使用对象、属性和方法,以及如何创建自己的对象。

创建新对象

可以使用对象初始化器。或者,您可以首先创建一个构造函数,然后使用新的操作员。

使用对象初始值设定项

对象初始值设定项也称为对象字面量。“对象初始值设定项”与C++使用的术语一致。

使用对象初始值设定项的对象的语法为:

js型
常量对象={property1:value1,//属性名称可以是一个标识符2:value2,//或数字“属性n”:value3,//或字符串};

冒号之前的每个属性名称都是一个标识符(名称、数字或字符串文字),每个值N是一个表达式,其值被指定给属性名。属性名称也可以是表达式;计算出的键需要用方括号括起来。这个对象初始化器参考资料包含更详细的语法解释。

在这个例子中,新创建的对象被分配给一个变量对象-这是可选的。如果不需要在其他地方引用此对象,则不需要将其分配给变量。(请注意,如果对象出现在预期的语句位置,则可能需要将对象文字括在括号中,以免将文字与块语句混淆。)

对象初始值设定项是表达式,每当执行其中出现的语句时,每个对象初始值设置项都会导致创建一个新对象。相同的对象初始值设定项会创建不同的对象,这些对象之间的比较并不相等。

下面的语句创建一个对象并将其赋值给变量x个当且仅当表达式康德为真:

js型
设x;if(条件){x={问候语:“你好”};}

以下示例创建我的本田具有三个属性。请注意发动机属性也是一个具有自己属性的对象。

js型
const myHonda={颜色:“红色”,车轮:4,引擎:{气缸:4,大小:2.2},};

使用初始值设定项创建的对象被调用普通对象,因为它们是对象,但不是任何其他对象类型。某些对象类型具有特殊的初始值设定项语法-例如,数组初始值设定项正则表达式文字.

使用构造函数

或者,可以使用以下两个步骤创建对象:

  1. 通过编写构造函数定义对象类型。使用大写首字母是一种很有道理的习惯。
  2. 使用创建对象的实例新的.

要定义对象类型,请为对象类型创建一个函数,指定其名称、属性和方法。例如,假设要为汽车创建对象类型。您希望调用此类型的对象小型车,您希望它具有make、model和year属性。为此,您需要编写以下函数:

js型
功能车(品牌、型号、年份){this.make=品牌;this.model=模型;this.year=年;}

注意使用根据传递给函数的值为对象的属性赋值。

现在可以创建一个名为我的汽车如下:

js型
const myCar=新车(“Eagle”,“Talon TSi”,1993年);

此语句创建我的汽车并为其属性指定值。那么我的汽车.make是字符串“鹰”,我的汽车模型是字符串“泰龙TSi”,我的汽车年份是整数1993,依此类推。参数和参数的顺序应该相同。

您可以创建任意数量的小型车对象的调用新的例如,

js型
const kensar=新车(“日产”,“300ZX”,1992年);const vpgscar=新车(“马自达”,“米亚塔”,1990年);

一个对象可以有一个本身就是另一个对象的属性。例如,假设您定义了一个名为如下:

js型
功能人员(姓名、年龄、性别){this.name=名称;this.age=年龄;this.sex=性别;}

然后实例化两个新的对象如下:

js型
constrand=新人(“rand McKinnon”,33,“M”);const ken=新人(“ken Jones”,39,“M”);

然后,您可以重写小型车包括主人采用对象,如下所示:

js型
功能车(品牌、型号、年份、车主){this.make=品牌;this.model=模型;this.year=年;this.owner=所有者;}

要实例化新对象,请使用以下命令:

js型
const car1=新车(“Eagle”,“Talon TSi”,1993年,兰特);const-car2=新车(“日产”,“300ZX”,1992年,肯塔基州);

注意,在创建新对象时,上面的语句不是传递文本字符串或整数值,而是传递对象兰特肯恩作为业主的论据。如果你想知道赛车总动员2,您可以访问以下属性:

js型
car2.owner.name;

您始终可以将特性添加到先前定义的对象。例如,语句

js型
car1.color=“黑色”;

添加属性颜色汽车1,并为其赋值“黑色”。但是,这不会影响任何其他对象。要将新属性添加到相同类型的所有对象中,必须将该属性添加到小型车对象类型。

您还可以使用语法而不是功能定义构造函数的语法。有关更多信息,请参阅课堂指导.

使用Object.create()方法

也可以使用对象.create()方法。此方法非常有用,因为它允许您选择原型对象,而无需定义构造函数。

js型
//动物特性和方法封装const动物={type:“无脊椎动物”,//属性默认值显示类型(){//显示动物类型的方法console.log(this.type);},};//创建新的动物类型animal1const animal1=Object.create(动物);animal1.displayType();//原木:无脊椎动物//创建新的动物类型,称为鱼类const fish=Object.create(动物);fish.type=“鱼”;fish.displayType();//原木:鱼类

对象和属性

JavaScript对象具有与其关联的属性。对象属性基本上与变量相同,只是它们与对象关联,而不是范围对象的属性定义了对象的特征。

例如,此示例创建一个名为我的汽车,属性名为制作,模型、和,其值设置为“福特”,“野马”、和1969:

js型
const myCar={品牌:“福特”,型号:“野马”,年份:1969年,};

与JavaScript变量一样,属性名也区分大小写。属性名称只能是字符串或符号-所有键都是转换为字符串除非它们是符号。数组索引实际上,这些属性具有包含整数的字符串键。

访问属性

可以通过对象的属性名称访问对象的属性。属性访问器有两种语法:点符号括号记法。例如,您可以访问我的汽车对象如下:

js型
//点表示法myCar.make=“福特”;myCar.model=“野马”;myCar.年=1969年;//括号表示法myCar[“make”]=“福特”;myCar[“model”]=“野马”;myCar[“年”]=1969;

对象属性名称可以是任何JavaScript字符串或符号,包括一个空字符串。但是,不能使用点表示法访问名称不是有效JavaScript标识符的属性。例如,具有空格或连字符、以数字开头或保存在变量内的属性名称只能使用括号表示法进行访问。当属性名称要动态确定时,即在运行时才可确定时,此符号也非常有用。示例如下:

js型
const myObj={};const str=“myString”;const rand=数学.random();const anotherObj={};//在myObj上创建其他属性myObj.type=“名为type的键的点语法”;myObj[“date-created”]=“此密钥有空格”;myObj[str]=“此键位于变量str中”;myObj[rand]=“这里的关键是随机数”;myObj[anotherObj]=“此键是另一个对象Obj”;myObj[“”]=“此密钥是空字符串”;console.log(myObj);// {//type:'名为type的键的点语法',//'创建日期':'此密钥有空格',//myString:'此键位于变量str中',//“0.6398914448618778”:“此处的关键是随机数”,//“[object object]”:“此键是object anotherObj”,//“”:“此键是空字符串”// }console.log(myObj.myString);//'此键位于变量str'中

在上述代码中,键另一个对象是一个对象,既不是字符串也不是符号。将其添加到我的对象,JavaScript调用toString()方法另一个对象,并将结果字符串用作新键。

您还可以使用存储在变量中的字符串值访问属性。变量必须以括号表示法传递。在上面的例子中,变量字符串持有“myString”而且它是“myString”这是属性名。因此,我的对象.str将返回为未定义。

js型
str=“myString”;myObj[str]=“此键位于变量str中”;console.log(myObj.str);//未定义console.log(myObj[str]);//'此键位于变量str'中console.log(myObj.myString);//'此键位于变量str'中

这允许访问运行时确定的任何属性:

js型
let propertyName=“make”;myCar[propertyName]=“福特”;//通过更改变量的内容访问不同的属性propertyName=“model”;myCar[propertyName]=“野马”;console.log(myCar);//{品牌:“福特”,型号:“野马”}

但是,要注意使用方括号访问由外部输入给定名称的属性。这可能会使您的代码容易受到对象注入攻击.

对象的不存在属性具有值未定义(而不是无效的).

js型
myCar.nonexistentProperty;//未定义

枚举属性

有三种本地方法可以列出/遍历对象属性:

  • 用于。。。在里面循环。此方法遍历对象的所有可枚举字符串属性及其原型链。
  • Object.keys()。此方法返回一个数组,该数组在对象中只包含可枚举的自身字符串属性名称(“keys”)我的对象而不是原型链中的那些。
  • 对象.getOwnPropertyNames()。此方法返回一个数组,其中包含对象中所有自己的字符串属性名称我的对象,无论它们是否可枚举。

您可以使用括号表示法用于。。。在里面迭代对象的所有可枚举属性。为了说明其工作原理,当您将对象和对象名称作为参数传递给函数时,以下函数将显示对象的属性:

js型
函数showProps(obj,objName){让结果=“”;for(obj中的常量i){//对象.hasOwn()用于从对象的//原型链,只显示“自己的属性”if(Object.hasOwn(obj,i)){result+=`${objName}${i} =${obj[i]}\n`;}}console.log(结果);}

术语“自有属性”是指对象的属性,但不包括原型链的属性。因此,函数调用showProps(myCar,“myCar”)将打印以下内容:

myCar.make=福特myCar.model=野马myCar.year=1969年

上述内容相当于:

js型
函数showProps(obj,objName){让结果=“”;Object.keys(obj).forEach((i)=>{result+=`${objName}${i} =${obj[i]}\n`;});console.log(结果);}

没有本地方法来列出继承的非枚举属性。然而,这可以通过以下功能实现:

js型
函数列表所有属性(myObj){让objectToInspect=myObj;设result=[];while(objectToInspect!==null){结果=result.concat(Object.getOwnPropertyNames(objectToInspect));objectToInspect=Object.getPrototypeOf(objectToInspect);}返回结果;}

有关更多信息,请参阅属性的可枚举性和所有权.

删除属性

可以使用删除操作员。以下代码显示如何删除属性。

js型
//创建一个具有两个属性a和b的新对象myobj。const myobj=新对象();myobj.a=5;myobj.b=12;//删除a属性,使myobj只保留b属性。删除myobj.a;console.log(myobj中的“a”);//

继承

JavaScript中的所有对象都继承自至少一个其他对象。从中继承的对象称为原型,继承的属性可以在原型构造函数的对象。请参见继承和原型链了解更多信息。

为一种类型的所有对象定义属性

可以将特性添加到通过特定建造师使用原型属性。这定义了一个属性,该属性由指定类型的所有对象共享,而不是仅由对象的一个实例共享。以下代码添加了颜色属性设置为所有类型的对象小型车,然后从实例中读取属性的值汽车1.

js型
Car.prototype.color=“红色”;控制台.log(car1.color);//“红色”

定义方法

A类方法是与对象关联的函数,或者换言之,方法是作为函数的对象的属性。方法的定义方式与普通函数的定义方式相同,只是它们必须被指定为对象的属性。另请参见方法定义了解更多详细信息。例如:

js型
objectName.methodName=函数名称;常量myObj={myMethod:函数(参数){//做点什么},//这也行得通!myOtherMethod(参数){//做点别的},};

哪里对象名称是现有对象,调用的方法名是指定给方法的名称,并且函数名称是函数的名称。

然后可以在对象上下文中调用该方法,如下所示:

js型
objectName.methodName(参数);

方法通常在原型对象,以便相同类型的所有对象共享相同的方法。例如,您可以定义一个函数来格式化和显示先前定义的小型车物体。

js型
Car.prototype.displayCar=函数(){constresult=`A美丽的${this.year}${this.make}${this.model}`;console.log(结果);};

注意使用引用该方法所属的对象。然后你可以打电话给显示汽车每个对象的方法如下:

js型
car1.显示Car();car2.显示Car();

将其用于对象引用

JavaScript有一个特殊的关键字,,您可以在方法中使用它来引用当前对象。例如,假设您有两个对象,经理实习生。每个对象都有自己的名称,年龄工作.在函数中sayHi(),注意使用this.name(此名称)。当添加到这两个对象时,同一个函数将打印带有所附加到的相应对象名称的消息。

js型
常量管理器={name:“卡丽娜”,年龄:27岁,职位:“软件工程师”,};const实习生={name:“泰龙”,年龄:21岁,职位:“软件工程师实习生”,};函数sayHi(){console.log(`您好,我的名字是${this.name}`);}//将sayHi函数添加到两个对象经理.sayHi=sayHi;Intern.sayHi=说嗨;经理.sayHi();//你好,我叫卡丽娜实习生sayHi();//你好,我叫泰龙

是函数调用的“隐藏参数”,通过在调用函数之前指定对象来传入。例如,在经理.sayHi(),经理对象,因为经理在函数之前sayHi()。如果您从另一个对象访问相同的函数,也会发生变化。如果使用其他方法调用该函数,如函数.prototype.call()反射.apply(),可以显式传递的值作为一个论点。

定义getter和setter

A类吸气剂是与获取特定属性值的属性关联的函数。A类设置器是与设置特定属性值的属性相关联的函数。它们结合在一起可以间接地表示属性的价值。

Getter和setter可以是

对象初始值设定项,getter和setter的定义类似于正则方法,但前缀为关键字得到设置。getter方法不能期望参数,而setter方法只期望一个参数(要设置的新值)。例如:

js型
常量myObj={a: 7、,获取b(){返回this.a+1;},集合c(x){这.a=x/2;},};console.log(myObj.a);//7console.log(myObj.b);//8,从get b()方法返回myObj.c=50;//调用set c(x)方法console.log(myObj.a);//25

这个我的对象对象的属性为:

  • 我的目标-一个数字
  • 我的目标b-返回的getter我的目标加1
  • 我的目标c-设置我的目标值的一半我的目标c正在设置为

创建对象后,还可以随时使用对象.defineProperties()方法。此方法的第一个参数是要在其上定义getter或setter的对象。第二个参数是一个对象,其属性名是getter或setter名称,其属性值是用于定义getter或setter函数的对象。下面的示例定义了上一示例中使用的相同getter和setter:

js型
const myObj={a:0};Object.defineProperties(myObj{b:{获取(){返回this.a+1;},},抄送:{集合(x){这.a=x/2;},},});myObj.c=10;//运行setter,将10/2(5)赋值给“a”属性console.log(myObj.b);//运行getter,生成+1或6

选择哪种形式取决于您的编程风格和手头的任务。如果可以更改原始对象的定义,则可能会通过原始初始值设定项定义getter和setter。这种形式更紧凑、更自然。然而,如果您以后需要添加getter和setter(可能是因为您没有编写特定的对象),那么第二种形式是唯一可能的形式。第二种格式更好地代表了JavaScript的动态特性,但它会使代码难以阅读和理解。

比较对象

在JavaScript中,对象是引用类型。两个不同的对象永远不会相等,即使它们具有相同的属性。只有将同一对象引用与其本身进行比较,才能得到true。

js型
//两个变量,两个具有相同属性的不同对象const-fruit={name:“苹果”};const果树熊={name:“苹果”};水果==水果熊;//返回false水果===水果熊;//返回false
js型
//两个变量,一个对象const-fruit={name:“苹果”};const fruitbear=水果;//将水果对象引用指定给水果熊//这里,水果和水果熊指向同一个物体水果==水果熊;//返回true水果===水果熊;//返回trueruit.name=“葡萄”;console.log(水果熊);//{名称:葡萄};不是{name:“苹果”}

有关比较运算符的更多信息,请参见相等运算符.

另请参见