Мне интересно, какая разница между функцией и классом. Как с использованием функции ключевого слова, существует ли очевидное различие между этими двумя?
Javascript: какая разница между функцией и классом
Ответ 1
Технически нет класса, они оба являются просто функциями. Любая функция может быть вызвана как конструктор с ключевым словом new
, а свойство prototype этой функции используется для того, чтобы объект наследовал методы из.
"Класс" используется только концептуально для описания вышеупомянутой практики.
Итак, когда кто-то говорит вам "сделать класс цвета" или что-то еще, вы бы сделали:
function Color(r, g, b) {
this.r = r;
this.g = g;
this.b = b;
}
Color.prototype.method1 = function() {
};
Color.prototype.method2 = function() {
};
Когда вы его ломаете, есть просто функция и некоторые назначения для свойства, называемого prototype
этой функции, все
общий синтаксис javascript, ничего не происходит.
Все становится немного волшебным, когда вы говорите var black = new Color(0,0,0)
. Затем вы получите объект со свойствами .r
, .g
и .b
. Этот объект
также будет иметь скрытую ссылку [[prototype]] на Color.prototype
. Это означает, что вы можете сказать black.method1()
, хотя .method1()
не существует в объекте black
.
Ответ 2
JavaScript является наиболее популярной реализацией стандарта ECMAScript. Основные функции Javascript основаны на стандарте ECMAScript, но Javascript также имеет другие дополнительные функции, которых нет в спецификации/стандарте ECMA. У каждого браузера есть интерпретатор JavaScript.
Overview
" ECMAScript изначально разрабатывался как язык веб-сценариев, предоставляя механизм для оживления веб-страниц в браузерах и для выполнения вычислений на сервере как часть веб-архитектуры клиент-сервер. Язык сценариев - это язык программирования, который используется для управления, настройки и автоматизации возможностей существующей системы.
ECMAScript - это объектно-ориентированный язык программирования для выполнения вычислений и манипулирования вычислительными объектами в среде хоста. Веб-браузер предоставляет хост-среду ECMAScript для вычислений на стороне клиента, включая, например, объекты, которые представляют окна, меню, всплывающие окна, диалоговые окна, текстовые области, якоря, рамки, историю, файлы cookie и ввод/вывод.
ECMAScript основан на объектах: базовый язык и основные средства предоставляются объектами, а программа ECMAScript представляет собой кластер взаимодействующих объектов.
Объекты "
-
Каждый конструктор - это функция, которая имеет свойство с именем
"prototype"
, которое используется для реализации наследования на основе прототипа и общих свойств. -
Каждый объект, созданный конструктором, имеет неявную ссылку (называемую прототипом объектов) на значение свойства
constructors "prototype"
своихconstructors "prototype"
. Кроме того, прототип может иметь ненулевую неявную ссылку на свой прототип и т. Д.; это называетсяprototype chain
.
функция
JavaScript обрабатывает функции как объекты первого класса, поэтому, будучи объектом, вы можете назначать свойства функции.
Подъем - это действие интерпретаторов JavaScript, которое перемещает все объявления переменных и функций в начало текущей области видимости. Function Hoisting, declarations & expressions
FunctionDeclaration: функция BindingIdentifier (FormalParameters) {FunctionBody} FunctionExpression: функция BindingIdentifier (FormalParameters) {FunctionBody}
ES5 Функция:
function Shape(id) { // Function Declaration
this.id = id;
};
// prototype was created automatically when we declared the function
Shape.hasOwnProperty('prototype'); // true
// Adding a prototyped method to a function.
Shape.prototype.getID = function () {
return this.id;
};
var expFn = Shape; // Function Expression
console.dir( expFn () ); // Function Executes and return default return type - 'undefined'
Для функции, если возвращаемое значение не указано, возвращается undefined
. Если функция вызывается с new
и возвращаемое значение не является объектом, то возвращается этот (новый объект).
ПРИМЕЧАНИЕ. Свойство прототипа автоматически создается для каждой функции, чтобы обеспечить возможность использования функции в качестве конструктора.
constructor
"Функциональный объект, который создает и инициализирует объекты.prototype
"объект, который предоставляет общие свойства для других объектов.__proto__
"Свойство proto, указывающее на прототип__proto__
. Если вы откроете его, то увидите, что прото указывает на его переменные и функции суперобъекта.
Чтобы получить доступ к методам-прототипам вышеупомянутой функции, мы должны создать объект, используя ключевое слово new
вместе с constructor function
. если вы создаете Shape - Object
с использованием new
ключевого слова, то у него есть internal (or) private link
на прототип функции Shape
.
Классы функций конструктора ES5: объекты функций, созданные с использованием Function.prototype.bind
Shape.prototype.setID = function ( id ) {
this.id = id;
};
var funObj = new Shape( );
funObj.hasOwnProperty('prototype'); // false
funObj.setID( 10 )
console.dir( funObj );
console.log( funObj.getID() );
/*
expFun funObj
name: "Shape" id: 10
prototype:Object
constructor: function Shape(id)
getID: function()
setID: function( id )
__proto__: function () __proto__: Object
constructor: function Shape(id)
getID: function()
setID: function( id )
<function scope>
*/
В ES6 появилась функция Arrow: выражение функции стрелки имеет более короткий синтаксис, чем выражение функции, и не связывает свой собственный this, arguments, super или new.target. Эти функциональные выражения лучше всего подходят для не-методических функций и не могут использоваться в качестве конструкторов. Производство грамматики ArrowFunction не имеет свойства прототипа.
ArrowFunction: ArrowParameters => ConciseBody
a => (a < 10) ? 'valid' : 'invalid' const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; }; console.log( fn(2) ); // Even console.log( fn(3) ); // Odd
Учебный класс
В объектно-ориентированном языке на основе классов в общем случае состояние передается экземплярами, методы - классами, а наследование - только по структуре и поведению. В ECMAScript состояние и методы переносятся объектами, а структура, поведение и состояние наследуются.
Babel - это компилятор JavaScript. Используйте его для преобразования
ES6
в форматES6
ES5
BABEL JS
(или)ES6Console
.
Классы ES6. Классы ES2015 classes
- это простой сахар по сравнению с основанным на прототипе шаблоном ОО. Наличие единой удобной декларативной формы облегчает использование шаблонов классов и способствует взаимодействию. Классы поддерживают наследование на основе прототипов, супер вызовы, экземпляры и статические методы и конструкторы.
class Shape {
constructor(id) {
this.id = id
}
get uniqueID() {
return this.id;
}
set uniqueID(changeVal) {
this.id = changeVal;
}
}
Shape.parent_S_V = 777;
// Class Inheritance
class Rectangle extends Shape {
constructor(id, width, height) {
super(id)
this.width = width
this.height = height
}
// Duplicate constructor in the same class are not allowed.
/*constructor (width, height) { this._width = width; this._height = height; }*/
get area() {
console.log('Area : ', this.width * this.height);
return this.width * this.height
}
get globalValue() {
console.log('GET ID : ', Rectangle._staticVar);
return Rectangle._staticVar;
}
set globalValue(value) {
Rectangle._staticVar = value;
console.log('SET ID : ', Rectangle._staticVar);
}
static println() {
console.log('Static Method');
}
// this.constructor.parent_S_V - Static property can be accessed by it instances
setStaticVar(staticVal) { // https://sckoverflow.com/a/42853205/5081877
Rectangle.parent_S_V = staticVal;
console.log('SET Instance Method Parent Class Static Value : ', Rectangle.parent_S_V);
}
getStaticVar() {
console.log('GET Instance Method Parent Class Static Value : ', Rectangle.parent_S_V);
return Rectangle.parent_S_V;
}
}
Rectangle._staticVar = 77777;
var objTest = new Rectangle('Yash_777', 8, 7);
console.dir( objTest );
Классы функций ES5: использует Object.defineProperty( O, P, Attributes )
Метод
Object.defineProperty()
определяет новое свойство непосредственно для объекта или изменяет существующее свойство объекта и возвращает объект.Экземпляры функций, которые можно использовать в качестве конструктора, имеют свойство prototype.
Это свойство имеет атрибуты {[[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: false}.
'use strict';
var Shape = function ( superClass ) {
var currentClass = Shape;
_inherits(currentClass, superClass); // Prototype Chain - Extends
function Shape(id) { superClass.call(this); // Linking with SuperClass Constructor.
// Instance Variables list.
this.id = id; return this;
}
var staticVariablesJOSN = { "parent_S_V" : 777 };
staticVariable( currentClass, staticVariablesJOSN );
// Setters, Getters, instanceMethods. [{}, {}];
var instanceFunctions = [
{
key: 'uniqueID',
get: function get() { return this.id; },
set: function set(changeVal) { this.id = changeVal; }
}
];
instanceMethods( currentClass, instanceFunctions );
return currentClass;
}(Object);
var Rectangle = function ( superClass ) {
var currentClass = Rectangle;
_inherits(currentClass, superClass); // Prototype Chain - Extends
function Rectangle(id, width, height) { superClass.call(this, id); // Linking with SuperClass Constructor.
this.width = width;
this.height = height; return this;
}
var staticVariablesJOSN = { "_staticVar" : 77777 };
staticVariable( currentClass, staticVariablesJOSN );
var staticFunctions = [
{
key: 'println',
value: function println() { console.log('Static Method'); }
}
];
staticMethods(currentClass, staticFunctions);
var instanceFunctions = [
{
key: 'setStaticVar',
value: function setStaticVar(staticVal) {
currentClass.parent_S_V = staticVal;
console.log('SET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
}
}, {
key: 'getStaticVar',
value: function getStaticVar() {
console.log('GET Instance Method Parent Class Static Value : ', currentClass.parent_S_V);
return currentClass.parent_S_V;
}
}, {
key: 'area',
get: function get() {
console.log('Area : ', this.width * this.height);
return this.width * this.height;
}
}, {
key: 'globalValue',
get: function get() {
console.log('GET ID : ', currentClass._staticVar);
return currentClass._staticVar;
},
set: function set(value) {
currentClass._staticVar = value;
console.log('SET ID : ', currentClass._staticVar);
}
}
];
instanceMethods( currentClass, instanceFunctions );
return currentClass;
}(Shape);
// ===== ES5 Class Conversion Supported Functions =====
function defineProperties(target, props) {
console.log(target, ' : ', props);
for (var i = 0; i < props.length; i++) {
var descriptor = props[i];
descriptor.enumerable = descriptor.enumerable || false;
descriptor.configurable = true;
if ("value" in descriptor) descriptor.writable = true;
Object.defineProperty(target, descriptor.key, descriptor);
}
}
function staticMethods( currentClass, staticProps ) {
defineProperties(currentClass, staticProps);
};
function instanceMethods( currentClass, protoProps ) {
defineProperties(currentClass.prototype, protoProps);
};
function staticVariable( currentClass, staticVariales ) {
// Get Key Set and get its corresponding value.
// currentClass.key = value;
for( var prop in staticVariales ) {
console.log('Keys : Values');
if( staticVariales.hasOwnProperty( prop ) ) {
console.log(prop, ' : ', staticVariales[ prop ] );
currentClass[ prop ] = staticVariales[ prop ];
}
}
};
function _inherits(subClass, superClass) {
console.log( subClass, ' : extends : ', superClass );
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype,
{ constructor: { value: subClass, enumerable: false, writable: true, configurable: true } });
if (superClass)
Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
var objTest = new Rectangle('Yash_777', 8, 7);
console.dir(objTest);
Ниже приведен фрагмент кода для проверки каждого экземпляра, который имеет свою собственную копию элементов экземпляра и общих статических элементов.
var obj1 = new Rectangle('R_1', 50, 20);
Rectangle.println(); // Static Method
console.log( obj1 ); // Rectangle {id: "R_1", width: 50, height: 20}
obj1.area; // Area : 1000
obj1.globalValue; // GET ID : 77777
obj1.globalValue = 88; // SET ID : 88
obj1.globalValue; // GET ID : 88
var obj2 = new Rectangle('R_2', 5, 70);
console.log( obj2 ); // Rectangle {id: "R_2", width: 5, height: 70}
obj2.area; // Area : 350
obj2.globalValue; // GET ID : 88
obj2.globalValue = 999; // SET ID : 999
obj2.globalValue; // GET ID : 999
console.log('Static Variable Actions.');
obj1.globalValue; // GET ID : 999
console.log('Parent Class Static variables');
obj1.getStaticVar(); // GET Instance Method Parent Class Static Value : 777
obj1.setStaticVar(7); // SET Instance Method Parent Class Static Value : 7
obj1.getStaticVar(); // GET Instance Method Parent Class Static Value : 7
Ответ 3
В javascript нет классов. JavaScript использует наследование прототипов, а не наследование на основе классов. Многие люди ссылаются на классы в javascript, потому что это легче понять, но это чисто аналогия.
В наследовании на основе классов вы создаете класс ("план", если хотите), а затем создаете экземпляры объектов из этого класса.
При наследовании прототипа объект создается непосредственно из другого родительского объекта, не требуя каких-либо "чертежей".
См. Страницу википедии для получения дополнительной информации о наследовании класса против прототипа.
Ответ 4
Термин класс обычно используется в контексте объектно-ориентированного программирования. Класс - это шаблон объекта, который будет создан при создании экземпляра. JavaScript - это язык программирования на основе прототипов, поэтому немного странно использовать термин class для описания прототипа JavaScript. В JavaScript прототипы создаются как функции
Ответ 5
В этом talk было выделено одно ключевое различие между функциями и классами, что указывает на то, что функция - поведение, которое может переносить данные, а наоборот, класс - это данные, которые могут нести поведение.
Ответ 6
Разница между (конструктором) function
и class
Ключевое слово class
в javascript является просто синтаксическим сахаром для функции конструктора, которая все еще использует систему создания прототипов javascript. Единственное "различие", которое присутствует, это синтаксис, под капотом они одинаковы.
Пример должен прояснить это:
class PersonClass {
constructor(name) {
this.name = name;
}
speak () { console.log('hi'); }
}
console.log(typeof PersonClass);
// logs function, a class is a constructor function under the hood.
console.log(PersonClass.prototype.speak);
// The class methods are placed on the prototype of the PersonClass constructor function
const me = new PersonClass('Willem');
console.log(me.name);
// logs Willem, properties assinged in the constructor are placed on the newly created object
// The constructor function equivalent would be the following:
function PersonFunction (name) {
this.name = name;
}
PersonFunction.prototype.speak = function () { console.log('hi'); }