javascript函数可以返回结构类型

时间:2013-12-31 18:16:55

标签: javascript

我有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];
}

4 个答案:

答案 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)

如果您想要结构类型以提高性能或兼容性,则应查看TypedArraysDataViews

在此示例代码中,我对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>