chức năng động viết lại có thể được sử dụng như một hình thức lazy initialization, tuy nhiên có một nhược điểm:
function Foo() {...}
Foo.prototype = {
bar: function() {
//some initialized variables to close over
var a, b, c, ...;
Foo.prototype.bar = function() {
//do stuff with variables
};
Foo.prototype.bar.call(this);
}
};
Trong khi mã này là tương đối thẳng về phía trước để hiểu, và sẽ được sử dụng như:
var f = new Foo();
f.bar(); //initializes `bar` function
f.bar(); //uses initialized `bar` function
nó có một vấn đề tiềm ẩn:
var f = new Foo(),
g = {};
//passing by reference before the function was initialized will behave poorly
g.bar = f.bar;
f.bar(); //initializes `bar` function
g.bar(); //re-initializes `bar` function
f.bar(); //uses initialized `bar` function
g.bar(); //re-initializes `bar` function
Đó là vì lý do này mà bất kỳ khởi cần thiết cho một chức năng thường được thực hiện bằng cách sử dụng kiểu mô-đun:
function Foo() {...}
Foo.prototype = {
bar: (function() {
var a, b, c, ..., fn;
//some initialized variables to close over
fn = function() {
//do stuff with variables
};
return fn;
}())
};
Các mô hình mô-đun có những bất lợi của cách gọi mã khởi tạo ngay lập tức, nhưng sẽ không có các vấn đề liên quan đến tham chiếu hàm.
Tại sao sẽ có điều kiện chạy đua? Không có nhiều chuỗi đồng thời chạy JavaScript. – mellamokb
Oh duh. Cảm ơn :) – Alan