JavaScript原型链常⽤⽅法
JavaScript 原型链常⽤⽅法
对象属性类型
数据属性
1. Configurable(表⽰能否通过 delete 删除属性从⽽重新定义属性,能否修改属性的特性,或者能否把属性修改为访问器属性)
2. Enumerable(表⽰能否通过 for-in 循环返回属性)
3. Writable(表⽰能否修改属性的值)
4. Value(这个属性的数据值。读取属性值的时候,从这个位置读;写⼊属性值的时候,把新值保存在这个位置。默认值为 undefined)
把 configurable 设置为 fal,表⽰不能从对象中删除属性。如果对这个属性调⽤ delete,则在⾮严格模式下什么也不会发⽣,⽽在严格模式下会导致错误。⼀旦把属性定义为不可配置的,就不能再把它变回可配置了。此时,再调⽤ Object.defineProperty()⽅法修改除 writable 之外的特性,都会导致错误
访问器属性
访问器属性不包含数据值;它们包含⼀对⼉ getter 和 tter 函数(不过,这两个函数都不是必需的)。在读取访问器属性时,会调⽤getter 函数,这个函数负责返回有效的值;在写⼊访问器属性时,会调⽤tter 函数并传⼊新值,这个函数负责决定如何处理数据
访问器属性不能直接定义,必须使⽤ Object.defineProperty()来定义。在不⽀持 Object.defineProperty() ⽅法的浏览器中不能修改Configurable 和Enumerable
1. Configurable(表⽰能否通过 delete 删除属性从⽽重新定义属性,能否修改属性的特性,或者能否把属性修改为数据属性。默认值为
true)
2. Enumerable(表⽰能否通过 for-in 循环返回属性。对于直接在对象上定义的属性)
3. Get(在读取属性时调⽤的函数。默认值为 undefined)
4. Set(在写⼊属性时调⽤的函数。默认值为 undefined)
注意事项:
共同点:数据属性 和 访问器属性均具有以下可选键值:
1. configurable 当且仅当该属性的 configurable 为 true 时,该属性描述符才能够被改变,同时该属性也能从对应的对象上被删除。
2. enumerable 当且仅当该属性的enumerable为true时,该属性才能够出现在对象的枚举属性中。默认为 fal。
如果⼀个描述符不具有value,writable,get 和 t 任意⼀个关键字,那么它将被认为是⼀个数据描述符。如果⼀个描述符同时有(value 或writable)和(get或t)关键字,将会产⽣⼀个异常。
考虑特性被赋予的默认特性值⾮常重要,通常,使⽤**点运算符和Object.defineProperty()**为对象的属性赋值时,数据描述符中的属性默认值是不同的,如下例所⽰。
obj.vfrank =1;
// 等同于 :
Object.defineProperty(obj,"vfrank",{
value:1,
writable:true,
configurable:true,
enumerable:true
});
// 另⼀⽅⾯,蒜蓉大虾怎么做好吃
Object.defineProperty(obj,"vfrank",{ value:1});
// 等同于 :
Object.defineProperty(obj,"vfrank",{
value:1,
writable:fal,
刮痧和拔罐configurable:fal,
enumerable:fal
});
configurable enumerable value writable get t
数据属性(数据描述符)Yes Yes Yes Yes No No
访问器属性(存取描述符)Yes Yes No No Yes Yes Object.defineProperty() 和 Object.defineProperties()
定义
1. Object.defineProperty() ⽅法会直接在⼀个对象上定义⼀个新属性,或者修改⼀个对象的现有属性, 并返回这个对象**(IE8 部分
⽀持)**。
2. Object.defineProperties() ⽅法直接在⼀个对象上定义新的属性或修改现有属性,并返回该对象(IE9+)。
IE8 是第⼀个实现 Object.defineProperty()⽅法的浏览器版本。然⽽,这个版本的实现存在诸多限制:
只能在 DOM 对象上使⽤这个⽅法,⽽且只能创建访问器属性。由于实现不彻底,建议不要在 IE8 中使⽤ Object.defineProperty()⽅法
返回指定对象上⼀个⾃有属性对应的属性描述符。(⾃有属性指的是直接赋予该对象的属性,不需要从原型链上进⾏查找的属性)
可以取得给定属性的描述符。这个⽅法接收两个参数:属性所在的对象和要读取其描述符的属性名称。返回值是⼀个对象,如果是访问器属性,这个对象的属性有 configurable、enumerable、get 和 t;如果是数据属性,这个对象的属性有 configurable、enumerable、writable 和 value。
Object.defineProperties(vfrank,{
_year:{
value:2019
},
edition:{
value:1
},
year:{
get:function(){
return this._year;
},
t:function(newValue){
if(newValue >2019){
this._year = newValue;讲的成语
this.edition += newValue -2019;
}
}
}
});
// 数据属性
var descriptor = OwnPropertyDescriptor(vfrank,"_year");
console.log(descriptor.value);//2019
console.figurable);//fal
console.log();//"undefined"
// 访问器属性
var descriptor = OwnPropertyDescriptor(vfrank,"year");
console.log(descriptor.value);//undefined
console.umerable);//fal
console.log();//"function"
instanceof 运算符
obj instanceof classConstructor
instanceof运算符⽤于测试构造函数的prototype属性是否出现在对象的原型链中的任何位置(即:object是否属于classConstructor)
function VFrank(name, work, age){
绽的读音
this.name = name;
this.work = work;
this.age = age;
}
发了
var person =new VFrank('VFrank','Web engineer',24);
console.log(person instanceof VFrank);// true
console.log(person instanceof Object);// true
isPrototypeOf()
prototypeObj.isPrototypeOf(obj)
⽤于测试⼀个对象是否存在于另⼀个对象的原型链上。在obj对象原型链上搜寻
VFrank.prototype.name ="vfrank";
VFrank.prototype.age =29;
VFrank.prototype.job ="Web Engineer";
var person =new VFrank();
console.log(VFrank.prototype.isPrototypeOf(person));// PrototypeOf()
返回指定对象的原型(内部[[Prototype]]属性的值)
function VFrank(){}
药膳养生VFrank.prototype.name ="vfrank";
VFrank.prototype.age =29;
VFrank.prototype.job ="Web Engineer";
var person =new VFrank();
console.PrototypeOf(person));
// {name: "vfrank", age: 29, job: "Web Engineer"} hasOwnProperty()
obj.hasOwnProperty(prop)
obj对象⾃⾝属性中是否具有prop的属性举措和措施的区别
function VFrank(){}
VFrank.prototype.name ="vfrank";
VFrank.prototype.age =29;
VFrank.prototype.job ="Web Engineer";
var person =new VFrank();
console.log(person.name);//"vfrank" 来⾃原型链
console.log(person.hasOwnProperty("name"));//fal
person.name ="GongGe";
console.log(person.name);//"GongGe"——来⾃实例
console.log(person.hasOwnProperty("name"));//true
delete person.name;
console.log(person.name);//"vfrank"——来⾃原型
console.log(person.hasOwnProperty("name"));//fal
in 操作符
VFrank.prototype.name ="vfrank";
VFrank.prototype.age =29;
VFrank.prototype.job ="Web Engineer";
var person =new VFrank();
console.log(person.name);//"vfrank" ——来⾃实例
console.log(person.hasOwnProperty("name"));//fal
console.log("name"in person);//true
person.name ="GongGe";古诗词起名
console.log(person.name);//"GongGe" ——来⾃实例
console.log(person.hasOwnProperty("name"));//true
console.log("name"in person);//true
delete person.name;
console.log(person.name);//"vfrank" ——来⾃原型
console.log(person.hasOwnProperty("name"));//fal
console.log("name"in person);//true
同时使⽤ hasOwnProperty()⽅法和 in 操作符,就可以确定该属性到底是存在于对象中,还是存在于原型中
IE 早期版本的实现中存在⼀个 bug,即屏蔽不可枚举属性的实例属性不会出现在 for-in 循环中
var obj ={
toString:function(){
return"Hellp VFrank";
}
};
for(var prop in obj){
if(prop =="toString"){
console.log("Found toString Hellp VFrank");//在 IE 中不会显⽰(书上写的)
// 真实测试IE11 edge中还是会有,使⽤仿真的也会出来,需要⽤真实版IE低版本测试下
}
}
getOwnPropertyNames()
返回⼀个由指定对象的所有⾃⾝属性的属性名(包括不可枚举属性但不包括Symbol值作为名称的属性)组成的数组。(Object.keys()是列举可枚举属性)
数组中枚举属性的顺序与通过 for…in 循环(或 Object.keys)迭代该对象属性时⼀致。数组中不可枚举属性的顺序未定义。
function VFrank(){}
VFrank.prototype.name ="vfrank";
VFrank.prototype.age =29;
VFrank.prototype.job ="Web Engineer";
var person =new VFrank();
console.OwnPropertyNames(VFrank.prototype));// ["constructor", "name", "age", "job"]
console.log(Object.keys(VFrank.prototype));// ["name", "age", "job"]