Я не думаю, что делать «это» свободным было ошибкой. Сначала это может сбить с толку, но для этого есть веские причины. Первое, что приходит на ум, это то, что, поскольку JavaScript не является языком, основанным на классах, функции не связаны с каким-либо конкретным классом, поэтому нет единого способа автоматически связать «this» с правильным экземпляром объекта. Например,
function Person(first, last, age) {
this.firstName = first;
this.lastName = last;
this.age = age;
}
Person.prototype.getFullName = function() {
return this.firstName + " " + this.lastName;
};
«this» должен ссылаться на объект Person, но функция, назначенная Person.prototype.getName, не имеет никакого способа узнать, как он будет использоваться, поэтому «this» необходимо привязать к какому-либо объекту это называется.
Где это вызывает проблему, это когда у вас есть вложенные функции.
// This is a really contrived example, but I can't think of anything better
Person.prototype.getInfo = function() {
// get name as "Last, First"
function getNameLastFirst() {
// oops. "this" is the global object, *not* the Person
return this.lastName + ", " + this.firstName;
}
// expect something like "Crumley, Matthew: Age 25",
// but you get "undefined, undefined: Age 25"
return getNameLastFirst() + ": Age " + this.age;
};
Предлагаемый синтаксис Искусственный_лиот будет удобен, но довольно просто связать "это" с конкретным объектом, используя apply:
function bind(func, obj) {
return function() {
return func.apply(obj, arguments);
};
}
Person.prototype.getInfo = function() {
// get name as "Last, First"
var getNameLastFirst = bind(function () {
return this.lastName + ", " + this.firstName;
}, this);
return getNameLastFirst() + ": Age " + this.age;
};
или более «традиционный» метод с использованием замыканий:
Person.prototype.getInfo = function() {
var self = this;
// get name as "Last, First"
function getNameLastFirst() {
return self.lastName + ", " + self.firstName;
}
return getNameLastFirst() + ": Age " + this.age;
};