node JavaScriptの 'new'キーワードは何ですか?




super class javascript (12)

newキーワードは、関数が実行されているコンテキストを変更し、そのコンテキストへのポインタを返します。

newキーワードを使用しない場合、 Vehicle()関数が実行されるコンテキストは、 Vehicle関数を呼び出すコンテキストと同じです。 thisキーワードは、同じコンテキストを参照します。 new Vehicle()を使用すると、新しいコンテキストが作成され、関数内のthisキーワードが新しいコンテキストを参照するようになります。 あなたが得意とするのは、新たに作成されたコンテキストです。

JavaScriptのnewキーワードは、JavaScriptがオブジェクト指向のプログラミング言語ではないと考える傾向があるため、最初に遭遇すると非常に混乱することがあります。

  • それは何ですか?
  • どのような問題が解決しますか?
  • それはいつ適切なのですか?

JavaScript オブジェクト指向プログラミング言語であり、インスタンスを作成するために使用されます。 クラスベースではなく、プロトタイプベースですが、それはオブジェクト指向ではありません。


初心者のためにそれをよりよく理解するために

ブラウザのコンソールで次のコードを試してみてください。

function Foo() { 
    return this; 
}

var a = Foo();       //returns window object
var b = new Foo();   //returns empty object of foo

a instanceof Window;  // true
a instanceof Foo;     // false

b instanceof Window;  // false
b instanceof Foo;     // true

今すぐあなたはコミュニティのwikiの答えを読むことができます:)


時にはコードが単語よりも簡単です:

var func1 = function (x) { this.x = x; }                    // used with 'new' only
var func2 = function (x) { var z={}; z.x = x; return z; }   // used both ways
func1.prototype.y = 11;
func2.prototype.y = 12;

A1 = new func1(1);      // has A1.x  AND  A1.y
A2 =     func1(1);      // undefined ('this' refers to 'window')
B1 = new func2(2);      // has B1.x  ONLY
B2 =     func2(2);      // has B2.x  ONLY

私にとって、プロトタイプでない限り、私はfunc2のスタイルを使用しています。これは、関数の内部と外部でもう少し柔軟性があるからです。


ダニエル・ハワードの答えに加えて、ここにnewがあります(少なくとも、やっているようです):

function New(func) {
    var res = {};
    if (func.prototype !== null) {
        res.__proto__ = func.prototype;
    }
    var ret = func.apply(res, Array.prototype.slice.call(arguments, 1));
    if ((typeof ret === "object" || typeof ret === "function") && ret !== null) {
        return ret;
    }
    return res;
}

var obj = New(A, 1, 2);

var obj = new A(1, 2);

newキーワードは、新しいオブジェクトインスタンスを作成するためのキーワードです。 そして、はい、javascriptはオブジェクト指向プログラミングパラダイムをサポートする動的プログラミング言語です。 オブジェクトの命名規則については、newキーワードでインスタンス化されるはずのオブジェクトには常に大文字を使用します。

obj = new Element();

それは5つのことを行います:

  1. 新しいオブジェクトを作成します。 このオブジェクトのタイプは単なるオブジェクトです。
  2. この新しいオブジェクトの内部のアクセス不可能な[[prototype]] (つまり__proto__ )プロパティは、コンストラクタ関数の外部のアクセス可能なプロトタイプオブジェクトに設定されます(すべての関数オブジェクトは自動的にプロトタイププロパティを持ちます)。
  3. this変数は、新しく作成されたオブジェクトを指し示します。
  4. これは、新しく作成されたオブジェクトを使用してコンストラクタ関数を実行します。
  5. コンストラクタ関数がnullオブジェクト参照を返さない限り、新しく作成されたオブジェクトを返します。 この場合、そのオブジェクト参照が代わりに返されます。

注: コンストラクタ関数は、 newキーワードの後の関数を参照します。

new ConstructorFunction(arg1, arg2)

これが完了すると、新しいオブジェクトの定義されていないプロパティが要求された場合、スクリプトはオブジェクトのオブジェクト[[prototype]]オブジェクトを代わりにチェックします。 これは、JavaScriptで伝統的なクラス継承に似た何かを得る方法です。

これに関する最も難しい部分はポイント番号2です。すべてのオブジェクト(関数を含む)は、 [[prototype]]と呼ばれるこの内部プロパティを持っています。 これは、 新規作成、 Object.create 、またはリテラル(Function.prototypeのデフォルトの関数、Number.prototypeの数など)に基づいてオブジェクトを作成するときにのみ設定できます。 これは、 Object.getPrototypeOf(someObject)でのみ読み取ることができます。 この値を設定または読み取る他の方法はありません

hidden [[prototype]]プロパティに加えて、関数にはprototypeというプロパティもあります。このオブジェクトにアクセスして変更することで、継承したプロパティとメソッドを提供できます。

次に例を示します。

ObjMaker = function() {this.a = 'first';};
// ObjMaker is just a function, there's nothing special about it that makes 
// it a constructor.

ObjMaker.prototype.b = 'second';
// like all functions, ObjMaker has an accessible prototype property that 
// we can alter. I just added a property called 'b' to it. Like 
// all objects, ObjMaker also has an inaccessible [[prototype]] property
// that we can't do anything with

obj1 = new ObjMaker();
// 3 things just happened.
// A new, empty object was created called obj1.  At first obj1 was the same
// as {}. The [[prototype]] property of obj1 was then set to the current
// object value of the ObjMaker.prototype (if ObjMaker.prototype is later
// assigned a new object value, obj1's [[prototype]] will not change, but you
// can alter the properties of ObjMaker.prototype to add to both the
// prototype and [[prototype]]). The ObjMaker function was executed, with
// obj1 in place of this... so obj1.a was set to 'first'.

obj1.a;
// returns 'first'
obj1.b;
// obj1 doesn't have a property called 'b', so JavaScript checks 
// its [[prototype]]. Its [[prototype]] is the same as ObjMaker.prototype
// ObjMaker.prototype has a property called 'b' with value 'second'
// returns 'second'

これはクラス継承のようなものなので、 new ObjMaker()を使用して作成したオブジェクトはすべて、 'b'プロパティを継承しているように見えます。

サブクラスのようなものが必要な場合は、次のようにします。

SubObjMaker = function () {};
SubObjMaker.prototype = new ObjMaker(); // note: this pattern is deprecated!
// Because we used 'new', the [[prototype]] property of SubObjMaker.prototype
// is now set to the object value of ObjMaker.prototype.
// The modern way to do this is with Object.create(), which was added in ECMAScript 5:
// SubObjMaker.prototype = Object.create(ObjMaker.prototype);

SubObjMaker.prototype.c = 'third';  
obj2 = new SubObjMaker();
// [[prototype]] property of obj2 is now set to SubObjMaker.prototype
// Remember that the [[prototype]] property of SubObjMaker.prototype
// is ObjMaker.prototype. So now obj2 has a prototype chain!
// obj2 ---> SubObjMaker.prototype ---> ObjMaker.prototype

obj2.c;
// returns 'third', from SubObjMaker.prototype

obj2.b;
// returns 'second', from ObjMaker.prototype

obj2.a;
// returns 'first', from SubObjMaker.prototype, because SubObjMaker.prototype 
// was created with the ObjMaker function, which assigned a for us

私は最終的にこのページを見つけ出す前に、このテーマについて1トンのゴミを読んでいます 。ここで、これは素敵なダイアグラムでうまく説明されています。


Javascriptは、オブジェクト指向プログラミングパラダイムをサポートする動的プログラミング言語であり、オブジェクトの新しいインスタンスを作成するために使用されます。

クラスはオブジェクトには必要ありません.Javascriptはプロトタイプベースの言語です。


この関数があるとします:

var Foo = function(){
  this.A = 1;
  this.B = 2;
};

このようなスタンドアロンの関数としてこれを呼び出すと:

Foo();

この関数を実行すると、 windowオブジェクト( AB )に2つのプロパティが追加されwindow 。 このようにwindow追加するのは、 windowがそのように実行したときに関数を呼び出したオブジェクトであり、関数内で関数を呼び出すオブジェクトであるためです。 少なくともJavascriptで。

今、これをnewものと呼んでください:

var bar = new Foo();

関数呼び出しにnew関数を追加すると、新しいオブジェクト( var bar = new Object()だけvar bar = new Object()が作成され、関数内のthisは、呼び出されたオブジェクトではなく、今作成した新しいObjectを指すことになります関数。 したがって、 barはプロパティABAオブジェクトになりました。 どの関数もコンストラクタになり得ますが、それは必ずしも意味をなさないだけです。


オブジェクトのインスタンスを作成するのではないでしょう

それはまさにそのために使われています。 関数コンストラクタは次のように定義します。

function Person(name) {
    this.name = name;
}

var john = new Person('John');

しかし、ECMAScriptが持っている特別な利点は、 .prototypeプロパティで拡張することができるので、次のようなことができます。

Person.prototype.getName = function() { return this.name; }

このコンストラクタから作成されたすべてのオブジェクトは、アクセス権を持つプロトタイプチェーンのためにgetNameを持つようになりました。


概要:

newキーワードは、コンストラクタ関数からオブジェクトを作成するためにjavascriptで使用されます。 newキーワードは、コンストラクタ関数の呼び出しの前に置かなければならず、次のことを行います:

  1. 新しいオブジェクトを作成します。
  2. このオブジェクトのプロトタイプをコンストラクタ関数のprototypeプロパティに設定します。
  3. thisキーワードを新しく作成されたオブジェクトにバインドし、コンストラクタ関数を実行します。
  4. 新しく作成されたオブジェクトを返します。

例:

function Dog (age) {
  this.age = age;
}

const doggie = new Dog(12);

console.log(doggie);
console.log(doggie.__proto__ === Dog.prototype) // true

正確にはどうなるの?

  1. const doggie :変数を宣言するためのメモリが必要です。
  2. assigment演算子=は言う:我々はこの変数を式の後に=
  3. その表現はnew Dog(12)です。 JSエンジンは新しいキーワードを見て、新しいオブジェクトを作成し、プロトタイプをDog.prototypeに設定します
  4. コンストラクタ関数は、 this値を新しいオブジェクトに設定して実行されます。 このステップでは、新しく作成されたdoggieオブジェクトに年齢が割り当てられます。
  5. 新しく作成されたオブジェクトが返され、変数doggieに割り当てられます。

newキーワードは、関数をコンストラクタとして使用してオブジェクトのインスタンスを作成します。 例えば:

var Foo = function() {};
Foo.prototype.bar = 'bar';

var foo = new Foo();
foo instanceof Foo; // true

インスタンスは、コンストラクタ関数のprototypeから継承します。 だから上の例では...

foo.bar; // 'bar'




new-operator