Да, первая функция не имеет отношения к экземпляру объекта этой функции конструктора , вы можете рассматривать ее как «статический метод» .
В JavaScript функции являются объектами первого класса , это означает, что вы можете обращаться с ними как с любым объектом, в этом случае вы просто добавляете свойство к объекту функции .
Вторая функция, поскольку вы расширяете прототип функции конструктора, будет доступна для всех экземпляров объекта, созданных с помощью newключевого слова, и контекст в этой функции ( thisключевое слово) будет ссылаться на фактический экземпляр объекта, где вы его вызываете.
Рассмотрим этот пример:
// constructor functionfunctionMyClass(){var privateVariable;// private member only available within the constructor fnthis.privilegedMethod =function(){// it can access private members//..};}// A 'static method', it's just like a normal function // it has no relation with any 'MyClass' object instanceMyClass.staticMethod =function(){};MyClass.prototype.publicMethod =function(){// the 'this' keyword refers to the object instance// you can access only 'privileged' and 'public' members};var myObj =newMyClass();// new object instance
myObj.publicMethod();MyClass.staticMethod();
Но почему Function.prototype.method == Function.method?
Рагхавендра
1
@Рагхавендра это не так
Зоргатоне
1
@ Неужели твоя ссылка мертва
Евгений Сунич
19
Когда вы создаете более одного экземпляра MyClass, у вас все равно будет только один экземпляр publicMethod в памяти, но в случае privilegedMethod вы в конечном итоге создадите множество экземпляров, а staticMethod не имеет отношения к экземпляру объекта.
Вот почему прототипы экономят память.
Кроме того, если вы измените свойства родительского объекта, если соответствующее свойство ребенка не было изменено, оно будет обновлено.
Для визуальных учеников, при определении функции без .prototype
ExampleClass=function(){};ExampleClass.method =function(customString){
console.log((customString !==undefined)?
customString :"called from func def.");}ExampleClass.method();// >> output: `called from func def.` var someInstance =newExampleClass();
someInstance.method('Called from instance');// >> error! `someInstance.method is not a function`
С тем же кодом, если .prototypeон добавлен,
ExampleClass.prototype.method =function(customString){
console.log((customString !==undefined)?
customString :"called from func def.");}ExampleClass.method();// > error! `ExampleClass.method is not a function.` var someInstance =newExampleClass();
someInstance.method('Called from instance');// > output: `Called from instance`
Чтобы было понятнее,
ExampleClass=function(){};ExampleClass.directM =function(){}//M for methodExampleClass.prototype.protoM =function(){}var instanceOfExample =newExampleClass();ExampleClass.directM();✓ works
instanceOfExample.directM(); x Error!ExampleClass.protoM(); x Error!
instanceOfExample.protoM();✓ works
**** Обратите внимание, что в приведенном выше примере someInstance.method () не будет выполняться, так как
ExampleClass.method () вызывает ошибку, и выполнение не может продолжаться.
Но ради иллюстрации и легкого понимания я сохранил эту последовательность. ****
Результаты, полученные из chrome developer console&
Нажмите на ссылку jsbin выше, чтобы пройти через код.
Переключить прокомментированный раздел с помощью +JS Bin
Посмотрите, как staticключевое слово использовалось для объявления статического метода isPerson.
Создать объект Personкласса.
const aminu = new Person("Aminu", "Abubakar");
Используя статический метод isPerson.
Person.isPerson(aminu); // will return true
Используя метод экземпляра sayHi.
aminu.sayHi(); // will return "Hi Aminu"
ПРИМЕЧАНИЕ. Оба примера по сути одинаковы, JavaScript остается бесклассовым языком. Представленный classв ES6 является в первую очередь синтаксическим сахаром по сравнению с существующей моделью наследования на основе прототипов.
«В ES6» вы описываете только синтаксический сахар. Это не «ES2015» (пожалуйста, прекратите использовать ES6, используйте подходящий термин ES2015), чтобы сделать это. Это просто другой способ сделать это и, на мой взгляд, неправильный путь.
К - Токсичность в СО растет.
2
@KarlMorrison Амину не написал «способ сделать это», вы просто написали это сами и воспользовались этим. Ваша точка зрения может быть справедливой в отношении ES6 против ES2015, но в разговоре люди часто прибегают к более короткому соглашению по эффективности, поэтому я думаю, что исключить его из записи невозможно или наверняка желательно.
Вуливонг
Спасибо за ES6 часть вашего ответа; это многое проясняет, особенно в сочетании с 2 ответами «публичный + привилегированный» выше. Я, однако, полностью смущен тем obj.constructor === Person, trueчто ты являешься примером ... Вааааа? Как конструктор экземпляра ===класса сам класс ...? (Это все равно, что сказать, что подмножество набора - это сам набор и т. Д.)
Эндрю
Оооо ... это все, что буквально означает, что конструктор - это все, чем на самом деле является класс JS? Все остальное либо сваливается в конструктор, либо полностью является статической конструкцией, изолированной от класса, кроме как по имени / концепции (и, как подразумеваемое «это», сделанное доступным, очевидно)? (Таким образом, то, что я считал подмножеством набора, на самом деле не было подмножеством.)
Когда вы создаете более одного экземпляра MyClass, у вас все равно будет только один экземпляр publicMethod в памяти, но в случае privilegedMethod вы в конечном итоге создадите множество экземпляров, а staticMethod не имеет отношения к экземпляру объекта.
Вот почему прототипы экономят память.
Кроме того, если вы измените свойства родительского объекта, если соответствующее свойство ребенка не было изменено, оно будет обновлено.
источник
Для визуальных учеников, при определении функции без
.prototype
С тем же кодом, если
.prototype
он добавлен,Чтобы было понятнее,
**** Обратите внимание, что в приведенном выше примере someInstance.method () не будет выполняться, так как
ExampleClass.method () вызывает ошибку, и выполнение не может продолжаться.
Но ради иллюстрации и легкого понимания я сохранил эту последовательность. ****
Результаты, полученные из
chrome developer console
& Нажмите на ссылку jsbin выше, чтобы пройти через код. Переключить прокомментированный раздел с помощью +JS Bin
ctrl/
источник
Да, первый
static method
также называетсяclass method
, а второй -instance method
.Рассмотрим следующие примеры, чтобы понять это более подробно.
В ES5
В приведенном выше коде
isPerson
это статический метод, аsayHi
метод экземпляраPerson
.Ниже описано, как создать объект из
Person
конструктора.var aminu = new Person("Aminu", "Abubakar");
Используя статический метод
isPerson
.Person.isPerson(aminu); // will return true
Используя метод экземпляра
sayHi
.aminu.sayHi(); // will return "Hi Aminu"
В ES6
Посмотрите, как
static
ключевое слово использовалось для объявления статического методаisPerson
.Создать объект
Person
класса.const aminu = new Person("Aminu", "Abubakar");
Используя статический метод
isPerson
.Person.isPerson(aminu); // will return true
Используя метод экземпляра
sayHi
.aminu.sayHi(); // will return "Hi Aminu"
ПРИМЕЧАНИЕ. Оба примера по сути одинаковы, JavaScript остается бесклассовым языком. Представленный
class
в ES6 является в первую очередь синтаксическим сахаром по сравнению с существующей моделью наследования на основе прототипов.источник
obj.constructor === Person
,true
что ты являешься примером ... Вааааа? Как конструктор экземпляра===
класса сам класс ...? (Это все равно, что сказать, что подмножество набора - это сам набор и т. Д.)