Object.defineProperty(myobj.prototype,'length',{ get:function(){ return this.length_; //这里不能是length。 }, /*set:function(value){ return this.length_=value; }*/ }); myobj.length = 3;
这个代码会抛出异常:Uncaught TypeError: Cannot set property length of #<myobj> which has only a getter。
要让对象的属性只读,还可以用writable:false,
Object.defineProperty(myobj.prototype,'length',{ writable:false });
writable:false不能与get set共存,否则会抛出Type Error。
configurable:是否能用delete语句删除,但是configurable属性好像在严格模式下才有效,这样的代码在非严格模式下仍然能执行:(严格模式报错)
Object.defineProperty(myobj.prototype,'length',{ configurable:false }); var obj = new myobj(); delete obj.length;
value:指定该对象的固定值。value:10,表示这个对象初始值为10.
在非严格模式下,这样的代码不会报错,严格模式下会报错:
Object.defineProperty(myobj.prototype,'length',{ writable:false, value:'10' }); var obj = new myobj(); obj.length = 100;
可以用getOwnPropertyDescriptor来获取并修改这些值,比如说,现在我的length属性是只读的。
运行这样的代码,结果却报错了:
Object.defineProperty(myobj.prototype,'length',{ value:, writable:false, }); var descriptor = Object.getOwnPropertyDescriptor(myobj.prototype, "length"); descriptor.writable = true; Object.defineProperty(myobj.prototype,'length',descriptor); Uncaught TypeError: Cannot redefine property: length
这是因为configurable的默认值是false,在调用了defineProperty之后,configurable就具有false属性,这样就不能逆转了。以后就不能改了。
所以必须使用 configurable:true,这个对象属性才是可以修改的,完整的代码如下:
Object.defineProperty(myobj.prototype,'length',{ value:, writable:false, configurable:true }); var descriptor = Object.getOwnPropertyDescriptor(myobj.prototype, "length"); descriptor.writable = true; Object.defineProperty(myobj.prototype,'length',descriptor); myobj.prototype.length = ; var obj = new myobj(); alert(obj.length);
可以加上一句descriptor.configurable = false;
表示这个属性我修改了,以后你们都不能再修改了
这个特性在很多时候也有用,数组Array的push pop等方法,如果使用call、apply,要求对象的length可变。如果对象的length属性只读,那么调用call、apply时,会抛出异常。
就比如DOMTokenList对象,它的length就是不可以变的。我拿到了一个DOM对象DOMTokenList,
但是它的configurable是true,我们可以修改让它的length属性可以变啊:
看见没,这个configurable是true,而setter是undefined,我们给它写一个set方法,不就可以了吗?
var descriptor = Object.getOwnPropertyDescriptor(DOMTokenList.prototype,'length'); descriptor.set = function(value){ this.length = value; } Object.defineProperty(DOMTokenList.prototype,'length',descriptor);
然后运行,
又抛出了一个异常,Uncaught RangeError: Maximum call stack size exceeded(…)
这是因为,我们在set this.length时,它会在我们写的那个set方法中无限递归。
因此,我们需要使用delete消除length属性的影响,也就是:
var descriptor = Object.getOwnPropertyDescriptor(DOMTokenList.prototype,'length'); descriptor.set = function(value){ delete DOMTokenList.prototype.length; this.length = value; } Object.defineProperty(DOMTokenList.prototype,'length',descriptor);
这样,DOMTokenList也就支持了push,pop等等操作了。
Array.prototype.push.call(document.body.classList,'abc')
然后再行封装
DOMTokenList.prototype.push = function(){ Array.prototype.push.call(document.body.classList,Array.prototype.slice.call(arguments)); }
Array.prototype.slice.call(arguments)方法用于把arguments对象转换为数组。
您可能感兴趣的文章: