У меня есть глобальная переменная в одном файле javascript, и я пытаюсь получить к ней доступ из другого, но она не работает. Я не могу понять почему. Вот весь соответствующий код.
Полный файл библиотеки javascript:
let tasker = (function () {
let verbs = [
"make",
"install",
"update",
"generate data for",
"talk to",
"schedule a time for",
"develop a plan for",
"knit",
"create",
"build",
"write",
"get",
"finish",
"call",
"arrange",
"submit",
"talk to",
"do",
"protest",
"collect",
"shop for"
];
let nouns = [
"a cake",
"the boat",
"our wedding",
"the garage",
"the tow truck",
"our shed",
"1090 tax form",
"the IRS agent",
"milk",
"some LED lights",
"monthly budget",
"marketing plan",
"the flowers",
"an albatross"
];
let userNames = [
"frodo baggins",
"gandalf gray",
"smaug dragon"
];
let Task = function (id, ownerId, desc, due, color, complete) {
this.ownerId = ownerId;
this.desc = desc;
this.due = due;
this.color = color;
this.complete = complete;
this.id = id || randomId();
};
let randomId = function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
let randomColor = function () {
let pad = function (v) {
return v.length == 1 ? '0' + v : v;
}
r = Math.floor(Math.random() * 256).toString(16);
g = Math.floor(Math.random() * 256).toString(16);
b = Math.floor(Math.random() * 256).toString(16);
return '#' + pad(r) + pad(g) + pad(b);
}
let randomDate = function () {
year = Math.floor(Math.random() * 14 + 2010);
month = Math.floor(Math.random() * 12);
day = Math.floor(Math.random() * 31);
return new Date(year, month, day);
};
let choose = function (things) {
let i = Math.floor(Math.random() * things.length);
return things[i];
}
let randomDescription = function () {
return choose(verbs) + ' ' + choose(nouns);
};
let makeList = function (ownerId, n) {
result = [];
for (i = 0; i < n; i += 1) {
result.push(new Task(null,
ownerId,
randomDescription(),
randomDate(),
randomColor(),
choose([true, false])));
}
return result;
}
let updateTask = function( oldTask, editedTask ) {
let propertiesToCopy = ['desc', 'due', 'color', 'complete' ];
propertiesToCopy.forEach( prop => {
if ( editedTask.hasOwnProperty( prop ) ) {
oldTask[prop] = editedTask[prop];
}
});
}
let state = {
users: userNames.reduce(function (acc, cv) {
let parts = cv.split(' '); //
let name = parts[0];
let email = parts[0][0] + parts[1] + '@uwlaxer.edu';
let id = randomId();
let password = parts[1];
let tasks = makeList(id, Math.random() * 50 + 20).reduce((acc, t) => { acc[t.id] = t; return acc; }, {});
acc[id] = {
name: name,
email: email,
id: id,
password: password,
tasks: tasks
};
return acc;
}, {}),
user: null
};
let getTask = function (ownerId, id) {
try {
return state.users[ownerId].tasks[id];
} catch (e) {
return null;
}
}
let getUserByName = function (name) {
for (id in state.users) {
if (state.users[id] && state.users[id].name === name) {
return state.users[id];
}
}
return null;
}
let taskList = function (ownerId) {
let result = [];
for (let tid in state.user.tasks) {
result.push(state.user.tasks[tid]);
}
return result.sort((a, b) => b.due.getTime() - a.due.getTime());
}
let respond = function (error, value, cb) {
window.setTimeout(() => cb(error, value), Math.random() * 1500);
}
let copyTask = function( task ) {
return new Task(task.id, task.ownerId, task.desc, task.due, task.color, task.complete);
}
return {
login: function ( username, passwd, cb) {
let user = getUserByName( username );
if (user && user.password === passwd) {
state.user = user;
let cleansedUser = { name: user.name, email: user.email, id: user.id };
respond(null, cleansedUser, cb);
} else {
respond('forbidden', null, cb);
}
},
logout: function (cb) {
state.user = null;
respond(null, true, cb);
},
tasks: function (ownerId, cb) {
if (ownerId === state.user.id) {
let tasks = taskList(ownerId).map(u => new Task(u.id, u.ownerId, u.desc, u.due, u.color, u.complete));
respond(null, tasks, cb);
} else {
respond('forbidden', null, cb);
}
},
add: function (ownerId, task, cb) {
if (state.user.id == ownerId) {
if (task.desc && task.due && task.color) {
let due = new Date(task.due);
let task = new Task(task.id, ownerId, task.desc, due, task.color, Boolean(task.complete));
state.users[ownerId].tasks[task.id] = task;
respond(null, task, cb);
} else {
respond('invalid task', null, cb);
}
} else {
respond('forbidden', null, cb);
}
},
delete: function (ownerId, taskId, cb) {
if (state.user.id === ownerId) {
let task = state.users[ownerId].tasks[taskId];
delete state.users[ownerId].tasks[taskId];
if (task) {
respond(null, task, cb);
} else {
respond('no such task', null, cb);
}
} else {
respond('forbidden', null, cb);
}
},
edit: function (ownerId, taskId, task, cb) {
if (state.user.id == ownerId) {
if (taskId) {
let oldTask = getTask(ownerId, taskId);
if ( oldTask) {
updateTask( oldTask, task );
respond( null, copyTask( oldTask ), cb );
} else {
respond( 'no such task', null, cb );
}
} else {
respond( 'no such task', null, cb );
}
} else {
respond( 'forbidden', null, cb );
}
}
}
})();
Функция Я пытаюсь получить доступ к глобальной переменной из:
function login(e) {
var userName = document.getElementById("usernameInput").value;
var password = document.getElementById("passwordInput").value;
console.info("hi");
tasker.login( userName, password, (err, user => {
if (err) {
alert( err );
}
else {
var s = document.getElementById("home");
s.style.visibility = 'hidden';
}
}));
}
Сопровождающий документ HTML:
<!DOCTYPE html>
<html lang = "en" xmlns = "http://www.w3.org/1999/xhtml">
<head>
<meta charset = "utf-8" />
<title>Tasker</title>
<script src = "tasker.js"></script>
<link rel = "stylesheet" href = "tasker_matic.css">
<link rel = "stylesheet" href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src = "tasker_matic.js"></script>
</head>
<body>
<div class = "container">
<div id = "login" class = "on">
<h1>Login</h1><br>
<form style = "width:50%">
<input id = "usernameInput" type = "text" name = "username" placeholder = "Username" class = "form-control">
<input id = "passwordInput" type = "password" name = "password" placeholder = "Password" class = "form-control">
<input type = "submit" value = "Login" class = "btn btn-primary pull-right" onclick = "login(event)">
</form>
</div>
<div id = "home" class = "off">
<h1>Tasker <small><span class = "pull-right btn btn-primary btn-sm" id = "logout" onclick = "logout()"></span></small></h1>
<div class = "well well-sm">
<form class = "form-inline">
<div class = "form-group">
<label for = "descField">Description</label>
<input class = "form-control" type = "text" placeholder = "Description" id = "descField">
</div>
<div class = "form-group">
<label for = "cField">Color Code</label>
<input class = "form-control" type = "color" id = "cField"/>
</div>
<div class = "form-group">
<label for = "dField">Due Date</label>
<input class = "form-control" type = "date" id = "dField"/>
</div>
<input class = "form-control" type = "button" value = "+" id = "addButton" onclick = "addTask()"/>
</form>
</div>
<div class = "well well-sm">
<form class = "form-inline">
<input class = "form-control" type = "text" placeholder = "search" id = "searchField" style = "width:25%" onkeyup = "searchTextChange()"/>
<div class = "checkbox">
<label>
<input type = "checkbox" id = "incompleteBox" onclick = "incompleteChange()"/>Incomplete Only
</label>
</div>
<div class = "checkbox">
<label>
<input type = "checkbox" id = "overdueBox" onclick = "overdueChange()"/>Over-due only
</label>
</div>
</form>
</div>
<table id = "tasks" class = "table table-striped">
</table>
</div>
</div>
</body>
</html>
Любая помощь будет очень признательна. Я просто не понимаю, что происходит.
tasker.login(userName, password, (err, user => { - это одна проблема, вы используете оператор запятой, вы, вероятно, хотели использовать вместо этого (err, user)Мне так жаль. Это таскер.
используйте var вместо let при определении таскера. Проверьте правила определения объема работ.
Или явно назначить window.tasker
Или вы можете заменить его на function tasker(){ }. Дизайн и реализация будут такими же, хотя и с меньшим количеством скобок. Вы все равно назначаете IIFE переменной, в чем смысл. Просто сделайте это регулярной функцией и покончите с этим. Он будет иметь свою собственную область видимости и предотвращать загрязнение глобального пространства имен, как обычно ... как и должно быть.
К сожалению, я вообще не могу изменить документы html и глобальных переменных.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


err, user => { заменить на (err, user) => {
tasker уже является глобальной переменной:
Почему это должно иметь значение?
tasker.login( userName, password, (err, user => { }));(err, user => { })err - это не параметр, а переменная. tasker.login( userName, password, (err, user) => { });Что ж, после того, как вы изменили свой ответ, это имеет смысл;)
Добавьте файлы Jquery.min.js и bootstrap.min.js первыми приоритетами, затем добавьте свои собственные файлы js
приведенный ниже код является стандартным форматом начальной загрузки
<!DOCTYPE html>
<html lang = "en">
<head>
<meta charset = "utf-8">
<meta http-equiv = "X-UA-Compatible" content = "IE=edge">
<meta name = "viewport" content = "width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<title>Bootstrap 101 Template</title>
<!-- Bootstrap -->
<link href = "css/bootstrap.min.css" rel = "stylesheet">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src = "https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"></script>
<script src = "https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<h1>Hello, world!</h1>
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src = "js/bootstrap.min.js"></script>
</body>
</html>
Вы не собираетесь называть имя этой глобальной переменной ..?