对象属性分为数据属性
与访问器属性
数据属性
属性特性描述
- configurable(true):能否通过delete删除属性从而重新定义
- enumerable(true):能否通过for-in循环遍历到属性
- writable(true):能否修改属性的值
- value(undefined):包含这个属性的数据值
注:数据属性的设定需使用Object.defineProperty(object,object.key,{writable:…})
坑点,直接通过Object.defineProperty添加的属性,writable默认为false,也就是当前属性默认不可修改
var person = {
age: 18
};
Object.defineProperty(person, "name", {
//writable:true,
value: "steven"
})
console.log(person.name); //steven
person.name = 'killer';
使用Object.defineProperty设定的属性默认不可修改
console.log(person.name); //steven
访问器属性
属性特性描述
- configurable(true):能否通过delete删除属性从而重新定义
- enumerable(true):能否通过for-in循环遍历到属性
- Get(undefined):读取属性时调用函数
- Set(undefined):写入属性是调用函数
注:访问器属性的设定需使用Object.defineProperty(object,object.key,{writable:…})
注:Object.defineProperties可一次访问、设置多条属性
var book={};
Object.defineProperties(book,{
_year:{
writable:true,
value:4000
},edition:{
writable:true,
value:32
}
});
读取属性特性
var book={};
Object.defineProperties(book,{
_year:{
writable:true,
value:4000
},edition:{
writable:true,
value:32
}
});
var descriptor=Object.getOwnPropertyDescriptor(book,"_year");
console.log(descriptor.value); //4000
console.log(descriptor.configurable); //false
instanceof
对象检测
检测一个对象是否是另一个对象的实例
var arr=new Array();
console.log(arr instanceof Array); //true
console.log(arr instanceof String); //false
构造函数
构造函数可用来创建特定类新的对象。
//DEMO
function man(name,age,speak){
this.name=name;
this.age=age;
this.describe=function(){
console.log(name+'said that'+speak);
};
}
//使用构造函数实例化对象
var man1=new man('steven',20,'do it yourself');
找到实例化成功对象的构造函数
console.log(man1.constructor); //man函数
console.log(man1.constructor==man); //true
prototype原型模式
只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。
代码示例
//创建函数,给函数给prototype上添加一些属性(可以是值也可以是函数)
function person(){}
person.prototype.name='steven';
person.prototype.age='35';
person.prototype.price='300K';
person.prototype.say=function(){
console.log('Hello world!');
};
console.log(person.name);
//使用new方法实例化一个pp函数的对象,该函数对象会继承person函数在prototype上面定义的所有方法
var person1=new person();
//当使用继承的属性时会默认查找自身是否定义过相关的方法,如果没定义过会再去其继承的prototype上边查找
console.log(person1.name); //steven
person1.name='qc';
console.log(person1.name); //qc
hasOwnProperty
判断属性是否来自来自实例
function people () {}
people.prototype.name='lbsen';
var people1=new people();
console.log(people1.hasOwnProperty("name")); //false
console.log(people1.name); //lbsen 来自原型
people1.name='nicholas';
console.log(people1.hasOwnProperty("name")); //true
console.log(people1.name); //nicholas 来自实例
delete.people1.name;
console.log(people1.name); //lbsen 来自原型
代码解析
- 创建函数people,并给people的prototype上绑定name。
- 创建一个people的实例person1,console发现people1.hasOwnProperty为false,因为hasOwnProperty是用来判断(函数)对象自身是否含有name属性。
- 给people1的name属性赋值后,people1.hasOwnProperty(“name”)变为true
- 使用delete删除name后,发现其原型链上的name属性还在,说明delete方法只能删除其自身添加的属性,无法删除通过prototype继承的属性
in
判断对象是否包含某属性
console.log('name' in people1); //true
delete.people1.name;
console.log('name' in people1); //true
判断people1是否有可用的属性name,无论找到其自身的name属性还是来自prototype的属性,都会返回true,否则返回false
Object.key()枚举属性
function man () {}
man.prototype.sex='male';
man.prototype.age='20';
man.prototype.job='teacher';
man.prototype.sayName=function(){
console.log(this.name);
}
var man1=new man();
man1.name='tom';
man1.height='60kg';
console.log(Object.keys(man1));
//["name", "height"] 枚举对象实例属性
console.log(man1.constructor.prototype);
//获取到man1原型的prototype方法
console.log(Object.keys(man1.constructor.prototype));
//["sex", "age", "job"] 枚举对象原型属性
- Object.keys(Object) 枚举对象实例属性
- Object.keys(Object.constructor.prototype) 枚举对象原型属性
原型链的简单封装
man.prototype.sex='male';
man.prototype.age='20';
man.prototype.job='teacher';
man.prototype.sayName=function(){
console.log(this.name);
}
对于以上代码,我们其实可以这么写
man.prototype = {
sex: 'male',
age: '20',
job: 'teacher',
sayName: function() {
console.log(this.name);
}
}
查看各类对象的原生方法(举一反三)
之前利用constructor找到了实例化的对象通过prototype继承的方法,于是我突然想到,平时我们用到的布尔值、字符串、数组、字符串、数字等都属于对象。
平时你一定用过这种方式创建一个空数组。
var arr= new Array();
平时我们用的处理数组的各种方法其实都是基于prototype继承,比如push、shift、pop等等,不信?那就控制台把这些方法都打出来好了
var arr=new Array();
console.log(arr.constructor.prototype);
控制台效果如下,以下就是原声js对于数组对象的所有方法。
有没有感觉醍醐灌顶,如果没有赶紧再看一遍…
除此以外,你还可以用类似的方法查看布尔值、字符串、字符串、数字等对象的原声方法。
var arr=new Array();
console.log(arr.constructor.prototype);
var obj=new Object();
console.log(obj.constructor.prototype);
var num=new Number();
console.log(num.constructor.prototype);
var fun=new Function();
console.log(fun.constructor.prototype);
var bool=new Boolean();
console.log(bool.constructor.prototype);
- 以上输出的prototype方法的数据类型都是对象
- 以上对象无法通过for-in循环遍历输出对应方法,因为prototype对象属性的默认配置是enumerable:false
- 不知道enumerable:false是什么意思的请面壁,然后看看本文最开始关于数据属性特性描述中的内容