Аргументы функции передаются либо по значению, либо по совместному использованию, но никогда НИКОГДА по ссылке в Javascript!
Примитивные типы передаются по значению:
var num = 123, str = "foo";
function f(num, str) {
num += 1;
str += "bar";
console.log("inside of f:", num, str);
}
f(num, str);
console.log("outside of f:", num, str);
Перераспределения внутри области действия не отображаются в области видимости.
Это также относится к String
s, которые являются составными типами данных и все же неизменяемыми:
var str = "foo";
function f(str) {
str[0] = "b"; // doesn't work, because strings are immutable
console.log("inside of f:", str);
}
f(str);
console.log("outside of f:", str);
Объекты , то есть все типы, которые не являются примитивами, передаются путем совместного использования. Переменная, содержащая ссылку на объект, фактически содержит только копию этой ссылки. Если Javascript будет проводить стратегию оценки по вызову, переменная будет содержать исходную ссылку. Это ключевое различие между совместным использованием и ссылкой.
Каковы практические последствия этого различия?
var o = {x: "foo"}, p = {y: 123};
function f(o, p) {
o.x = "bar"; // mutation
p = {x: 456}; // reassignment
console.log("o inside of f:", o);
console.log("p inside of f:", p);
}
f(o, p);
console.log("o outside of f:", o);
console.log("p outside of f:", p);
Мутирование означает изменение определенных свойств существующего Object
. Справочная копия, к которой привязана переменная, и которая относится к этому объекту, остается неизменной. Таким образом, мутации видны в области вызова.
Переназначение означает замену ссылочной копии, привязанной к переменной. Поскольку это только копия, другие переменные, содержащие копию той же ссылки, остаются неизменными. Таким образом, переопределения не отображаются в области вызывающего абонента, как это было бы с стратегией оценки по вызову.
Дополнительная информация о стратегиях оценки в Экмаскрипте.
Хорошо, я немного подумал об этом и, наконец, нашел решение. Я немного упростил свое решение и использовал вместо кнопок прямоугольники, но вы можете перенести большую часть кода на кнопки, чтобы Начнем с того, что это не та функциональность, которую вы искали, но настолько близко, насколько это возможно, я запускаю событие при нажатии мыши, которое освобождает щелчок мыши и до тех пор, пока это событие не приходит из прямоугольника, тогда не переворачиваем булеву картину рисовать, и поэтому вы в основном нажимаете, чтобы войти в «Режим рисования», и нажимаете еще раз, чтобы выйти из раскрашивания плиток
public class Main extends Application {
private boolean mousePressed;
@Override
public void start(Stage primaryStage) throws Exception{
BorderPane borderPane = new BorderPane();
primaryStage.setTitle("SpriteSheet");
Group root = new Group();
Scene scene = new Scene(borderPane, 500,200);
// scene.setFill(Color.BLACK);
primaryStage.setScene(scene);
GridPane gridPane = new GridPane();
borderPane.setCenter(root);
for(int x = 0; x < 10; x++) {
for(int y = 0; y < 10; y++) {
Rectangle rectangle = new Rectangle(10, 10);
rectangle.setOnMousePressed(event -> {
mousePressed = true;
System.out.println("mouseDown");
rectangle.fireEvent(new MouseEvent(MouseEvent.MOUSE_RELEASED,
rectangle.getLayoutX(), rectangle.getLayoutY(), rectangle.getLayoutX(), rectangle.getLayoutY(),
MouseButton.PRIMARY, 1,
false, false, false, false,
false, false, false, false,
false, false, null));
});
rectangle.setOnMouseReleased(event -> {
System.out.println(event.getSource());
if(!event.getSource().toString().equals("Rectangle[x=0.0, y=0.0, width=10.0, height=10.0, fill=0x000000ff]")) {
mousePressed = false;
System.out.println("mouseUp");
}
});
rectangle.setOnMouseMoved(event -> {
if(mousePressed) {
rectangle.setFill(Color.BLUE);
}
});
gridPane.add(rectangle, x, y);
}
}
root.getChildren().add(gridPane);
primaryStage.show();
}
public static void main(String[] args) { launch(args); }
}