문제

이것은이 JavaScript "클래스"정의를 고려할 때이 질문을 생각할 수있는 가장 좋은 방법입니다.

var Quota = function(hours, minutes, seconds){
    if (arguments.length === 3) {
        this.hours = hours;
        this.minutes = minutes;
        this.seconds = seconds;

        this.totalMilliseconds = Math.floor((hours * 3600000)) + Math.floor((minutes * 60000)) + Math.floor((seconds * 1000));
    }
    else if (arguments.length === 1) {
        this.totalMilliseconds = hours;

        this.hours = Math.floor(this.totalMilliseconds / 3600000);
        this.minutes = Math.floor((this.totalMilliseconds % 3600000) / 60000);
        this.seconds = Math.floor(((this.totalMilliseconds % 3600000) % 60000) / 1000);
    }

    this.padL = function(val){
        return (val.toString().length === 1) ? "0" + val : val;
    };

    this.toString = function(){
        return this.padL(this.hours) + ":" + this.padL(this.minutes) + ":" + this.padL(this.seconds);
    };

    this.valueOf = function(){
        return this.totalMilliseconds;
    };
};

다음 테스트 설정 코드 :

var q1 = new Quota(23, 58, 50);
var q2 = new Quota(0, 1, 0);
var q3 = new Quota(0, 0, 10);

console.log("Quota 01 is " + q1.toString());    // Prints "Quota 01 is 23:58:50"
console.log("Quota 02 is " + q2.toString());    // Prints "Quota 02 is 00:01:00"
console.log("Quota 03 is " + q3.toString());    // Prints "Quota 03 is 00:00:10"

암시 적으로 만드는 방법이 있습니까? q4 A로 Quota 다음과 같이 추가 연산자를 사용하는 객체 ...

var q4 = q1 + q2 + q3;
console.log("Quota 04 is " + q4.toString());    // Prints "Quota 04 is 86400000"

의지하는 대신 ...

var q4 = new Quota(q1 + q2 + q3);
console.log("Quota 04 is " + q4.toString());    // Prints "Quota 04 is 24:00:00"

이 영역에서 산술 연산자를 통해 구성 가능한 사용자 지정 숫자 자바 스크립트 객체를 만들기위한 모범 사례 권장 사항은 무엇입니까?

도움이 되었습니까?

해결책

내가 아는 한, JavaScript (적어도 현재 존재하는대로)는 연산자 과부하를 지원하지 않습니다.

내가 제안 할 수있는 가장 좋은 것은 다른 여러 사람으로부터 새로운 할당량 개체를 만드는 클래스 방법입니다. 내가 의미하는 바에 대한 간단한 예는 다음과 같습니다.

// define an example "class"
var NumClass = function(value){
    this.value = value;
}
NumClass.prototype.toInteger = function(){
    return this.value;
}

// Add a static method that creates a new object from several others
NumClass.createFromObjects = function(){
    var newValue = 0;
    for (var i=0; i<arguments.length; i++){
        newValue += arguments[i].toInteger();
    }
    return new this(newValue)
}

그리고 다음과 같이 사용하십시오.

var n1 = new NumClass(1);
var n2 = new NumClass(2);
var n3 = new NumClass(3);

var combined = NumClass.createFromObjects(n1, n2, n3);

다른 팁

불행하게도.

폴백의 경우 리턴 값을 정렬하면 메소드 체인을 사용할 수 있습니다.

var q4 = q1.plus(p2).plus(q3);

다운 다운 모든 사람들이 나의 다른 대답에 투표했기 때문에 나는 실제로 의도 한대로 작동하는 개념 증명 코드를 게시하고 싶었습니다.

이것은 Chrome 및 IE에서 테스트되었습니다.

//Operator Overloading

var myClass = function () {

//Privates

var intValue = Number(0),
    stringValue = String('');

//Publics
this.valueOf = function () {
    if (this instanceof myClass) return intValue;
    return stringValue;
}

this.cast = function (type, call) {
    if (!type) return;
    if (!call) return type.bind(this);
    return call.bind(new type(this)).call(this);
}

}

//Derived class
var anotherClass = function () {

//Store the base reference
this.constructor = myClass.apply(this);

var myString = 'Test',
    myInt = 1;

this.valueOf = function () {
    if (this instanceof myClass) return myInt;
    return myString;
}

}


//Tests

var test = new myClass(),
anotherTest = new anotherClass(),
composed = test + anotherTest,
yaComposed = test.cast(Number, function () {
    return this + anotherTest
}),
yaCComposed = anotherTest.cast(Number, function () {
    return this + test;
}),
t = test.cast(anotherClass, function () {
    return this + anotherTest
}),
tt = anotherTest.cast(myClass, function () {
    return this + test;
});

debugger;

누군가가 기술적 인 설명을 할 정도로 친절하다면 왜 이것이 충분히 좋지 않은지 나는 그것을 듣고 기뻐할 것입니다!

두 번째 제안 :

var q4 = Quota.add(q1, q2, q3);

나는 최근 에이 기사에 나왔다 : http://www.2ality.com/2011/12/fake-operator-overloading.html .

객체에서 메소드의 값을 재정의하여 JavaScript에서 연산자 과부하와 같은 작업을 수행하는 방법을 설명합니다. 작동중인 객체에 대해서만 돌연변이터 작업을 수행 할 수 있으므로 원하는 것을 수행하지 않을 것 같습니다. 그럼에도 불구하고 흥미로운.

정수 또는 문자열로 변환 할 수 있습니다.

JavaScript가 숫자 또는 문자열을 기대하는 경우 객체는 암시 적으로 변환됩니다. 전자의 경우 변환은 세 가지 단계를 수행합니다.

1.- 호출 값 (). 결과가 원시 (객체가 아닌) 인 경우 사용하여 숫자로 변환하십시오.

2.- 그렇지 않으면 toString ()을 호출하십시오. 결과가 원시인 경우 사용하여 숫자로 변환하십시오.

3.- 그렇지 않으면 TypeError를 던지십시오. 1 단계의 예 :

3 * {valueof : function () {return 5}}

JavaScript가 String으로 변환되면 1 단계와 2 단계가 바뀌 었습니다. toString ()이 먼저 시도됩니다.

http://www.2ality.com/2013/04/quirk-implicit-conversion.html

Paper.js는 예를 들어 포인트 첨가를 사용합니다 (문서):

var point = new Point(5, 10);
var result = point + 20;
console.log(result); // {x: 25, y: 30}

그러나 그것은 자체를 사용하여 수행합니다 사용자 정의 스크립트 파서.

사람들이 왜이 질문에 계속 대답하는지 잘 모르겠습니다!

내가 이해하기 위해 John Resig가 될 필요가없는 매우 작은 스크립트로 간략히 설명 할 방법이 절대적으로 있습니다 ...

그렇게하기 전에 JavaScript에서 당신의 생성자가 작동하는 방식은 배열을 확인하거나 '인수'를 반복하는 것입니다.

예를 들어 내 '클래스'의 제작자에서 나는 arugments를 반복하고, 기본 arugments의 유형을 결정하고, 그것을 지능적으로 처리 할 것입니다.

즉, 배열을 통과하면 배열을 찾아 배열을 찾아 배열의 요소 유형에 따라 추가 처리를 수행하기 위해 배열을 반반합니다.

예 :> 새로운 someclass ([Instancea, instanceb, instancec])

그러나 여러분은 실제로 Populare의 신념에 반하여 실제로 달성 될 수있는 운영자 과부하에 대한 "C"스타일의 접근 방식을 찾고 있습니다.

다음은 운영자 과부하를 존중하는 mootools를 사용하여 만든 클래스입니다. 평범한 오래된 JavaScript에서는 동일한 Tostring 메소드를 사용하여 인스턴스의 프로토 타입에 직접 연결합니다.

이 접근법을 표시하는 나의 주된 이유는이 기능이 에뮬레이션하기에 "불가능한"이 기능을 지속적으로 읽은 텍스트 때문입니다. 불가능한 것은 충분하지 않으며 아래에 이것을 표시 할 것입니다 ...

 //////

debugger;

//Make a counter to prove I am overloading operators
var counter = 0;

//A test class with a overriden operator
var TestClass = new Class({
    Implements: [Options, Events],
    stringValue: 'test',
    intValue: 0,
    initialize: function (options) {
        if (options && options instanceof TestClass) {
            //Copy or compose
            this.intValue += options.intValue;
            this.stringValue += options.stringValue;
        } else {
            this.intValue = counter++;
        }
    },
    toString: function () {
        debugger;
        //Make a reference to myself
        var self = this;
        //Determine the logic which will handle overloads for like instances
        if (self instanceof TestClass) return self.intValue;
        //If this is not a like instance or we do not want to overload return the string value or a default.
        return self.stringValue;
    }
});

//Export the class
window.TestClass = TestClass;

//make an instance
var myTest = new TestClass();

//make another instance
var other = new TestClass();

//Make a value which is composed of the two utilizing the operator overload
var composed = myTest + other;

//Make a value which is composed of a string and a single value
var stringTest = '' + myTest;

//////

이 명칭의 가장 최근 표시는 XDate의 문서 페이지에서 관찰되었습니다.http://arshaw.com/xdate/

이 경우 나는 그것이 실제로 더 쉬운 일이라고 생각합니다. 그는 날짜 개체의 프로토 타입을 사용하여 동일하게 달성 할 수있었습니다.

다른 사람을위한 이러한 스타일의 활용을 묘사 해야하는 예제로서 내가 준 방법은 덜 없습니다.

편집하다:

여기에 완전한 구현이 있습니다.

http://netjs.codeplex.com/

다른 음식과 함께.

JavaScript로 연산자를 과부하시키는 스크립트를 만들었습니다. 일을하는 것은 간단하지 않았으므로 몇 가지 단점이 있습니다. 프로젝트 페이지에서 경고를 게시 할 것입니다. 그렇지 않으면 하단에서 링크를 찾을 수 있습니다.

  • 계산 결과를 새 개체로 전달해야하므로 (P1 + P2 + P3) 대신 새 포인트 (P1 + P2 + P3)를 수행해야합니다 (사용자 정의 객체의 이름이 "Point").

  • +, -, * 만 지원되며, 5 번째 산술 Opperator %는 그렇지 않습니다. 문자열에 대한 강요 ( ""+p1) 및 비교 (p1 == p2)는 예상대로 작동하지 않습니다. 필요한 경우 (P1.Val == P2.Val) 필요한 경우 이러한 목적을 위해 새로운 기능을 구축해야합니다.

  • 마지막으로 답변을 계산하는 데 필요한 계산 리소스는 용어 수에 따라 2 차적으로 증가합니다. 따라서 기본값 당 하나의 계산 체인에서는 6 개의 항만 허용됩니다 (이는 증가 할 수 있지만). 그보다 더 긴 계산 체인의 경우 다음과 같이 계산을 분할하십시오. New Point (New Point (P1 + P2 + P3 + P4 + P5 + P6) + New Point (P7 + P8 + P9 + P10 + P11 + P12)).

그만큼 Github 페이지.

이미 말한 것 외에도 :. valueof ()를 재정의하면 매우 강력한 연산자 과부하를 생성하는 데 도움이 될 수 있습니다. 개념 증명에서 손가락 .js lib .net 스타일로 이벤트 리스너를 추가 할 수 있습니다.

function hi() { console.log("hi") }
function stackoverflow() { console.log("stackoverflow") }
function bye() { console.log("bye") }

on(yourButton).click += hi + stackoverflow;
on(yourButton).click -= hi - bye;

핵심 아이디어는 on ()가 호출 될 때 일시적으로 가치를 대체하는 것입니다.

const extendedValueOf = function () {
    if (handlers.length >= 16) {
        throw new Error("Max 16 functions can be added/removed at once using on(..) syntax");
    }

    handlers.push(this); // save current function

    return 1 << ((handlers.length - 1) * 2); // serialize it as a number.
};

그런 다음 핸들러 배열을 사용하여 반환 된 숫자를 다시 기능으로 다시 제외 할 수 있습니다. 또한 최종 값 (FUNC1 + FUNC2 -FUNC3)에서 추출 비트 값이 가능한 것이 가능하므로 효과적으로 추가 된 기능과 어떤 기능이 제거되었는지 이해할 수 있습니다.

소스를 확인할 수 있습니다 github 그리고 놀아요 여기 데모.

이것에 완전한 설명이 존재합니다 기사 (ecmascript는 js에 대해 작동하기 때문에 AS3의 경우에도 힘든 일입니다).

일부 제한된 사용 사례의 경우 작업자 "과부하"효과를 가질 수 있습니다.

function MyIntyClass() {
    this.valueOf = function() { return Math.random(); }
}
var a = new MyIntyClass();
var b = new MyIntyClass();
a < b
false

a + b
0.6169137847609818

[a, b].sort() // O(n^2) ?
[myClass, myClass]

function MyStringyClass() {
    this.valueOf = function() { return 'abcdefg'[Math.floor(Math.random()*7)]; }
}
c = new MyStringyClass();
'Hello, ' + c + '!'
Hello, f!

위의 코드는 MIT 라이센스에 따라 무료로 사용할 수 있습니다. ymmv.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top