Pertanyaan Apa kata kunci 'baru' dalam JavaScript?


Itu new kata kunci dalam JavaScript bisa sangat membingungkan ketika pertama kali ditemui, karena orang cenderung berpikir bahwa JavaScript bukan bahasa pemrograman berorientasi objek.

  • Apa itu?
  • Masalah apa yang dipecahkannya?
  • Kapan tepat dan kapan tidak?

1555
2017-10-29 21:32


asal


Jawaban:


Itu melakukan 5 hal:

  1. Ini menciptakan objek baru. Jenis objek ini sederhana saja obyek.
  2. Ini menetapkan objek baru ini internal, tidak dapat diakses, [[prototipe]] (yaitu. __proto__) properti menjadi fungsi konstruktor eksternal, dapat diakses, prototipe objek (setiap objek fungsi secara otomatis memiliki prototipe milik).
  3. Itu membuat this titik variabel ke objek yang baru dibuat.
  4. Ini menjalankan fungsi konstruktor, menggunakan objek yang baru dibuat kapan saja this disebutkan.
  5. Ini mengembalikan objek yang baru dibuat, kecuali jika fungsi konstruktor mengembalikan nilainull referensi objek. Dalam hal ini, referensi objek dikembalikan sebagai gantinya.

catatan: fungsi konstruktor merujuk fungsi setelah new kata kunci, seperti pada

new ConstructorFunction(arg1, arg2)

Setelah ini selesai, jika properti yang tidak terdefinisi dari objek baru diminta, skrip akan memeriksa objeknya [[prototipe]] objek untuk properti sebagai gantinya. Ini adalah bagaimana Anda bisa mendapatkan sesuatu yang mirip dengan pewarisan kelas tradisional di JavaScript.

Bagian paling sulit tentang ini adalah titik nomor 2. Setiap objek (termasuk fungsi) memiliki properti internal ini disebut [[prototipe]]. Bisa hanya disetel pada waktu pembuatan objek, baik dengan baru, dengan Object.create, atau berdasarkan literal (fungsi default ke Function.prototype, angka ke Number.prototype, dll.). Itu hanya bisa dibaca dengan Object.getPrototypeOf (someObject). Ada tidak cara lain untuk mengatur atau membaca nilai ini.

Fungsi, selain yang tersembunyi [[prototipe]] properti, juga memiliki properti yang disebut prototipe, dan inilah yang dapat Anda akses, dan modifikasi, untuk menyediakan properti dan metode yang diwariskan untuk objek yang Anda buat.


Berikut ini contohnya:

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'

Ini seperti pewarisan kelas karena sekarang, objek apa pun yang Anda gunakan new ObjMaker() juga akan tampak mewarisi properti 'b'.

Jika Anda menginginkan sesuatu seperti subkelas, maka Anda melakukan ini:

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

Saya membaca satu ton sampah tentang hal ini sebelum akhirnya menemukan halaman ini, dimana ini dijelaskan dengan sangat baik dengan diagram yang bagus.


1958
2017-10-29 22:22



Misalkan Anda memiliki fungsi ini:

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

Jika Anda menyebut ini sebagai fungsi mandiri seperti:

Foo();

Menjalankan fungsi ini akan menambah dua properti ke window objek (A dan B). Itu menambahkannya ke window karena window adalah objek yang disebut fungsi ketika Anda menjalankannya seperti itu, dan this dalam fungsi adalah objek yang disebut fungsi. Setidaknya dalam Javascript.

Sekarang, sebut saja seperti ini new:

var bar = new Foo();

Apa yang terjadi saat Anda menambahkan new untuk panggilan fungsi adalah bahwa objek baru dibuat (hanya var bar = new Object()) dan bahwa this dalam fungsi menunjuk ke yang baru Object Anda baru saja membuat, bukan ke objek yang disebut fungsi. Begitu bar sekarang menjadi objek dengan properti A dan B. Fungsi apa pun bisa menjadi konstruktor, itu tidak selalu masuk akal.


359
2018-06-20 23:46



Selain jawaban Daniel Howard, ini adalah apa new tidak (atau setidaknya tampaknya melakukan):

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;
}

Sementara

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

setara dengan

var obj = new A(1, 2);

146
2018-05-27 09:23



Untuk pemula untuk memahaminya lebih baik

coba kode berikut di konsol browser.

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

Sekarang Anda dapat membaca jawaban wiki komunitas :)


85
2017-10-29 21:34



jadi mungkin bukan untuk membuat   contoh objek

Ini digunakan persis untuk itu. Anda mendefinisikan konstruktor fungsi seperti ini:

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

var john = new Person('John');

Namun manfaat ekstra yang dimiliki ECMAScript adalah Anda dapat memperpanjang dengan .prototype properti, jadi kita bisa melakukan sesuatu seperti ...

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

Semua objek yang dibuat dari konstruktor ini sekarang akan memiliki getName karena rantai prototipe yang dapat mereka akses.


33
2017-10-29 21:36



JavaScript aku s bahasa pemrograman berorientasi objek dan digunakan persis untuk membuat instance. Ini berbasis prototipe, bukan berbasis kelas, tetapi itu tidak berarti bahwa itu tidak berorientasi objek.


26
2017-10-29 21:37



Javascript adalah bahasa pemrograman dinamis yang mendukung paradigma pemrograman berorientasi objek, dan digunakan digunakan untuk membuat contoh objek baru.

Kelas tidak diperlukan untuk objek - Javascript adalah a berdasarkan prototipe bahasa.


13
2018-05-16 07:21



terkadang kode lebih mudah daripada kata-kata:

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

bagi saya, selama saya tidak prototipe, saya menggunakan gaya func2 karena memberi saya sedikit lebih banyak fleksibilitas di dalam dan di luar fungsi.


3
2017-10-29 21:38



Itu new kata kunci adalah untuk membuat instance objek baru. Dan ya, javascript adalah bahasa pemrograman dinamis, yang mendukung paradigma pemrograman berorientasi objek. Konvensi tentang penamaan objek, selalu menggunakan huruf kapital untuk objek yang seharusnya dipakai oleh kata kunci baru.

obj = new Element();

2
2017-10-05 02:28



Sudah ada beberapa jawaban yang sangat bagus tapi saya posting yang baru untuk menekankan pengamatan saya pada kasus AKU AKU AKU di bawah ini tentang apa yang terjadi ketika Anda memiliki pernyataan kembali eksplisit dalam fungsi yang Anda newnaik. Lihatlah kasus-kasus di bawah ini:

Kasus I:

var Foo = function(){
  this.A = 1; 
  this.B = 2;
};
console.log(Foo()); //prints undefined
console.log(window.A); //prints 1

Di atas adalah kasus sederhana memanggil fungsi anonim yang ditunjuk oleh Foo. Ketika Anda memanggil fungsi ini, ia akan kembali undefined. Karena tidak ada pernyataan pengembalian eksplisit sehingga juru bahasa JavaScript dengan paksa menyisipkan a return undefined; pernyataan di akhir fungsi. Jendela di sini adalah objek permintaan (kontekstual this) yang baru A dan B properti.

Kasus II:

var Foo = function(){
  this.A = 1;
  this.B = 2;
};
var bar = new Foo();
console.log(bar()); //illegal isn't pointing to a function but an object
console.log(bar.A); //prints 1

Di sini penerjemah JavaScript melihat new kata kunci menciptakan objek baru yang bertindak sebagai objek permintaan (kontekstual this) fungsi anonim yang ditunjuk oleh Foo. Pada kasus ini A dan Bmenjadi properti pada objek yang baru dibuat (sebagai ganti objek jendela). Karena Anda tidak memiliki pernyataan pengembalian eksplisit apa pun sehingga juru bahasa JavaScript secara paksa menyisipkan pernyataan pengembalian untuk mengembalikan objek baru yang dibuat karena penggunaan new kata kunci.

Kasus III:

var Foo = function(){
  this.A = 1;
  this.B = 2;
  return {C:20,D:30}; 
};
var bar = new Foo();
console.log(bar.C);//prints 20
console.log(bar.A); //prints undefined. bar is not pointing to the object which got created due to new keyword.

Di sini lagi juru bahasa JavaScript melihat new kata kunci menciptakan objek baru yang bertindak sebagai objek permintaan (kontekstual this) fungsi anonim yang ditunjuk oleh Foo. Lagi, A dan B menjadi properti pada objek yang baru dibuat. Tapi kali ini Anda memiliki pernyataan kembali eksplisit sehingga juru bahasa JavaScript akan tidak melakukan apa saja sendiri.

Hal yang perlu diperhatikan AKU AKU AKU adalah bahwa objek yang dibuat karena new kata kunci hilang dari radar Anda. bar sebenarnya menunjuk ke objek yang benar-benar berbeda yang bukan merupakan salah satu yang diciptakan juru bahasa JavaScript karena new kata kunci.


2
2018-05-13 23:05