Sergey Alexandrovich Kryukov
Надеюсь, вам понравилась ссылка, которую я предоставил в решении 2. А теперь давайте посмотрим, что происходит с вашим простым делом. Одним из возможных решений было бы следующее:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
// make alculateBonus a property:
this.calculateBonus = function() {
alert(this.name); // "Mayank"
return (this.salary + 1000);
}
this.calculateBonus();
}
Предположим, что вы используете строгий режим во всех случаях. Нестрогое поведение слишком запутанно, чтобы использовать его во время разработки. В вашем исходном коде,
alert
показал бы
window
объект, который явно ошибочен (или, эти устаревшие неправильные решения!) и трудно распознать, что это такое. Я выходной
this.name
только для того, чтобы показать некоторые доказательства того, что это правильное "это". (В стиле изречений кролика из "Винни-Пуха" Милна: "это может быть по-другому!". :-))
Конечно, в этом конкретном фрагменте кода, делая
calculateBonus
это было бы совершенно непрактично, потому что это не то, что вы хотели сделать; вы, вероятно, не хотели раскрывать эту функцию пользователям объекта. Я почти уверен, что вы знали практическое решение; только было бы бесполезно раскрывать "тайну" "этого". Так, на всякий случай:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
calculateBonus = function(owner) { // not a property!
alert(owner.name);
return (owner.salary + 1000);
}
calculateBonus(this);
}
Теперь, скажем,вы хотите использовать закрытие. Отлично! На самом деле это гораздо лучшая идея, чем использование свойств. Я надеюсь, что решение будет очевидным:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
var name = this.name;
var salary = this.salary;
var calculateBonus = function() { // use closure
alert(name);
return (salary + 1000);
}
calculateBonus();
}
Давайте сделаем еще один шаг. Зачем нам вообще нужен "calculateBonus"? Избавьтесь от него:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
var name = this.name;
var salary = this.salary;
(function() { // use closure
alert(name);
return (salary + 1000);
})();
}
Гораздо лучше, не так ли? Пожалуйста, смотрите
Pluralitas non est ponenda sine necessitate, смотреть также:
Бритва Оккама-Википедия, свободная энциклопедия,
Немедленно вызываемое выражение функции — Википедия, свободная энциклопедия.
Еще один вариант, сочетающий в себе некоторые из вышеперечисленных:
function Employee() {
this.name = "Mayank";
this.Age = 26;
this.salary = 10000;
var owner = this;
(function() { // use closure
alert(owner.name);
return (owner.salary + 1000);
})();
}
Теперь я хочу представить вам еще одну захватывающую особенность строгого режима. Это может помочь вам, устраняя ложную свободу использования конструкторов. Попробовать это:
function ConstructorInFact() {
this.A = 13;
return 14;
}
var a = new ConstructorInFact();
var b = ConstructorInFact();
Я надеюсь, что вы видите, как этот код глуп. Если это используется в качестве конструктора (
a
),
return 14
не использовать. Если это не вызов конструктора (
b
), "это" бессмысленно. Однако все это будет работать в нестрогом режиме. Некоторые говорят, что это хорошо, но он не обнаружит глупости этого кода. Переключитесь в строгий режим и для первой попытки закомментируйте последнюю строку (
b
И все же это сработает.
Раскомментируйте последнюю строку. В строке want проблема будет обнаружена. Сюрприз: в строке "этот.А =...": "это не определено". Обратите внимание, что проблема существует только в том случае, если есть последняя строка.
Погодите-ка! Не на JavaScript переводчика? Нет, это не чистый интерпретатор. Сценарий сначала лексически анализируется. Еще один сюрприз? :-)
—СА