我有java背景和处理javascript不是一个非常愉快的经历。 我想写一个函数,它接收一个2d点(x,y)的数组,并再次返回另一个2d点数组。在Java中我可以定义Class,比如C2DPoints,并在我的函数定义中用作输入参数类型和输出类型。但是,在javascript中处理这个问题的最佳方法是什么?
我的解决方案:
function scale2D(x,y, scaleX, scaleY){
// primitives x, y are passed by value
for (i=0;i< x.length;i++){
x[i] = x[i]*scaleX;
y[i] = y[i]*scaleY;
}
return [x,y];
}
答案 0 :(得分:2)
有很多方法......在jsfiddle中尝试一下。
//Taking in 2 numbers
var newArr = function(x,y){
var a = x+1,
b = y+1;
return [a,b];
}
console.log(newArr(1,1));
// Will echo: [2,2]
//Taking in an array of 2 numbers
var newArr = function(x){
var a = x[0]+1,
b = x[1]+1;
return [a,b];
}
console.log(newArr([1,1]));
// Will echo: [2,2]
// Taking in an object
var newArr = function(obj){
var a = obj.x+1,
b = obj.y+1;
return [a,b];
}
console.log( newArr({x:1,y:1}) );
// Will echo: [2,2]
// Accept an Obj and return an Obj
var newArr = function(obj){
var a = obj.x+1,
b = obj.y+1;
return {a:a,b:b};
}
console.log( newArr({x:1,y:1}) );
// Will echo: {a:2,b:2}
答案 1 :(得分:1)
当然,请查看JavaScript Object Literal表示法。实际上,您甚至不必在JavaScript中创建类,您可以在函数中创建对象,并为它们提供您希望它们在构造期间具有的功能。
function main() {
var myGuy = returner();
myGuy.sayAge();
}
function returner() {
return {
name: "bob",
age: "99",
sex: "m",
sayAge: function() {
console.log(this.age);
}
};
}
就你的例子而言,你仍然可以继续采用OOP方法并制作一种Point类。
function main() {
var points = [];
for (var i = 0; i < 10; i++) {
points.push(new Point2D(i, i + 1));
}
manipArray(points);
for (var i = 0; i < 10; i++) {
console.log("Point: " + i + " x: " + points[i].x + " y: " + points[i].y);
}
}
function Point2D(x, y) {
this.x = x;
this.y = y;
}
Point2D.prototype.add = function(other) {
this.x += other.x;
this.y += other.y;
}
function manipArray(arrOfPoints) {
var myPoint = new Point2D(4, 5);
for (var i = 0; i < arrOfPoints.length; i++) {
arrOfPoints[i].add(myPoint);
}
}
当main()
运行时,它会给你:
Point: 0 x: 4 y: 6 (12:48:07:947)
Point: 1 x: 5 y: 7 (12:48:07:952)
Point: 2 x: 6 y: 8 (12:48:07:956)
Point: 3 x: 7 y: 9 (12:48:07:958)
Point: 4 x: 8 y: 10 (12:48:07:959)
Point: 5 x: 9 y: 11 (12:48:07:961)
Point: 6 x: 10 y: 12 (12:48:07:962)
Point: 7 x: 11 y: 13 (12:48:07:963)
Point: 8 x: 12 y: 14 (12:48:07:964)
Point: 9 x: 13 y: 15 (12:48:07:965)
这意味着您传递的点已在函数中更改为排序的out
参数。这是你在找什么?
答案 2 :(得分:0)
//Taking in 2 numbers as an Object
const newArr = function(x,y){
this.x = x+1,
this.y = y+2;
},
const Arr = new newArr(1,1);
console.log(Arr.x);
// Will echo: 2
console.log(Arr.y);
// Will echo: 3
答案 3 :(得分:0)
如果您想要结构类型以提高性能或兼容性,则应查看TypedArrays和DataViews。
在此示例代码中,我对TypedArrays和其他常用技术进行了基准测试。
我验证了定时代码中没有发生v8 jit停用。
节点8.5中的基准时间一致:
A: 4.431ms [TypedArray([x1,y1]), TypedArray([x2,y2]), ...]
B: 2.655ms TypedArray(x1, y1, x2, y2, ...)
C: 4.454ms [[x1,y1], [x2,y2], ...]
D: 5.917ms [x1, y1, x2, y2, ...]
E: 80.101ms [{x1,y1}, {x2,y2}, ...] (as .x and .y)
在Chrome 70中,波动较小:
A: 4.19999985024333ms
B: 2.79999990016222ms
C: 4.800000227987766ms
D: 3.8999998942017555ms
E: 33.19999994710088ms
您可以运行该代码段以查看浏览器的时间。
// technique A : js array of TypedArray points
const count = 100 * 1000;
function Point(x, y) {
return Float32Array.from([x, y]);
}
function scale1(points, scaleX, scaleY) {
for (let i = 0; i < points.length; i++) {
points[i][0] *= scaleX;
points[i][1] *= scaleY;
}
}
function init1() {
let points = [];
for (let i = 0; i < count; i++) {
points[i] = Point(i, count - i);
}
return points;
}
function test1() {
let points = init1();
let start = performance.now();
scale1(points, 1.2, 1.8);
let delta = performance.now() - start;
document.write('A: ', delta, 'ms<br>');
}
// technique B : TypedArray of consecutive xy values
function scale2(values, scaleX, scaleY) {
for (let i = 0; i < count; i++) {
values[i * 2] *= scaleX;
values[i * 2 + 1] *= scaleY;
}
}
function init2() {
let points = new Float32Array(count * 2);
for (i = 0; i < count; i++) {
points[i * 2] = i;
points[i * 2 + 1] = count - i;
}
return points;
}
function test2() {
let points = init2();
let start = performance.now();
scale2(points, 1.2, 1.8);
let delta = performance.now() - start;
document.write('B: ', delta, 'ms<br>');
}
// technique C : js array of js point arrays
function scale3(points, scaleX, scaleY) { // same as A
for (let i = 0; i < points.length; i++) {
// jit chokes on *= here, but not in A
// probably because A uses a TypedArray underneath
//points[i][0] *= scaleX;
//points[i][1] *= scaleY;
points[i][0] = points[i][0] * scaleX;
points[i][1] = points[i][1] * scaleY;
}
}
function init3() {
return init1(); // jit deopts (lazy) if init3() is duplicate of init1()
}
function test3() {
let points = init3();
let start = performance.now();
scale3(points, 1.2, 1.8);
let delta = performance.now() - start;
document.write('C: ', delta, 'ms<br>');
}
// technique D : js array of js numbers
function scale4(values, scaleX, scaleY) { // same as B
for (let i = 0; i < count; i++) {
values[i * 2] *= scaleX;
values[i * 2 + 1] *= scaleY;
}
}
function init4() {
let points = [];
for (i = 0; i < count; i++) {
points[i * 2] = i;
points[i * 2 + 1] = count - i;
}
return points;
}
function test4() {
let points = init4();
let start = performance.now();
scale4(points, 1.2, 1.8);
let delta = performance.now() - start;
document.write('D: ', delta, 'ms<br>');
}
// technique E : js array of js objects
function scale5(points, scaleX, scaleY) { // same as A
for (let i = 0; i < points.length; i++) {
points[i].x = points[i].x * scaleX;
points[i].y = points[i].y * scaleY;
}
}
function init5() {
let points = [];
for (let i = 0; i < count; i++) {
points[i] = { x: i, y: count - i };
}
return points;
}
function test5() {
let points = init5();
let start = performance.now();
scale5(points, 1.2, 1.8);
let delta = performance.now() - start;
document.write('E: ', delta, 'ms<br>');
}
// main
function main() {
test1();
test2();
test3();
test4();
test5();
}
main();
<p>Node benchmark times for a few different techniques:</p>
<pre>
A: 4.431ms [TypedArray([x1,y1]), TypedArray([x2,y2]), ...]
B: 2.655ms TypedArray(x1, y1, x2, y2, ...)
C: 4.454ms [[x1,y1], [x2,y2], ...]
D: 5.917ms [x1, y1, x2, y2, ...]
E: 80.101ms [{x1,y1}, {x2,y2}, ...] (as .x and .y)
</pre>
<p><b>Browser benchmark times will display on run.</b></p>