构造函数
通过同一个构造函数创建的对象,我们称为一类对象,也将一个构造函数称为一个类。我们通过一个构造函数创建的对象,称为该类的实例
一、构造函数创建
- 构造函数模式
function Person(name,age){
this.name = name;
this.age = age;
this.sayHello = function(){};
}
var per1 = new Person('猪八戒',20);
- 工厂模式创建
function Person(name,age){
var obj = {
name:name,
age:age,
sayHello:function(){}
}
}
var per1 = Person('唐僧',23);
二、构造函数与普通函数的区别
- 构造函数的命名首字母通常大写
- 调用方式不同,构造函数通过 new 关键字调用,普通函数通过函数名() 调用
- 返回值不同,构造函数返回当前对象,普通函数的返回值由 return 决定,不写 return 则返回 undefied
- this 指向不同,构造函数指向当前调用对象,普通函数指向 windows{} 对象
- 构造函数通过 new 调用的时候,没有参数可以省略 ()
三、对象检测
- 使用 instanceof 关键字检测一个对象是否是一个类的实例(是否由这个构造函数创建)
- 语法:对象 instaceof 构造函数
- 返回值 :true / false
- 所有的对象都是Object 的后代
- 任何对象 instanceof Object => 得到的结果都是 true
四、对象的方法(.defineProperty(对象名 , ‘添加的属性名’{}))
- 删除对象的属性:
delete obj.name
//删除 obj 对象的 name 属性 - 通过 .definrProperty(obj , ‘属性值’,{})进行添加属性
- 这个方法中的属性默认值都是 false ( 例如 configurable:fasle )
var obj = {
name:'小花',
ID:'42000019981023512x',
num:0
};
Object.defineProperty(obj,'height',{
configurable:false, // true(false表示不能被删除)
enumerable:false, //true(true 表示可以被for ... in 进行遍历)
writable:false, // false (true 表示可以更改)
value:200
});
console.log(delete obj.height);//设置不可删除后,返回false 且不生效
for (var i in obj){
console.log(obj[i]);//只能输出 小花 ,添加的 height:200 因为设置不可遍历
}
obj.height = 100; //更改 obj 的 height 为 100
console.log(obj.height);//输出 200 ,因为设置不可更改
console.log(obj);
4.访问器属性
读取访问器属性,自动调用get()
设置访问器,自动调用set(),
get:function(){}
①可以通过 get:function(){} 进行运算再给添加给属性,当去读取的时候就会调用
②访问器 get 和可写属性 writable 不能同时存在 ,所以 get 访问器的值是一定不可更改的
Object.defineProperty(obj,'sex',{
// writable:false, //访问器和可写属性不能同时存在
get:function(){
if(this.Id[16]%2 == 0){
return '女';
}else{
return '男';
}
}
});
console.log(delete obj.sex);//get()中您默认 configurable:false,所以删除无效
console.log(obj.sex);
obj.sex = 'nv'; //因为访问器和可写属性不能同时存在,所以 get 访问器的值是一定不可更改的
console.log(obj.sex);//男
set:function(){}
①通过 set() 对对象内部别的属性值做递增,递减操作
Object.defineProperty(obj,'add',{
set(value){//这种写法等同于 set:function(){}
this.num += value;
}
});
obj.add = 5;//相当于把 obj.add 的值代入进去做运算, this.num = this.num + 5;
obj.add = 5;//再做一次加5操作
console.log(obj.num);//10
五、.defineProperties(对象名 , { 属性值:{ value:属性值,}}) (一次添加多个值)
function Person(name,id,birthday){
Object.defineProperties(this,{
name:{
value:'唐僧',
configurable:false, // true(false表示不能被删除)
},
id:{
value:id,
},
birthday:{
value:birthday,
},
sex:{
get() {
return this.id[16] % 2 == 0? '女':'男';
}
},
age:{
get() {
return (new Date(Date.now() - new Date(this.birthday).getTime())).getFullYear() - 1970;
}
}
})
}
var obj = new Person('孙悟空','420000199910234512','1999-10-23');
console.log(obj);
六、获取当前对象属性的详细信息
重点:这里的属性一定加引号
//Object.getOwnPropertyDescriptor(要获取的对象,要获取的属性)
var name1 = Object.getOwnPropertyDescriptor(obj,"name");//这里的 name 必须加引号
console.log(name1);//{value: "孙悟空", writable: false, enumerable: false, configurable: false}
// value: "孙悟空"
// writable: false
// enumerable: false
// configurable: false
// __proto__: Object
七、遍历对象
1、for( var i in obj)
var obj = {
name:'小花',
ID:'42000019981023512x',
num:0
};
for(var i in obj){
console.log(i);//这里的 i 是所有的属性名,上面提到过一个属性叫 enumerable:false,当值为false的时候,该值不会被遍历
console.log(obj[i]);//该方式可以拿到所有的属性值,因为 i 是一个变量,防止被添加成 obj 的属性,我们用 []
}
2、Object.keys
var n = Object.keys(obj);//这里得到的结果是数组,拿出所有的属性组成数组
console.log(n);//["name", "ID", "num"]
n.forEach(function(value,index,array){
console.log(obj[value]);//再通过数组遍历的方式就可以获取所有的属性值了
})
3、Object.getOwnPropertyNames(obj)
唯一的区别是这个方法可以拿到添加 enumerable:false 的值
var n = Object.getOwnPropertyNames(obj);//这里得到的结果是数组,拿出所有的属性组成数组
console.log(n);//["name", "ID", "num"]
n.forEach(function(value,index,array){
console.log(obj[value]);//再通过数组遍历的方式就可以获取所有的属性值了
})
八、判断对象中是否存在某属性
1、‘属性名’ in obj
重点:属性名一定要加引号,不加引号相当于是一个变量
console.log('name' in obj);//返回值为 true 则有,反之没有
2、obj.hasOwnProperty(‘name’)
重点:属性名一定要加引号,不加引号相当于是一个变量
obj.hasOwnProperty('name');//返回值为 true 则有,反之没有