ECMAScript5 新特性(1)
Function 1: Object.create
这是一个很重要的改动,现在我们终于可以得到一个原型链干净的对象了。以前要创建一个类
function Cat(name) { this.name = name; this.paws = 4; this.hungry = false; this.eaten = []; } Cat.prototype = { constructor : Cat, play : function () { this.hungry = true; return 'playing!'; }, feed : function (food) { this.eaten.push(food); this.hungry = false; }, speak : function () { return 'Meow'; } };
必须要分两步走,但是现在可以不必了
var Dog = { name : 'dog', paws : 4, hungry : false, eaten : null, play : function () { this.hungry = true; return 'playing!'; }, speak : function () { return 'Woof!'; } }; var dog = Object.create(Dog);
Object.create他还有第2个参数,是一个properties descriptor object ,关于这方面的详细解释,请看第2点。
另外:如果浏览器不支持Object.create,可以用这种方法代替
if (typeof Object.create !== 'function') { Object.create = function (o) { function F() {} F.prototype = o; return new F(); }; }
Browser Support
○ Firefox 4
○ Internet Explorer 9
○ Safari 5
○ Chrome 5+
Function 2: Object.defineProperty
如果你想为一个对象定义属性,那么就必须my_dog.age = 2; 用这种方法。但是在ECMAScript5中,提供了更好的包装方法Object.defineProperty
Parameters:
1.对象引用
2.属性名
3.修饰对象
修饰对象中的定义如下:
● value:
use this to set the value of a property. Defaults
to undefined
.
● writable:
use this boolean to define whether this is a read-only variable. If
it’s writable, it’s true
.
Defaults to false
.
● configurable:
use this boolean to define whether the type (value vs. method) of
this property can be changed, or whether the property can be deleted.
If it’s configurable, it’s true
.
Defaults to false
.
● enumerable:
use this boolean to define whether this property is included when the
properties of the object are enumerated (a for-in
loop
or the keys method). Defaults to false
.
● get:
use this to define a custom getter method. Defaults to undefined
.
● set:
use this to define a custom setter method. Defaults to undefined
.
Sample:
var Dog = { name : 'dog', paws : 4 }; var dog = Object.create(Dog); Object.defineProperty(dog, 'age', { set : function (age) { this.humanYears = age * 7; }, get : function () { return this.humanYears / 7; }, enumerable : true }); dog.age = 2; dog.humanYears; // 14
以上代码让age和humanYears保存了同步,如果你不想对外界暴露humanYears,可以这样使用闭包:
Object.defineProperty(dog, 'age', (function () { var humanYears; return { set : function (age) { humanYears = age * 7; }, get : function () { return humanYears / 7; }, enumerable : true }; }()));
当然,也可以用在Object.create方法上面
var yourDog = Object.create(Dog, { age : { get : function () { /* . . . */ }, set : function () { /* . . . */ }, enumerable: true }, gender : { value : 'female' } });
Browser Support
○ Firefox 4
○ Internet Explorer 9
○ Safari 5
○ Chrome 5+
Function 3: Object.defineProperties
当然,如果你想像Object.create方法那样一口气给对象加入很多属性的话,你可以用Object.defineProperties方法
Object.defineProperties(dog, { age : { get : function () { /* . . . */ }, set : function () { /* . . . */ }, enumerable: true }, gender : { value : 'female' } });
注意区别 Object.create和Object.defineProperties第一个参数的不同,Object.create是prototype,而Object.defineProperties是对象
Browser Support
○ Firefox 4
○ Internet Explorer 9
○ Safari 5
○ Chrome 5+
悲剧,可怜的4,穿越了。
标准上个月才升级,那到浏览器支持还有的等呢,说不定5也会胎死腹中
以前用构造函数+原型链的方法要分2步走。用动态原型又不支持继承。相当麻烦,一般只好引入第三方框架。现在可以一步到位了还是不错的。
但是要等到浏览器支持估计还是要比较久的。
○ Firefox 4
○ Internet Explorer 9
○ Safari 5
○ Chrome 5+
哥哥,您的文章我仔细看了才回帖的。这些浏览器真的普及了吗。程序员用的多,不代表用户普及了。何况这些浏览器,就是在程序员群体中恐怕也不能说普及了。
var objDefinition = { "test" : function(){} };var instance = new objDefinition();
我靠 知音啊
----------
我倒觉得完全不可用,倒是好事。早点淘汰。
VML 而已
</p>
<pre name="code" class="js">改自OpenLayers框架...</pre>
<pre name="code" class="js">Class = function() {
var len = arguments.length;
var P = arguments[0];
var F = arguments[len - 1];
var C = typeof F.initialize == "function" ? F.initialize : function() {
P.apply(this, arguments);
};
if (len > 1) {
var newArgs = [ C, P ].concat(Array.prototype.slice.call(arguments)
.slice(1, len - 1), F);
inherit.apply(null, newArgs);
} else {
C.prototype = F;
C.prototype.superclass = [];
}
if(C.prototype.tsuperclass){
C.prototype.superclass = C.prototype.tsuperclass;
delete C.prototype.tsuperclass;
}
return C;
}</pre>
<p> </p>
<p> </p>
<p>
</p>
<pre name="code" class="js">inherit = function(C, P) {
var F = function() {
};
F.prototype = P.prototype;
C.prototype = new F;
C.prototype.tsuperclass = [];
addUnique(C.prototype.tsuperclass, P);
var i, l, o;
for (i = 2, l = arguments.length; i < l; i++) {
o = arguments[i];
//strict equal
if (typeof o === "function") {
addUnique(C.prototype.tsuperclass, o);
o = o.prototype;
}
extend(C.prototype, o);
}
};</pre>
<p> </p>
<p> </p>
<p>
</p>
<pre name="code" class="js">extend = function(destination, source) {
destination = destination || {};
if(source) {
for(var property in source) {
var value = source[property];
if(value !== undefined) {
destination[property] = value;
}
}
/**
* IE doesn't include the toString property when iterating over an object's
* properties with the for(property in object) syntax. Explicitly check if
* the source has its own toString property.
*/
/*
* FF/Windows < 2.0.0.13 reports "Illegal operation on WrappedNative
* prototype object" when calling hawOwnProperty if the source object
* is an instance of window.Event.
*/
var sourceIsEvt = typeof window.Event == "function"
&& source instanceof window.Event;
if(!sourceIsEvt
&& source.hasOwnProperty && source.hasOwnProperty('toString')) {
destination.toString = source.toString;
}
}
return destination;
};</pre>
<p> </p>
<p> </p>
<p>
</p>
<pre name="code" class="js">addUnique = function(current, obj){
if(!current||!obj){
return;
}
if(Kay.Util.indexOf(current, obj) != -1){
return;
}
current.push(obj);
};</pre>
<p> </p>
<p>有了以上四个方法, 就可以这样定义类了</p>
<p>
</p>
<p style="margin: 0px;"><span style="white-space: pre;"><br></span></p>
<pre name="code" class="js"> var Dog = Class({</pre>
<pre name="code" class="js"> name:null,</pre>
<pre name="code" class="js"> bite:function(another){
console.debug(this.name + ' bite ' + another.name + ' !');
},
getFeatures:function(){
return '两只眼睛, 四只脚, 一条尾巴, 一张嘴';
},
initialize:function(options){
extendz(options, this);
//init
}
});
var JAPADog = Class(Dog, {
from:'鸡国',
getFeatures:function(){
return Dog.prototype.apply(this, arguments) + (this.from + '的');
}
});
var doga = new Dog({name:'小犬惷一郞'});
var dogb = new JAPADog({name:'小犬笨二郞'});</pre>
doga.bite(dogb);
<div class="quote_div">
<p> </p>
<pre name="code" class="js">改自OpenLayers框架...</pre>
<pre name="code" class="js">Class = function() {
var len = arguments.length;
var P = arguments[0];
var F = arguments[len - 1];
var C = typeof F.initialize == "function" ? F.initialize : function() {
P.apply(this, arguments);
};
if (len > 1) {
var newArgs = [ C, P ].concat(Array.prototype.slice.call(arguments)
.slice(1, len - 1), F);
inherit.apply(null, newArgs);
} else {
C.prototype = F;
C.prototype.superclass = [];
}
if(C.prototype.tsuperclass){
C.prototype.superclass = C.prototype.tsuperclass;
delete C.prototype.tsuperclass;
}
return C;
}</pre>
<p> </p>
<p> </p>
<p> </p>
<pre name="code" class="js">inherit = function(C, P) {
var F = function() {
};
F.prototype = P.prototype;
C.prototype = new F;
C.prototype.tsuperclass = [];
addUnique(C.prototype.tsuperclass, P);
var i, l, o;
for (i = 2, l = arguments.length; i < l; i++) {
o = arguments[i];
//strict equal
if (typeof o === "function") {
addUnique(C.prototype.tsuperclass, o);
o = o.prototype;
}
extend(C.prototype, o);
}
};</pre>
<p> </p>
<p> </p>
<p> </p>
<pre name="code" class="js">extend = function(destination, source) {
destination = destination || {};
if(source) {
for(var property in source) {
var value = source[property];
if(value !== undefined) {
destination[property] = value;
}
}
/**
* IE doesn't include the toString property when iterating over an object's
* properties with the for(property in object) syntax. Explicitly check if
* the source has its own toString property.
*/
/*
* FF/Windows < 2.0.0.13 reports "Illegal operation on WrappedNative
* prototype object" when calling hawOwnProperty if the source object
* is an instance of window.Event.
*/
var sourceIsEvt = typeof window.Event == "function"
&& source instanceof window.Event;
if(!sourceIsEvt
&& source.hasOwnProperty && source.hasOwnProperty('toString')) {
destination.toString = source.toString;
}
}
return destination;
};</pre>
<p> </p>
<p> </p>
<p> </p>
<pre name="code" class="js">addUnique = function(current, obj){
if(!current||!obj){
return;
}
if(Kay.Util.indexOf(current, obj) != -1){
return;
}
current.push(obj);
};</pre>
<p> </p>
<p>有了以上四个方法, 就可以这样定义类了</p>
<p> </p>
<p style="margin: 0px;"><span style="white-space: pre;"><br></span></p>
<pre name="code" class="js"> var Dog = Class({</pre>
<pre name="code" class="js"> name:null,</pre>
<pre name="code" class="js"> bite:function(another){
console.debug(this.name + ' bite ' + another.name + ' !');
},
getFeatures:function(){
return '两只眼睛, 四只脚, 一条尾巴, 一张嘴';
},
initialize:function(options){
extendz(options, this);
//init
}
});
var JAPADog = Class(Dog, {
from:'鸡国',
getFeatures:function(){
return Dog.prototype.apply(this, arguments) + (this.from + '的');
}
});
var doga = new Dog({name:'小犬惷一郞'});
var dogb = new JAPADog({name:'小犬笨二郞'});</pre>
doga.bite(dogb);</div>
<p> </p>
<p>A!B!C!openlayer会把代码改的这么恶心??</p>
<p> </p>
<p>另外,如果要实现继承,向上转型判断,以及自动调用父类函数请参照我的其他博客,比如:</p>
<p>
</p>
<div style="color: #000000; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; background-color: #ffffff; margin: 8px;">
<div class="quote_title" style="font-weight: bold; margin-top: 5px; margin-right: 0px; margin-bottom: 0px; margin-left: 15px; padding: 5px;"><a href="http://rainsilence.iteye.com/admin/blogs/604418">http://rainsilence.iteye.com/admin/blogs/604418</a></div>
</div>
<p> </p>
<p> </p>
<p> </p>
use this boolean to define whether the type (value vs. method) of this property can be changed”
use this boolean to define whether the type (value vs. method) of this property can be changed”
据我验证,你的验证是错误的,最少chrome14就已经实现了。