假定我们定义了一个车类型的设备的对象类型:
//定义一个对象类型CarDevice
function CarDevice(driver)
{
this.wheels = 4;
this.color = '黑色';
this.engine = '内燃机';
this.displacement = '4.0';//排量
this.driverNum = 1;
this.maxPassengerNum = 4;
this.maxSpeed = 300;
this.driver = driver;
}
//再给这个车类设备定义一个喇叭鸣叫的方法,
//这台车目前移动功能还在开发中,只能叫不能跑。
CarDevice.prototype.beep = function()
{
console.log(`司机${this.driver},按下了喇叭,汽车发出了“滴滴的声音”。`);
}
//创建一个对象出来;
var HongQi_H5 = new CarDevice('李雷');//红旗H5被创建出来了
//但是这台车的排量没这么大,我们现在把它的排量改一下
HongQi_H5.displacement = '1.8';
//晚上坐上了车,突然发现车子还需要一个属性,比如车灯的类型:是LED的还是卤素,不光这台红旗
//需要这么一个属性,以后所有车子都会要。于是我们就给车子的对象类型添加属性
CarDevice.prototype.lightType = 'LED';//所有车都有灯的属性,还是LED灯
//但是我们发现红旗h5是卤素灯,不是LED的。
HongQi_H5.lightType = 'Halogen';
console.log(HongQi_H5.lightType);
console.log(HongQi_H5.driver);
HongQi_H5.beep();
通过上面的示例我们发现:无论某个对象实例是否已经创建,通过在对象原型上添加的属性,将会影响所有对象,无论对象是在此属性添加之前实例化还是之后实例化的,都会受到影响。
什么是方法?方法的本质是对象的一个具名化的属性的值,只不过这个值有点特殊,它是一个函数。
例如,苹果15作为一个对象。
var iphone15 = {
属性1: 值1,
属性2: 值2,
...
方法1: function(参数列表){
函数语句
},
//我们还可以这样写
方法2(参数列表)
{
函数语句
}
}
从上面的例子中,我们可看出给对象定义方法的语法如下:
//一、给已经存在的对象添加方法和属性
对象名称.方法名称 = 函数名称
//对象名称:这个对象必须是已经存在的具体实例
//在对象定义时的定义方法和属性
var objs = {
methodName: function(params){
语句...
}
//或者
methodName(){
语句...
}
}
//当我们要调用方法的时候
对象名称.方法名称(参数列表)
再举个当对象已经存在再给他添加方法的栗子,以帮助大家消化
//上面的汽车HongQi_H5现在还不能跑,我们现在给它定义一个跑的方法
function run(){
str=`${this.driver}踩下油门,车子一溜烟跑了。`;
return str;
}
HongQi_H5.run = run;
//当我们要调用的时候
console.log(HongQi_H5.run());
对象在定义的时候给其定义方法:
var iphone15 = {
call: function(num){//格式一
str = `给${num}打电话`;
return str;
},
sendMessage(num){//格式二
str = `给${num}发短信`;
return str;
},
}
console.log(iphone15.call('1334455667'));
console.log(iphone15.sendMessage('1334455667'));
在前面的代码中,我们多次看到this这个词,后面跟着小圆点跟着对象的属性或方法。
如果将对象类型当作一个模板,那么代码中的this,指代的就是这个模板本身。
哪个对象或者对象类型的代码中出现了this,那么这个this就指代的是谁。
getter:是一个获取某个特定属性的值的方法。
setter:是一个设定某个属性的值的方法。
我们可以为预定义的或用户定义的对象定义 getter 和 setter 以支持新增的属性。
使用getter和setter定义的属性是一种伪属性,一般有两种方式为对象定义属性。
第一种:通过对象初始化器进行定义,下面的示例演示的是getter和setter是如何通过对象初始化器进行定义的。
var phone = {
color:'green',
get pcolor(){//pcolor是一个伪属性。
return this.color;
},
set pcolor(v){//setter和getter可以同时设置为同一个伪属性名称。
if(this.color!=v) this.color= v
}
}
phone.pcolor = 'golden';
console.log(phone.pcolor);//golden
console.log(phone.color);//golden
由以上的示例,我们可以看到通过对象初始化器进行定义的setter和getter,其语法为:
对象名称 = {
对象属性1: 属性值1,
get 属性名(){
语句
},
set 属性名(参数){
语句
}
}
第二种: 通过静态方法Object.defineProperties 对一个已经存在的对象添加getter和setter方法。
let myObj = {};//空对象
let tempName;
Object.defineProperty(myObj,'name',{
get (){
return tempName;
},
set (value){
tempName = value;
},
enumerable: true,
configurable: true,
})
myObj.name = 'hello';
console.log(myObj.name);//hello
console.log(tempName);//hello,这说明属性添加成功了,因为经过了中间变量的数据传递。
不难看到,上面这种方法的语法
Object.defineProperty(对象名称, 属性名称, 属性描述符)
属性描述符有两种形式:
1、数据描述符:这种是指一个属性有value,和writable这种描述形式。
value: 属性的值,可以是任何值,默认情况下是undefined
writable:属性的值是否可被写。默认情况下是false,不可写。
2、访问描述符:这种是指一个属性有set和get这种描述形式。
get:用作属性 getter 的函数,如果没有 getter 则为 undefined。当访问该属性时,返回值将被用作该属性的值。默认值为 undefined。
set:用作属性 setter 的函数,如果没有 setter 则为 undefined。当该属性被赋值时,将调用此函数,设置该属性的值。默认值为 undefined。
以上这两种描述形式无法同时存在:就是说,你无法在一个属性拥有Value和writable的同时,再定义上getter和setter。
但是它们都共享有以下共同的可选项:
1、configurable:该可先项所代表的含义是:该属性是否可在数据属性和访问器属性之间进行切换;该属性是否要以被删除;其他属性是否可被更改。
其默认值是false,代表的意义是:
a、该属性的类型不能在数据属性和访问器属性之间更改;
b、该属性不可被删除
c、其描述符的其他属性也不能被更改(但是,如果它是一个可写的数据描述符,则 value 可以被更改,writable 可以更改为 false)。
2、enumerable:该属性是否可被枚举。值为 true时代表该属性可以被枚举。默认值为 false,该属性不可被枚举。
通过delete操作来删除一个不是继续过来的属性,如果对象的属性不是自有的,而是从其对象原型继承而来的,则无法被删除。其语法如下:
let myObj = {};//空对象
let tempName;
Object.defineProperty(myObj,'name',{
get (){
return tempName;
},
set (value){
tempName = value;
},
enumerable: true,
configurable: true,
})
myObj.name = 'hello';
console.log(myObj.name);//hello
console.log(tempName);//hello,这说明属性添加成功了,因为经过了中间变量的数据传递。
delete myObj.name; //删除name属性
console.log(myObj.name);//undefined,该属性不存在,被删除了。