1. 関数は新しいオブジェクトのコンストラクターです
を呼び出すnew FuncName
と、関数はコンストラクターとして機能し、this
inside の値は (関数自体ではなく) 構築中のオブジェクトを指します。を削除するとnew
、 にthis
なりundefined
、グローバル オブジェクトに戻ります (厳密モードでない限り)。
2. 関数もオブジェクト
すべての関数は のインスタンスでFunction
あるため、関数自体はオブジェクトであり、独自のプロパティを持つことができます。this.propName
これらのプロパティは、関数本体内ではアクセスできませんfuncName.propName
。これthis
は、関数内に関数オブジェクト自体が存在しないためです (強制的にbind
、call
、またはである場合を除きますapply
)。
上記の両方のトピックが、関数の仕組みを理解するのに役立つことを願っています。最後の質問については、CrockfordcreateObject
は継承を実装する別の方法であり、基本的Object.create
に ES5 準拠のブラウザーで行うことを行います。これにより、新しいコンストラクターを手動で作成し、そのprototype
プロパティ (関数オブジェクトのプロパティの例) を設定し、 new
. new
Crockford 氏はそれを好み、このアプローチを支持して使用をやめたと述べています。
あなたがチャットで尋ねた質問に答えて、ここでは関数とは何か、そしてそれらが何をするのかを例を挙げて説明しようとします.
関数はただ... 関数にすることができます
あなたがそれらを呼び出すと、彼らは何かをします:
function alertThis(what) {
alert(what)
}
alertThis("alerting something");
それらに値を渡し、値を返すようにすることもできます
function timesTwo(num) {
return num * 2;
}
timesTwo(2); // 4
オブジェクトを含め、何でも渡して返すことができます...
function createPerson(firstName, lastName) {
return {
firstName : firstName,
lastName : lastName
}
}
var john = createPerson('John', 'Doe');
john.lastName; // "Doe"
...その他の機能:
function timesN(n) {
return function(num) {
return n * num;
}
}
var timesThree = timesN(3);
timesThree(5); // 15
関数はオブジェクトです
関数は、通常のオブジェクトと同じように受け渡して返すことができます。それは、それらがオブジェクトだからです。他のオブジェクトと同様に、プロパティを持つことができます:
function countCalls() {
countCalls.timesCalled++;
}
countCalls.timesCalled = 0;
countCalls();
countCalls();
countCalls.timesCalled; // 2
関数の非常に重要なデフォルト プロパティの 1 つに がありますprototype
。これは特別なプロパティであり、その理由はわかります。
関数は新しいオブジェクトのコンストラクターとして機能できます
関数は、クラス コンストラクターが通常の OO 言語で行うように動作できます。で呼び出されるとnew
、特定の「クラス」の新しいオブジェクトが作成されます。この新しいオブジェクトはthis
関数内で呼び出され、自動的に返されます。
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
var john = new Person('John', 'Doe');
john.firstName; // "John"
john instanceof Person; // true
...意図的に何か他のものを返さない限り:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
var fakePerson = {
firstName : firstName,
lastName : lastName
};
return fakePerson;
}
var notPerson = new Person('John', 'Doe');
notPerson.firstName; // "John"
notPerson instanceof Person; // false
// Note: the object called 'this' inside the function is created, but
// after the function is called there is no outside reference to it.
コンストラクターによって作成されたオブジェクトは、作成者を認識し、そのprototype
プロパティを確認できます
実在の人物に戻る:
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
// Add something to the Person prototype
Person.prototype.sayHi = function() {
return "hi, I'm " + this.firstName;
}
var john = new Person('John', 'Doe');
john.sayHi(); // "Hi, I'm John"
john.constructor; // Person
オブジェクトは、コンストラクターのプロパティ内のすべてにアクセスjohn
できるsayHi()
ためです。prototype
ただし、 Person の他のプロパティを直接見ることはできません (独自のconstructor
プロパティを介してのみ)。
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
Person.timesCalled++;
// There is no 'this.timesCalled', only Person.timesCalled
}
Person.timesCalled = 0;
var john = new Person('John', 'Doe');
john.timesCalled; // undefined - john cannot be called, Person can
john.constructor.timesCalled; // 1