与JavaScript恋爱之对象的三个属性

一、原型属性
1、对象的原型属性是用来继续属性的,这个属性云云主要,我们一般称为:对象的原型属性或对象的原型。
对象的原型是在对象实例化的时刻就设置好的:
(1)、经由过程对象直接量建立的对象的原型是Object.prototype
(2)、经由过程(new+组织函数)的体式格局建立的对象的原型是(组织函数的prototype属性) 如:var arr=new Array(),arr的原型是:Array.prototype
(3)、经由过程new create(),建立的对象的原型是该要领的第一个参数,如: var obj=new create(o);obj的原型是o
2、检测对象的原型要领:
1、o.isPrototypeOf(p),(o为原型,p为要检测的对象):

var o={x:0,y:1};
var p=new create(o);
o.isPrototypeOf(p);    //true
Object.prototype.isPrototypeOf(p);  //true

上面例子中经由过程new create()建立对象,o作为p的原型,o为字面两建立的对象,o的原型是Object.prototype,
p继续了o的属性,o继续了Object.prototype的属性,所以p继续了oObject.prototype的属性,形成了一个原型链,所以Object.prototypep的原型(能够理解为最上游的原型)。
2、o.constructor.prototype,(o为要检测的对象):
new+组织函数建立的对象继续了一个叫constructor的属性,该属性指代该组织函数,o.constructor.prototypeo的原型。运用直接量建立的对象,也有一个叫constructor的属性,该属性指代Object组织函数,所以直接量建立的对象的真正原型是:o.constructor.prototype,运用o.constructor.prototype要领来检测对象的原型并不牢靠,在今后的文章中会提到。
3、在ECMAScript5中,Object.getPrototypeOf(o)这个要领来猎取对象的原型,这个要领IE8及以下不支持。
二、类属性
对象的类属性(class)是一个字符串,ECMAScript3和ECMAScript5没有供应设置对象类的要领,有一种间接的要领接见对象类的属性:toString(),该要领继续自Object.prototype返回字符串"[Object class]",我们只需取返回字符串的下标为8-1的字符串就猎取了对象的类属性class了,然则有许多的自定义对象重写了toString()要领,猎取对象的类属性时须挪用Function.call()要领,下面是返回恣意对象的类属性的classOf()函数:

function classOf(o){
   if(o===null) return "Null";
   if(o===undefined) return "Undefined";
   return Object.prototype.toString().call(o).slice(8,-1);
}
classOf(1);  //"Number"
classOf(""); //"String"
classOf(new Array()); //"Array"
classOf(new Date());   //"Date"
classOf(new RegExp()); //"RegExp"
classOf(true);  //"Boolean"
classOf({});  //"Object"
classOf(window); //"window"(客户端的宿主对象)
function F(){}   //自定义一个组织函数
classOf(new F());   //"Object",关于自定义的对象没法区分类

三、可扩大性
对象的可扩大性示意对象是不是能够增加新的属性,内置对象和自定义对象默许都是可扩大的,能够经由过程要领设置为不可扩大的,宿主对象的可扩大性是由javascript的引擎定义的。
1、查询对象的可扩大性,Object.isExtensible(),参数传入要查询的对象,如:

var obj={};
Object.isExtensible(obj); //该要领IE8及以下不支持

2、设置对象的可扩大性,
(1)、Object.preventExtensions(),参数传入要设置的对象,一旦对象的可扩大性设置为不可扩大的,就没法复原为可扩大的了,但不影响对象的继续属性,经由过程在对象的原型中增加属性,这个不可扩大的对象任然会继续原型新增加的属性。运用该要领后,对象:不可扩大、可设置、可写。(可罗列不受影响,存取器属性不受影响)
(2)、Object.seal(),参数传入要设置的对象,该要领可设置对象为不可扩大的和对象的属性是不可设置的,也就是说对象不能增加新的属性,不能设置和删除该对象属性,然则该对象的可写的属性任然能够设置。运用该要领后,对象:不可扩大、不可设置、可写。(可罗列不受影响,存取器属性不受影响)
(3)、Object.freeze(),参数传入要设置的对象,”凝结”对象,运用该要领后,对象:不可扩大、不可设置、不可写。(可罗列不受影响,存取器属性不受影响)

       var obj=Object.seal(Object.create(Object.freeze({x:1}),{
              y:{value:2,writable:true},
              z:{value:3,writable:true}
       }));
       obj.x=-1;
       obj.y=-2
       obj.x; //1,Object.freeze({x:1});设置该对象不可扩大、不可设置、不可写
       obj.y;//-2,Object.seal(),设置该对象为不可扩大、不可设置、没有设置对象的可写性

上面例子中Object.create()建立了一个对象原型是Object.freeze({x:1});原型是不可扩大的,继续属性x不可设置,不可写。自有属性有yzyz的属性描述符如例子中所示,是可写的,不可设置,不可罗列,Object.seal()传入了建立的对象,使得对象:不可扩大,对象内里的属性:不可设置,但没有影响可写性和可罗列性。

    原文作者:君莫言
    原文地址: https://segmentfault.com/a/1190000007739829
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞