1

ここでの私の質問は、javascript の関数とオブジェクトについてです。ある質問から別の質問へとつながる 3 つの質問があります。以下の例では、test で 'a' の値にアクセスしようとしていますが、undefined になります。しかし、テストの新しいオブジェクトを作成すると、「a」値にアクセスして変更することができます。

//create a function called test
         var test=function() {
           this.a=2
           this.b=3 };
           test.a//undefined
//create a object called test1 using 'new'
test1 = new test();
test1.a//2
//change the value of a in test1
test1.a=4
test1 //Object { a=4, b=3}

なぜこれが起こるのかを見つけようとしているときに、このjavascript関数はオブジェクトですか? そして、ここからまた別の質問が飛び出しました。そのSOの質問に対する受け入れられた解決策は以下のとおりです

var addn = function func(a) {
  return func.n + a;
};

addn['n'] = 3;
addn(3);

「func.n」を「this」に変更したところ、機能しなくなりました

var addn=function func(a) {
 return this.n+a;
};
addn['n']=3;
addn(3); //NaN

「this」で匿名関数を作成しても役に立たなかった

    //anonymous function
var addn=function(a) {
     return this.n+a;
    };
    addn['n']=3;
addn(3); //NaN

「これ」を使用しても機能しなかったのはなぜですか?

最後の質問です。キーワード「new」と「createObject」の使用の違いは何ですか。Douglas Crokford は彼の著書で 'CreateObject' の使用を提案していますが、私にはその理由がわかりません。コメントありがとうございます

4

2 に答える 2

5

1. 関数は新しいオブジェクトのコンストラクターです

を呼び出すnew FuncNameと、関数はコンストラクターとして機能し、thisinside の値は (関数自体ではなく) 構築中のオブジェクトを指します。を削除するとnew、 にthisなりundefined、グローバル オブジェクトに戻ります (厳密モードでない限り)。

2. 関数もオブジェクト

すべての関数は のインスタンスでFunctionあるため、関数自体はオブジェクトであり、独自のプロパティを持つことができます。this.propNameこれらのプロパティは、関数本体内ではアクセスできませんfuncName.propName。これthisは、関数内に関数オブジェクト自体が存在しないためです (強制的にbindcall、またはである場合を除きますapply)。


上記の両方のトピックが、関数の仕組みを理解するのに役立つことを願っています。最後の質問については、CrockfordcreateObjectは継承を実装する別の方法であり、基本的Object.createに ES5 準拠のブラウザーで行うことを行います。これにより、新しいコンストラクターを手動で作成し、そのprototypeプロパティ (関数オブジェクトのプロパティの例) を設定し、 new. newCrockford 氏はそれを好み、このアプローチを支持して使用をやめたと述べています。


あなたがチャットで尋ねた質問に答えて、ここでは関数とは何か、そしてそれらが何をするのかを例を挙げて説明しようとします.

関数はただ... 関数にすることができます

あなたがそれらを呼び出すと、彼らは何かをします:

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
于 2013-06-19T20:24:55.433 に答える
0

1. addn['n'] = 3; //静的プロパティ n を関数(オブジェクト) addn に追加することを意味します。addn.n も機能します。

2 this.n は、インスタンスのプロパティ n を意味します。this.n === undefined なので NaN を返します。

3 var addn=function func(a) は、func に 2 番目の名前を付けることを意味します。ほとんどの場合、var addn=function(a) の方が適切な形式です。

4 createObject はネイティブの JavaScript コードではありません。「新」です。

于 2013-06-19T20:39:09.187 に答える