Skip to content

Instantly share code, notes, and snippets.

@xgqfrms-GitHub
Last active July 3, 2020 17:05
Show Gist options
  • Save xgqfrms-GitHub/19479fdadbbc05356aceaf56073bec6d to your computer and use it in GitHub Desktop.
Save xgqfrms-GitHub/19479fdadbbc05356aceaf56073bec6d to your computer and use it in GitHub Desktop.
ecma-262 6.0 class

How To Reading ECMA-262

http://www.ecma-international.org/ecma-262/6.0/#sec-class-definitions

14.5 Class Definitions

Syntax

ClassDeclaration[Yield, Default] :
    class BindingIdentifier[?Yield] ClassTail[?Yield]
    [+Default] class ClassTail[?Yield]
    
ClassExpression[Yield] :
    class BindingIdentifier[?Yield]opt ClassTail[?Yield]
    
ClassTail[Yield] :
    ClassHeritage[?Yield]opt { ClassBody[?Yield]opt }
    
ClassHeritage[Yield] :
    extends LeftHandSideExpression[?Yield]
    
ClassBody[Yield] :
    ClassElementList[?Yield]
    
ClassElementList[Yield] :
    ClassElement[?Yield]
    ClassElementList[?Yield] ClassElement[?Yield]
    
ClassElement[Yield] :
    MethodDefinition[?Yield]
    static MethodDefinition[?Yield]
    ;

NOTE A ClassBody is always strict code.

blogs

https://chadaustin.me/2012/12/javascript-new-operator-ecma-262/

https://stackoverflow.com/questions/2738736/confused-with-ecmascript-language-specification-function-calls-section

http://stackoverflow.com/questions/761905/how-will-ecma-262-ecmascript-5-help-you

https://blog.appdynamics.com/engineering/7-ways-es2015-can-improve-your-javascript-programing/

https://leanpub.com/understandinges6/read

https://lightrains.com/blogs/es6#classes

@xgqfrms-GitHub
Copy link
Author

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented May 10, 2017

变量提升

https://developer.mozilla.org/zh-CN/docs/Glossary/Hoisting

变量提升

Hoisting 是您在JavaScript文档中找不到的术语。Hoisting 被认为是思考执行上下文(特别是创建和执行阶段)在JavaScript中如何工作的一般方式。但是,hoisting 可能会导致误解。例如,提升教导变量和函数声明被物理移动到编码的顶部,但这根本不是什么。真正发生的什么是在编译阶段将变量和函数声明放入内存中,但仍然保留在编码中键入的位置。

Note:  Hoisting 真正发生的是在编译阶段将变量和函数声明放入内存中,但仍然保留在编码中键入的位置。
了解更多
技术范例

JavaScript 在执行任何代码段之前,将函数声明放入内存中的优点之一是,这允许你可以在你的代码中使用一个函数,在声明该函数之前。

例如:

/**
* 正确的方式:先声明函数,再调用函数 (最佳实践)
*/
function catName(name) {
    console.log("My cat's name is " + name);
}

catName("Tigger");

/*
The result of the code above is: "My cat's name is Tigger"
*/


/*变量提升*/

foo = 2;
var foo;

// 被隐式地解释为:

var foo;
foo = 2;
上面的代码片段是你希望编写代码以使其工作的方式。现在,我们来看看当我们在写这个函数之前调用这个函数会发生什么:

/**
* 不推荐的方式:先调用函数,再声明函数 
*/

catName("Chloe");

function catName(name) {
    console.log("My cat's name is " + name);
}

/*
The result of the code above is: "My cat's name is Chloe"
*/

// 等价于

/*函数声明提升*/
function catName(name) {
    console.log("My cat's name is " + name);
}

catName("Tigger");

/*
The result of the code above is: "My cat's name is Chloe"
*/
即使我们先在代码中调用函数,在写该函数之前,代码仍然可以工作。这是因为在JavaScript中上下文如何执行的工作原理。

Hoisting 也适用于其他数据类型和变量。变量可以在声明之前进行初始化和使用。但是如果没有初始化,就不能使用它们。

技术范例

num = 6;
num + 7;
var num; 
/* 没有给出错误,只要声明了num */
JavaScript 仅提升声明,而不是初始化。如果你使用的是在使用后声明和初始化的一个变量,那么该值将是 undefined。以下两个示例演示了相同的行为。

var x = 1; 
// 声明 + 初始化 x

console.log(x + " " + y);  
// y 是未定义的

var y = 2;
// 声明 + 初始化 y


//上面的代码和下面的代码是一样的



var x = 1; 
// 声明 + 初始化 x

var y; 
// 声明 y

console.log(x + " " + y);  
//y 是未定义的

y = 2; 
// 初始化 y
 

技术参考

JavaScript: Understanding the Weird Parts - Udemy.com Course
var statement - MDN
function statement - MDN

@xgqfrms-GitHub
Copy link
Author

var-vs-let(hoisting)

image

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented May 10, 2017

var overwrite

http://blog.herobs.cn/es6-in-depth-let-and-const/

var x = 1;
// undefined
var x = 2;
// undefined
x
// 2

问题一:没有块级作用域

问题一:没有块级作用域

// OK
var messages = ["Hi!", "I'm a web page!", "alert() is fun!"];

for (var i = 0; i < messages.length; i++) {  
  alert(messages[i]);
}
// Error
    var messages = ["Meow!", "I'm a talking cat!", "Callbacks are fun!"];
    for (var i = 0; i < messages.length; i++) {  
        setTimeout(function () {
            alert(messages[i]);
            console.log(i);
        }, i * 1500);
    }
    console.log('i = ', i);

// i =  3
// undefined
// 3
// 3
// 3


    var messages = ["Meow!", "I'm a talking cat!", "Callbacks are fun!"];
    for (var i = 0; i < messages.length; i++) {  
        setTimeout(function () {
            alert(messages[i]);
            console.log(i);
        },1000);
    }
    console.log('i = ', i);

// i =  3
// undefined
// 3
// 3
// 3

    var messages = ["Meow!", "I'm a talking cat!", "Callbacks are fun!"];
    for (var i = 0; i < messages.length; i++) {  
        setTimeout(function () {
            alert(messages[i]);
            console.log(i);
        }, 0);
    }
    console.log('i = ', i);

// i =  3
// undefined
// 3
// 3
// 3

@xgqfrms-GitHub
Copy link
Author

Function 构造函数

创建一个新的Function对象。 在 JavaScript 中, 每个函数实际上都是一个Function对象。

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function

// 可以直接运行在 JavaScript 控制的代码例子

// 创建了一个能返回两个参数和的函数
const adder = new Function("a", "b", "return a + b");

// 调用函数
adder(2, 6);
//  8

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented May 10, 2017

Functions arguments

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments

arguments 是一个类似数组的对象, 对应于传递给函数的参数。

arguments对象是所有函数中可用的局部变量。你可以使用arguments对象在函数中引用函数的参数。
此对象包含传递给函数的每个参数的条目,第一个条目的索引从0开始。
例如,如果一个函数传递了三个参数,你可以参考它们如下:

arguments[0]
arguments[1]
arguments[2]

参数也可以被设置:

arguments[1] = 'new value';

arguments对象不是一个 Array 。它类似于数组,但除了 长度之外没有任何数组属性。
例如,它没有 pop 方法。但是它可以被转换为一个真正的数组::

let args = Array.prototype.slice.call(arguments); 

let args = [].slice.call(arguments);

你还可以使用 Array.from()方法或 spread 运算符将 arguments 转换为真正的数组:

let args = Array.from(arguments);
let args = [...arguments];

Array.from()

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/from

Array.from() 方法从一个类似数组或可迭代的对象中创建一个新的数组实例。

const bar = ["a", "b", "c"];

Array.from(bar);
// ["a", "b", "c"]

Array.from('foo');
// ["f", "o", "o"]

@xgqfrms-GitHub
Copy link
Author

扩展语句

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Spread_operator

扩展语法允许一个表达式在期望多个参数(用于函数调用)或多个元素(用于数组文本)或多个变量(用于解构赋值)的位置扩展。

用于函数调用:

myFunction(...iterableObj);

用于数组字面量:

[...iterableObj, 4, 5, 6]

更好的 apply 方法

在需要使用数组作为函数的参数的情况下,通常使用 Function.prototype.apply 方法:

function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction.apply(null, args);

如果使用了ES6的展开运算符,你可以这么写:

function myFunction(x, y, z) { }
var args = [0, 1, 2];
myFunction(...args);

还可以同时展开多个数组:

function myFunction(v, w, x, y, z) { }
var args = [0, 1];
myFunction(-1, ...args, 2, ...[3]);

@xgqfrms-GitHub
Copy link
Author

Rest parameters

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Rest_parameters

剩余参数(rest parameter)语法允许我们将一个不定数量的参数表示为一个数组。

function(a, b, ...theArgs) {
  // ...
}

元编程

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Meta_programming

从ECMAScript 2015/ES6 开始,JavaScript获得对Proxy和 Reflect对象的支持,允许你拦截并定义基本语言操作的自定义行为(比如,属性查找,赋值,枚举,函数调用,等)。
借助这两个对象,你可以在JavaScript元级别(meta level)进行编程。

从ES6 开始采用的 Proxy 对象允许拦截某些操作操作和实现自定义行为。例如,获取一个对象上的属性:

let handler = {
  get: function(target, name){
    return name in target ? target[name] : 42;
}};

let p = new Proxy({}, handler);
p.a = 1;

console.log(p.a, p.b); 
// 1, 42

Reflect

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect

Reflect 是一个内置的对象,它提供可拦截JavaScript操作的方法。
Reflect方法与代理处理程序的方法相同。Reflect 不是一个函数对象,因此它是不可构造的。

let

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let

let 语句声明一个块级作用域的本地变量,并且可选的将其初始化为一个值。

@xgqfrms-GitHub
Copy link
Author

xgqfrms-GitHub commented May 10, 2017

es6-in-depth-let-and-const

http://blog.herobs.cn/es6-in-depth-let-and-const/

letvar 究竟有哪些具体的差异?

  1. let 变量是块级作用域。其作用域只在块中,而不再是整个函数。

  2. for (let x...) 循环将会给每次循环创建一个新的 x 绑定。

  3. 任何尝试在 let 变量声明前使用变量将会抛出异常。(no hoisting ?)

  4. 使用 let 重复声明变量将会引起 Syntax Error(语法错误)。

  5. let 在严格模式是一个保留关键词,在非严格模式中,为了能够后向兼容,你任然可以使用 let 作为变量名、函数名和参数名.
    var let = 'aHa';

Closures

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

闭包是指这样的作用域,它包含有一个函数,这个函数可以调用被这个作用域所封闭的变量、函数或者闭包等内容。
通常我们通过闭包所对应的函数来获得对闭包的访问。

https://www.w3schools.com/js/js_function_closures.asp

let messages = ["Meow!", "I'm a talking cat!", "Callbacks are fun!"];
    for (var i = 0; i < messages.length; i++) {
        console.log(`inner i = ${i}`);
        setTimeout(function () {
            console.log(`messages[i] = ${messages[i]}`);
        }, 0);
    }
    console.log(`outer i = ${i}`);


let messages = ["Meow!", "I'm a talking cat!", "Callbacks are fun!"];
    for (let i = 0; i < messages.length; i++) {
        console.log(`inner i = ${i}`);
        setTimeout(function () {
            console.log(`messages[i] = ${messages[i]}`);
        }, 0);
    }
    console.log(`outer i = ${i}`);

let i

const

  1. const 声明的变量和 let 是一样的,但是你不能给他们赋值,否则将会抛出语法错误

  2. 在声明 const 变量时, 给定初始值。

const

@xgqfrms-GitHub
Copy link
Author

JavaScript 变量提升(Hoisting)

http://www.dongcoder.com/detail-270846.html

https://zonxin.github.io/post/2015/10/javascript-hoisting

http://www.jianshu.com/p/159b95d3e533

http://www.bbsmax.com/R/B0zqv2QJvL/

Closures

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures

闭包是指这样的作用域,它包含有一个函数,这个函数可以调用被这个作用域所封闭的变量、函数或者闭包等内容。
通常我们通过闭包所对应的函数来获得对闭包的访问。

// global  var
var counter = 0;

function add() {
    counter += 1;
    console.log(counter);
}

add();
// 1
add();
// 2
add();
// 3


// local var
function add() {
    var counter = 0;
    // overwrite
    counter += 1;
    console.log(counter);
}

add();
// 1
add();
// 1
add();
// 1

var local-vs-global

@xgqfrms-GitHub
Copy link
Author

闭包

function init() {
  let name = "Mozilla"; 
  // name 是一个被init创建的局部变量
  function displayName() { 
  // displayName() 是一个内部函数,
      alert(name); 
      //  一个闭包使用在父函数中声明的变量
  } 
  displayName();
}
init(); 

let-var already been declared

add()(); === var add = add(); add();

function add() {
    var counter = 0;
    return function () {
        console.log(counter);
        return counter += 1;
    }
}

add()();
// var add = add(); add();

@xgqfrms-GitHub
Copy link
Author

es6 let & emoji

https://github.com/xgqfrms-GitHub/Native-JavaScript/blob/master/es6-emoji.html

https://jsfiddle.net/sybn4h33/3/

You can't comment at this time — your comment contains unicode characters above 0xffff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment