こんにちは!
JavaScript初学者として、ほんの段差2cm、いや、5mm程度位で混乱して躓いた感じですが、
これは今後自分の学習においても、後学におかれましても、確定的な情報として有益だと感じましたので、首題「メソッドの追加」について、纏めさせていただきます!
実行してみましょう
jsFiddle(https://jsfiddle.net/ )
JS Bin(https://jsbin.com/?html,js,output )
メソッド追加 関数とオブジェクト
次のようにすると上手く行きます。
/* 関数オブジェクトfn生成 */
function fn() {
console.log("fn is called");
}
// プロパティ追加
fn.prop = 0;
/* ★メソッドの追加★ */
fn.method = function () {
console.log("method is called");
}
// 関数オブジェクト各種出力
fn();
console.log(fn.prop);
fn.method();
/* オブジェクトの生成 */
const tom = {
name: 'Tom',
age: 18
}
/* ★メソッドの追加★ */
tom.method = function() {
console.log("tom method is called");
}
// オブジェクトの各種出力
tom.method();
console.log(tom);
実行結果
"fn is called"
0
"method is called"
"tom method is called"
[object Object] {
age: 18,
method: function() {
window.runnerWindow.proxyConsole.log("tom method is called");
},
name: "Tom"
}
メソッド追加 オブジェクト 上手く行かない Ver.
次のようにすると上手く行きません。
/* オブジェクトの生成 */
const tom = {
name: 'Tom',
age: 18
}
/* ★メソッドの追加★ */
tom.prototype.proto_method = function() {
console.log("proto method is called");
}
// オブジェクトの各種出力
tom.proto_method();
console.log(tom);
実行結果
"error"
"TypeError: Cannot set properties of undefined (setting 'proto_method')
at xazoyat.js:8:28
at https://static.jsbin.com/js/prod/runner-4.1.8.min.js:1:13924
at https://static.jsbin.com/js/prod/runner-4.1.8.min.js:1:10866"
敢えて、オブジェクトtomのprototype(___proto___)にメソッドを追加したいなら、
こう。
※Web上のドキュメント(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf )に、「Object.setPrototypeOf() メソッドは、指定されたオブジェクトのプロトタイプ (つまり、内部の [[Prototype]] プロパティ)を、別のオブジェクトまたは null に設定します。」とある為、オブジェクトをSetするという発想です。
/* オブジェクトの生成 */
const tom = {
name: 'Tom',
age: 18
}
const tom_proto = {
proto_method : function() {
console.log("proto method is called");
}
}
/* ★メソッドの追加★ */
Object.setPrototypeOf(tom, tom_proto);
// オブジェクトの各種出力
tom.proto_method();
console.log(tom);
実行結果(Chrome)
proto method is called
main.js:17 {name: 'Tom', age: 18}
age: 18
name: "Tom"
[[Prototype]]: Object
proto_method: ƒ ()
[[Prototype]]: Object
メソッド追加 関数 prototype 上手く行かない Ver.
次のようにすると上手く行きません。
/* 関数オブジェクトfn生成 */
function fn() {
console.log("fn is called");
}
/* ★メソッドの追加★ */
fn.prototype.proto_method = function() {
console.log("proto method is called");
}
// 関数オブジェクト各種出力
fn.proto_method();
実行結果
"error"
"TypeError: fn.proto_method is not a function
at xazoyat.js:11:4
at https://static.jsbin.com/js/prod/runner-4.1.8.min.js:1:13924
at https://static.jsbin.com/js/prod/runner-4.1.8.min.js:1:10866"
これについては、次のように、コンストラクター関数として把握して、
インスタンスを生成して実行すべき局面。fn⇒Fnになっていることに注意。
/* 関数オブジェクトfn生成 */
function Fn() {
console.log("Fn is called");
}
/* ★メソッドの追加★ */
Fn.prototype.proto_method = function() {
console.log("proto method is called");
}
/* インスタンス生成 */
const instance = new Fn();
/* インスタンスの各種出力 */
// instance();
instance.proto_method();
実行結果
"Fn is called"
"proto method is called"
※ちなみに、instance()
のコメントアウトを外すと、次のようになる。
/* 関数オブジェクトfn生成 */
function Fn() {
console.log("Fn is called");
}
/* ★メソッドの追加★ */
Fn.prototype.proto_method = function() {
console.log("proto method is called");
}
/* インスタンス生成 */
const instance = new Fn();
/* インスタンスの各種出力 */
instance();
instance.proto_method();
実行結果
"Fn is called"
"error"
"TypeError: instance is not a function
at xazoyat.js:13:1
at https://static.jsbin.com/js/prod/runner-4.1.8.min.js:1:13924
at https://static.jsbin.com/js/prod/runner-4.1.8.min.js:1:10866"
まとめ
prototypeはコンストラクター関数で使用し、追加されたメソッドはインスタンスの下に実行可能。
オブジェクトと関数オブジェクトについて、メソッドを追加するに当たって、prototypeは不要。
以上、
数mm、数cmの段差を乗り越えるための記事でした!!