JavaScript
是ECMAScript标准最流行的实现。Javascript的核心特性是基于ECMAScript标准的,但是Javascript还具有ECMA规范/标准中没有的其他特性。每个浏览器都有一个JavaScript解释器。
ECMAScript是一种面向对象的编程语言,用于在宿主环境中执行计算和操作计算对象。
web浏览器为客户端计算提供ECMAScript主机环境,例如,包括表示窗口、菜单、弹出窗口、对话框、文本区域、锚定、框架、历史记录、cookie和输入/输出的对象。
ECMAScript是基于对象的
:基本语言和主机设施由对象提供,ECMAScript程序是通信对象的集群
物体
-
每个构造函数都是一个具有名为
âprototypeâ
-
由构造函数创建的每个对象都有一个对其值的隐式引用(称为对象原型)
constructorâs âprototypeâ
财产。此外,原型可能对其原型有非空的隐式引用,以此类推;这就是所谓的
prototype chain
.
功能
JavaScript将函数视为一级对象,因此作为一个对象,可以为函数分配属性。
Function Hoisting, declarations & expressions
FunctionDeclaration:函数BindingIdentifier(FormalParameters){FunctionBody}
FunctionExpression:函数BindingIdentifier(FormalParameters){FunctionBody}
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
注意:为每个函数自动创建一个prototype属性,以允许函数用作构造函数。
-
constructor
-
prototype
为其他对象提供共享属性的对象。
-
__proto__
原型
原型
新的
关键字以及
constructor function
. 如果您正在创建
Shape - Object
使用
然后它有一个
internal (or) private link
函数的原型
Shape
.
使用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 introduced Arrow function
箭头函数表达式的语法比函数表达式短,并且不绑定自己的this、arguments、super或new.target。这些函数表达式最适合于非方法函数,它们不能用作构造函数。
ArrowFunction语法产品没有prototype属性。
箭头函数:箭头参数=>简明体
a => (a < 10) ? 'valid' : 'invalid'
const fn = (item) => { return item & 1 ? 'Odd' : 'Even'; };
console.log( fn(2) ); // Even
console.log( fn(3) ); // Odd
Babel是一个JavaScript编译器。用它来改变
ES6
到
ES5
BABEL JS
(或)
ES6Console
.
:
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's 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 property
.
此属性具有属性{[[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
-
函数声明获取
Hoisted
到上下文的顶部,其中as类声明和函数表达式不被提升。
-
函数声明,表达式可以
Overridden
因为它们就像一个变量-
var
如果有多个声明可用,那么它将覆盖其父范围
let
|
const
,
let不允许在其范围内使用相同名称的多个声明。
-
-
Computed method names
允许ES6类有class关键字,但function关键字不允许
function myFoo() {
this.['my'+'Method'] = function () { console.log('Computed Function Method'); };
}
class Foo {
['my'+'Method']() { console.log('Computed Method'); }
}