Вопрос: Что такое «новое» ключевое слово в JavaScript?


newключевое слово в JavaScript может быть довольно запутанным, когда оно впервые встречается, поскольку люди склонны думать, что JavaScript не является объектно-ориентированным языком программирования.

  • Что это?
  • Какие проблемы он решает?
  • Когда это уместно, а когда нет?

1545


источник


Ответы:


Он делает 5 вещей:

  1. Он создает новый объект. Тип этого объекта просто объект ,
  2. Он устанавливает внутренний, недоступный, [[опытный образец]] (Т.е. __proto__ ) является внешней конструкцией, доступной, опытный образец объекта (каждый объект функции автоматически имеет опытный образец имущество).
  3. Это делает thisпеременная указывает на вновь созданный объект.
  4. Он выполняет функцию конструктора, используя вновь созданный объект всякий раз thisупомянуто.
  5. Он возвращает вновь созданный объект, если функция-конструктор не возвращает не- nullссылка на объект. В этом случае вместо этого возвращается эта ссылка на объект.

Заметка: функция конструктора ссылается на функцию после newключевое слово, как в

new ConstructorFunction(arg1, arg2)

Когда это будет сделано, если запрашивается неопределенное свойство нового объекта, скрипт проверяет объект [[опытный образец]] объект для свойства. Вот как вы можете получить что-то похожее на традиционное наследование классов в JavaScript.

Самая сложная часть этого вопроса - это номер 2. Каждый объект (включая функции) имеет это внутреннее свойство, называемое [[опытный образец]] , Оно может только быть установленным во время создания объекта, либо с новый , с Object.create , или на основе литерала (функции по умолчанию для Function.prototype, номера для Number.prototype и т. д.). Его можно читать только с помощью Object.getPrototypeOf (SomeObject) , Там есть нет другой способ установить или прочитать это значение.

Функции, помимо скрытых [[опытный образец]] свойство, также имеют свойство, называемое опытный образец , и именно поэтому вы можете получить доступ и изменить для предоставления унаследованных свойств и методов для объектов, которые вы создаете.


Вот пример:

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

Я прочитал тонну мусора на эту тему, прежде чем, наконец, найти эта страница , где это очень хорошо объясняется хорошими диаграммами.


1952



Предположим, что у вас есть эта функция:

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

Если вы называете это автономной функцией следующим образом:

Foo();

Выполнение этой функции добавит два свойства к windowобъект ( Aа также B). Он добавляет его в windowпотому как windowэто объект, который вызывает функцию при ее выполнении так, и thisв функции это объект, который вызывает функцию. В Javascript по крайней мере.

Теперь назовите его так: new:

var bar = new Foo();

Что происходит, когда вы добавляете newвызов функции - это создание нового объекта (просто var bar = new Object()) и что thisвнутри функции указывает на новый Objectвы только что создали, а не объект, называемый функцией. Так barтеперь является объектом со свойствами Aа также B, Любая функция может быть конструктором, она не всегда имеет смысл.


357



В дополнение к ответу Даниэля Говарда, вот что 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);

145



Для новичков это лучше понять

попробуйте использовать следующий код в консоли.

function Foo() { 
    return this; 
}

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

console.log(a instanceof Window);  // true
console.log(a instanceof Foo);     // false

console.log(b instanceof Window);  // false
console.log(b instanceof Foo);     // true

Теперь вы можете прочитать ответ wiki сообщества :)


81



так что это, вероятно, не для создания   экземпляры объекта

Он используется именно для этого. Вы определяете конструктор функции следующим образом:

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

var john = new Person('John');

Однако дополнительная выгода, которую имеет ECMAScript, заключается в том, что вы можете .prototypeсобственности, поэтому мы можем сделать что-то вроде ...

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

Все объекты, созданные из этого конструктора, теперь будут иметь getNameиз-за цепи прототипов, к которой у них есть доступ.


33



JavaScript is an object-oriented programming language and it's used exactly for creating instances. It's prototype-based, rather than class-based, but that does not mean that it is not object-oriented.


26



Javascript is a dynamic programming language which supports the object oriented programming paradigm, and it use used for creating new instances of object.

Classes are not necessary for objects - Javascript is a prototype based language.


13



sometimes code is easier than words:

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

for me, as long as I not prototype, I use style of func2 as it gives me a bit more flexibility inside and outside the function.


3