2017-04-11 7 views
0

入力オブジェクトにメソッドを適用できる関数が必要です。コンセプト:JavaScriptでコンストラクタのように機能する関数を作成する

まず、関数を作成します。

$ = function() { /* Constructor Code */ }; 

次に、メソッドを追加します。たとえば、typeとなります。このメソッドは次の関数を使用します。

function() { return toString.call(this).slice(8, -1); 

最後に、正しい出力が得られるかどうかをテストします。出力が入力と異なる必要があります

$("test"); // Output: "test" 
$("test").type(); // Output: "String" 
$(document.body).type(); // Output: "HTMLBodyElement" 

唯一の方法は、方法の適用である:これは、我々が見てみたいものです。いずれかの動作しませんまた

$("test").type(); // Output: "Object" 

eval関連の方法を使用して、いくつかのオブジェクトは、に変換しないように、:それはオブジェクトに入力を変換するように、動作しませんObject.addPropertiesを使用

文字列:

$(document.body).type(); // Error: Can't convert element to string! 

オブジェクトのプロパティを手動でオブジェクトに追加する場合も同じです。

$("test").type(); // Can't apply function to literal string! 

質問は、私たちがを何、ありますか?

答えて

2

入力のプリミティブバージョンにメソッドを適用する方法の1つです。

これはObject.assignで行われます。ここでは簡単な実装です:

$ = function (_) { 
    return Object.assign(_, { 
    type: function() { return toString.call(this).slice(8, -1) } 
    }) 
}; 

そして、ここでは出力です:

$("test").type() // Output: "String" 
$(document.body).type() // Output: "Date" 

我々はまた、同じ出力を返すことになる、メソッドリストとして変数を使用することができます。

$ = function (_) { 
    return Object.assign(_, $.methods) 
}; 

$.methods = ({ 
    type: function() { return toString.call(this).slice(8, -1) } 
}); 

しかし、これらのソリューションは、特定のオブジェクトの元の入力を取得するためには、どちらもvalueOfが必要です。

$ = function (_) { 
    return Object.assign(_, ({ 
    type: function() { return toString.call(this).slice(8, -1) }, val: _ 
    }); 
}; 

と関数呼び出しなしで、元の出力を返しますvalを使用して::

$("test").val // Output: "test" 
$(document.body).val // Output: <body>...</body> 
valueOfが安全でないことができるので

は、我々は、元の入力を取得するメソッドリストにプロパティを追加することができます

これは悪くありませんが、実際にはメソッドで変更されていない値を返す方法がありますか?

+0

これは興味深いコンセプトですが、どのように適用されるかは完全にはわかりません。渡した値をプリミティブ型のオブジェクト形式(Object.assign経由)に強制してから、そのプリミティブオブジェクトのインスタンスにプロパティを追加します。あなたのタイプ**は**変更されていないように見えますが、そうではありません。 'Number(5)=== 5 // true'ですが、' $(5)=== 5 // false'です。 'typeof 5 //" number "'、 'typeof $(5)//"オブジェクト "'さらに、あなたの明確化に応えて 'Number(5)=== $(5)// false'を – mhodges

+0

@mhodgesと答えました。 – imaxwill

+0

修正された答えの最後に追加した質問については、これを行う方法は単にjQueryのようにオブジェクトラッパーを使用することです。残念なことに、元の値を取得するためにアクセサメソッドを使用する必要がありますが、内部的にクロージャを利用して元の変更されていない値にアクセスすることができます。 'this'コンテキストを使用する代わりに、' toString.call(_)。slice(8、-1) 'と言って実際にそれを行うこともできます。 – mhodges

関連する問題