将getter作为原型编写
Write getters as a prototype
我正在对我的javascript代码进行性能更新。
在Firefox中,我得到了这个警告:
改变对象的[[Prototype]]将导致你的代码运行非常慢;相反,使用object .create
创建具有正确初始[[Prototype]]值的对象
我写了一些脚本来证明这一点,结果很好:没有突变,一个简单的脚本运行速度快了66%。
但是我有麻烦转换我的代码没有突变,我不能写getter:
这是我现在的文件:
// Class
function FooBar(options) {
this.options = options;
}
// Prototype
FooBar.prototype = {
// Getters
get a() {
return this.options.a;
},
get b() {
return this.options.b;
},
get ab() {
return this.options.a + this.options.b;
},
// Methods
displayOptions: function() {
console.log(this.options);
}
};
// Code
var options = {
a: 'foo',
b: 'bar'
};
var fooBar = new FooBar(options);
console.log(fooBar.a);
console.log(fooBar.b);
console.log(fooBar.ab);
fooBar.displayOptions();
作为原型的getter在返回时使用this关键字是问题所在。
如果我使用Object.defineProperty,则this关键字是错误的,除非我在构造函数中这样做,但它会在类的每个实例上重新创建属性,并进一步减慢我的代码速度。
这工作(我只是搞砸了语法在我之前的尝试):
// Class
function FooBar (options) {
this.options = options;
}
//Prototype getters
Object.defineProperty(FooBar.prototype, 'a', {
get: function() {
return this.options.a;
}
});
Object.defineProperty(FooBar.prototype, 'b', {
get: function() {
return this.options.b;
}
});
Object.defineProperty(FooBar.prototype, 'ab', {
get: function() {
return this.options.a + this.options.b;
}
});
// Methods
FooBar.prototype.displayOptions = function() {
console.log(this.options);
};
// Code
var options = {
a:'foo',
b:'bar'
};
var fooBar = new FooBar (options);
console.log(fooBar.a);
console.log(fooBar.b);
console.log(fooBar.ab);
fooBar.displayOptions();
对于那些对将这样的脚本转换为更快运行的好处感到好奇的人:运行以下代码并在控制台中查看您的输出(Chrome -快66%,Firefox -没有区别(好奇,因为我得到了Firefox的警告)):
// WITHOUT PROTOTYPING
var Person1 = function() {
this.name = 'myName';
this.changeName = function(name) {
this.name = name;
};
this.changeName2 = function(name) {
this.name = name;
};
this.changeName3 = function(name) {
this.name = name;
};
this.changeName4 = function(name) {
this.name = name;
};
}
// WITH PROTOTYPING, WITH MUTATION
var Person2 = function() {
this.name = 'myName';
}
Person2.prototype = {
changeName: function(name) {
this.name = name;
},
changeName2: function(name) {
this.name = name;
},
changeName3: function(name) {
this.name = name;
},
changeName4: function(name) {
this.name = name;
}
};
// WITH PROTOTYPING, WITHOUT MUTATION
var Person3 = function() {
this.name = 'myName';
}
Person3.prototype.changeName = function(name) {
this.name = name;
};
Person3.prototype.changeName2 = function(name) {
this.name = name;
};
Person3.prototype.changeName3 = function(name) {
this.name = name;
};
Person3.prototype.changeName4 = function(name) {
this.name = name;
};
// DO THE TEST
var i=0, len=1000000;
// TEST1
window.performance.mark('mark_test_start');
for(i=0;i<len;i++) {
p = new Person1();
p.changeName('myName2');
}
window.performance.mark('mark_test_end');
window.performance.measure('no-prototyping', 'mark_test_start', 'mark_test_end');
// TEST2
window.performance.mark('mark_test2_start');
for(i=0;i<len;i++) {
p = new Person2();
p.changeName('myName2');
}
window.performance.mark('mark_test2_end');
window.performance.measure('prototyping-with-mutation', 'mark_test2_start', 'mark_test2_end');
// TEST3
window.performance.mark('mark_test3_start');
for(i=0;i<len;i++) {
p = new Person2();
p.changeName('myName2');
}
window.performance.mark('mark_test3_end');
window.performance.measure('prototyping-without-mutation', 'mark_test3_start', 'mark_test3_end');
// OUTPUT tests
var items = window.performance.getEntriesByType('measure');
for (var i = 0; i < items.length; ++i) {
var req = items[i];
console.log(req.name + ': ' + req.duration.toFixed(2));
}
相关文章:
- 使用“;这个“;JavaScript原型方法中的关键字
- 查看JS对象的所有键,甚至是getter定义的键
- 引用类变量中的原型方法
- 如何从对象的原型方法访问JavaScript对象属性
- 为什么要包装每一个原型“;类“;JS中具有匿名函数的对象
- "实例范围”;TypeScript类的getter/setter
- Node.js中的JavaScript原型对象效率
- 重载JS'firefox中的对象原型
- “util.inherits”和在NodeJS中扩展原型之间的区别
- 附加到原型属性的Do函数没有闭包
- 使用方括号访问插件原型函数
- 为什么JSON.stringify没有序列化原型值
- 使用特权Getter/Setter函数的JavaScript原型函数
- 什么类型的对象/属性是原型getter和setter
- 将getter/setter添加到原型中
- 奇怪的“getter"在IE9访问属性“Number”时的行为.原型'来自数字字面量
- 将getter作为原型编写
- 如何在HTMLElement原型上覆盖getter函数
- 对象原型:所有属性上的不区分大小写的 getter
- getter和原型模式中的setter