Почему вы можете пропустить использование ключевого слова `new` в JavaScript [duplicate]

Используйте модуль os.path.

os.path.join( "C:", "meshes", "as" )

Или используйте необработанные строки

r"C:\meshes\as"
1564
задан Bergi 25 July 2015 в 13:42
поделиться

12 ответов

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

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

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

new ConstructorFunction(arg1, arg2)

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

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

Функции, в дополнение к скрытому свойству [[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

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

1964
ответ дан 27 revs, 22 users 56% 23 August 2018 в 22:33
поделиться

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

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

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

var john = new Person('John');

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

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

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

33
ответ дан Adrian Thompson Phillips 23 August 2018 в 22:33
поделиться

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

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

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:)

85
ответ дан Anulal S 23 August 2018 в 22:33
поделиться

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

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. Любая функция может быть конструктором, она не всегда имеет смысл.

361
ответ дан apsillers 23 August 2018 в 22:33
поделиться

В дополнение к ответу Даниэля Говарда, вот что делает 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);
146
ответ дан basilikum 23 August 2018 в 22:33
поделиться

Ключевое слово new создает экземпляры объектов, используя функции в качестве конструктора. Например:

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

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

Экземпляры наследуют от функции prototype функции конструктора. Поэтому, учитывая пример выше ...

foo.bar; // 'bar'
0
ответ дан eyelidlessness 23 August 2018 в 22:33
поделиться

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

26
ответ дан hyperslug 23 August 2018 в 22:33
поделиться

Хорошо, что JavaScript per si может сильно отличаться от платформы к платформе, поскольку она всегда является реализацией исходной спецификации EcmaScript.

В любом случае независимо от реализации все реализации JavaScript, соответствующие спецификации спецификации EcmaScript , предоставит вам объектно-ориентированный язык. Согласно стандарту ES:

ECMAScript - это объектно-ориентированный язык программирования для выполнения вычислений и управления вычислительными объектами в среде хоста.

Итак, теперь, когда мы согласились с тем, что JavaScript является реализацией EcmaScript и, следовательно, является объектно-ориентированным языком. Определение операции new на любом объектно-ориентированном языке говорит о том, что такое ключевое слово используется для создания экземпляра объекта из класса определенного типа (включая анонимные типы в случаях, подобных C #).

В EcmaScript мы не используем классы, как вы можете прочитать из спецификаций:

ECMAScript не использует классы, например, в C ++, Smalltalk или Java. Вместо этого объекты могут создаваться различными способами, в том числе через литеральную нотацию или через конструкторы, которые создают объекты, а затем выполняют код, который инициализирует все или часть из них, назначая исходные значения их свойствам. Каждый конструктор - это функция, которая имеет свойство named - prototype ‖, которое используется для реализации наследования на основе прототипов и общих свойств. Объекты создаются с помощью конструкторов в новых выражениях; например, новая дата (2009,11) создает новый объект Date. Вызов конструктора без использования new имеет последствия, которые зависят от конструктора. Например, Date () создает строковое представление текущей даты и времени, а не объекта.

1
ответ дан João Pinho 23 August 2018 в 22:33
поделиться

Ключевое слово new изменяет контекст, в котором выполняется эта функция, и возвращает указатель на этот контекст.

Если вы не используете ключевое слово new, контекст, под которым работает функция Vehicle(), представляет собой тот же контекст, из которого вы вызываете функцию Vehicle. Ключевое слово this будет ссылаться на один и тот же контекст. Когда вы используете new Vehicle(), создается новый контекст, поэтому ключевое слово this внутри функции ссылается на новый контекст. То, что вы получаете взамен, - это вновь созданный контекст.

1
ответ дан Juzer Ali 23 August 2018 в 22:33
поделиться

Есть уже некоторые очень большие ответы, но я публикую новый, чтобы подчеркнуть мое наблюдение на примере III ниже о том, что происходит, когда у вас есть явный оператор возврата в функции, которую вы new. Взгляните на приведенные ниже случаи:

Случай I:

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

Выше - простой случай вызова анонимной функции, на которую указывает Foo. Когда вы вызываете эту функцию, она возвращает undefined. Поскольку нет явного оператора return, поэтому интерпретатор JavaScript принудительно вставляет инструкцию return undefined; в конце функции. Здесь окно - это объект вызова (контекстный this), который получает новые свойства A и B.

Случай 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

Здесь интерпретатор JavaScript, f11] создает новый объект, который действует как объект вызова (контекстная this) анонимной функции, на которую указывает Foo. В этом случае A и B становятся свойствами только что созданного объекта (вместо объекта window). Поскольку у вас нет явного оператора return, поэтому интерпретатор JavaScript принудительно вставляет оператор return, чтобы вернуть новый объект, созданный из-за использования ключевого слова new.

Случай 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.

Здесь JavaScript-интерпретатор, который видит ключевое слово new, создает новый объект, который действует как объект-вызов (контекстный this) анонимной функции, на которую указывает Foo. Опять же, A и B становятся свойствами только что созданного объекта. Но на этот раз у вас есть явный оператор return, поэтому интерпретатор JavaScript будет not делать что-нибудь свое.

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

2
ответ дан RBT 23 August 2018 в 22:33
поделиться

иногда код проще, чем слова:

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, поскольку он дает мне немного большую гибкость внутри и снаружи функции.

3
ответ дан rsbkk 23 August 2018 в 22:33
поделиться

Ключевое слово new предназначено для создания новых экземпляров объектов. И да, javascript - это язык динамического программирования, который поддерживает парадигму объектно-ориентированного программирования. Соглашение об именовании объектов всегда использует заглавную букву для объектов, которые должны быть созданы новым ключевым словом.

obj = new Element();
13
ответ дан Seth 23 August 2018 в 22:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: