1、let

A:let关键字:将变量绑定到所在的任意作用域

 function process(){
//do something
} //在这个块中定义的内容完事就可以销毁
{
let someReallyBigData = {…………}; process(someReallyBigData);
} vra btn = document.getElementById("my_button");
btn.addEventListener('click',function click(evt){
console.info("click");
})

B:let循环

for(let i = 0 ; i < 10 ; i++){ console.info(i); }

注意:let不仅将i绑定到for循环中,事实上将其绑定到了循环中的每一个迭代中,确保上一个循环迭代结束的时候对它的值重新进行赋值

C:可以解决闭包中的作用域问题

 for(var i = 1 ; i <= 5 ; i++){
(function(j){
setTimeout(function timer(){
console.info(j)
},j * 1000);
})(i);
} 作用相同 for(var i = 1 ; i <= 5 ; i++){
let j = i ;
setTimeout(function timer(){
console.info(j)
},j * 1000);
}

2、const

创建块作用域变量,但其值是固定的(常量),之后任何试图修改值得操做都会引起错误

 

3、编译器---函数声明与函数表达式

函数声明:

 foo();  //success
function foo(){
console.info(a); //undefined
var a = 2;
}
解释为
function foo(){
var a;
console.info(a); //undefined
a = 2;
}
foo();

函数表达式:

 foo();   //TypeError
bar(); //ReferenceError
var foo = function bar(){
//....
}

 4、模块机制---ES6

 bar.js
function hello(who){
return "Let me introduce:" + who;
}
export hello; foo.js
//仅从“bar”模块中导入hello()
import hello from "bar"; var hungry = "hippo";
function awesome(){
console.info(hello(hungry).toUpperCase());
}
export awesome; baz.js
//导入完整的“foo”与“bar”模块
module foo from "foo";
module bar from "bar";
console.info(bar.hello("rhino")); //Let me introduce:rhino
foo.awesome(); //LET ME INTRODUCE:HIPPO

 5、ES6箭头函数 -- 当做function关键字的简写以及解决关于this绑定问题

箭头函数就是function关键字的简写,用于函数声明,放弃了所有普通的this绑定原则,取而代之的是用当前的语法作用域覆盖了this本来的值,具体参考以下例子:

 var obj = {
id : "awesome",
cool : function coolFn(){
console.info(this.id);
}
} var id = "not awesome"; obj.cool(); //awesome
//cool函数丢失了同this之间的绑定
setTimeout(obj.cool,100); //not awesome //可以通过var self = this;解决
var obj = {
count : 0,
cool : function coolFn(){
var self = this; if (self.count < 1) {
setTimeout(function timer(){
self.count++;
console.info("awesome?");
},100)
};
}
}
obj.cool(); //awesome? //这样一来代码过于冗长,通过ES6的箭头函数
var obj = {
count : 0,
cool : function coolFn(){
if (this.count < 1) {
setTimeout( () => {
this.count++;
console.info("awesome?");
},100)
};
}
}
obj.cool(); //awesome? //还可以通过bind()绑定
var obj = {
count : 0,
cool : function coolFn(){
if (this.count < 1) {
setTimeout(function timer(){
this.count++;
console.info("awesome?");
}.bind(this),100)
};
}
}
obj.cool(); //awesome?

 6、关于指向函数自身

A:如果要是从函数对象内部引用它自身,那只使用this是不够的,一般来说,你需要通过一个指向函数对象的词法标识符(变量)来引用,例如以下例子:

 function foo(){
foo.count = 4 ; //foo指向自身
} setTimeout(function(){
//匿名(没有名字)的函数无法指向自身
},10);

第一个函数称为具名函数,在他内部可以使用foo来引用自身

第二个函数中没哟名称标识符(匿名函数),因此无法从函数内部引用自身

B:arguments.callee已经弃用,不应该再使用

C:使用foo标识符替代this引用函数对象

 function foo(num){
foo.count++;
}
foo.count = 0;
var i; for(i = 0 ; i < 10 ; i++){
if (i > 5) {
foo(i)
};
}
console.info(foo.count); //

该方法回避了this问题,并且完全依赖于变量foo的词法作用域

D:强制this指向函数对象

 function foo(num){
this.count++;
}
foo.count = 0;
var i; for(i = 0 ; i < 10 ; i++){
if (i > 5) {
foo.call(foo,i);
};
}
console.info(foo.count); //

7、this绑定

A:在严格模式下,this的默认绑定是undefined,在非严格模式下,this的默认绑定是全局对象

 function foo(){
"use strict";
console.info(this.a);
}
var a = 2;
foo(); //TypeError : this is undefined function foo(){
console.info(this.a);
}
var a = 2 ;
(function(){
"use strict";
foo(); //
})();

注意:foo的运行环境不是在严格模式下,严格模式下调用foo不影响默认绑定

B:隐式绑定:需要考虑调用位置是否含有上下文对象,或者说被某个对象所拥有或包含

 function foo(){
console.info(this.a);
}
var obj = {
a : 2,
foo : foo
}
obj.foo(); //

调用foo的时候,this被绑定到obj,所以上下文中的this都是一样的

注意:对象属性引用链中只有上一层或者说最后一层在调用位置上面起作用,举例来说:

 function foo(){
console.info(this.a);
}
var obj2 = {
a : 42,
foo : foo
}
var obj1 = {
a : 2,
obj2 : obj2
}
obj1.obj2.foo(); //

C:隐式丢失

 function foo(){
console.info(this.a)
}
var obj = {
a : 2,
foo : foo
}
var bar = obj.foo;
var a = "oops";
bar(); //"oops"

bar其实是对foo函数本身的引用,因此此时bar()其实是一个不带任何修饰的函数调用,函数作为参数传递也是一样的

D:显示绑定

 function foo(){
console.info(this.a);
}
var obj = {
a : 2
}
var bar = function(){
foo.call(obj)
}
bar(); //
setTimeout(bar,100); //
//硬绑定的bar不可能再修改它的this
bar.call(window); //

另一种方式是创建一个包裹函数,负责接收参数并返回值

 function foo(something){
console.info(this.a,something);
return this.a + something;
}
var obj = {
a : 2
}
var bar = function(){
return foo.apply(obj,arguments);
}
var b = bar(3) //2 3
console.info(b) //

另一种方法是创建一个可以重复使用的辅助函数

 function foo(something){
console.info(this.a,something);
return this.a + something;
}
function bind(fn,obj){
return function(){
return fn.apply(obj,arguments);
}
}
var obj = {
a : 2
}
var bar = bind(foo,obj);
var b = bar(3); //2 3
console.info(b) //

另一种方法是bind

 function foo(something){
console.info(this.a,something);
return this.a + something;
}
var obj = {
a : 2
}
var bar = foo.bind(obj);
var b = bar(3); // 2 3
console.info(b) //

另一种方法是api调用的上下文

 function foo(el){
console.info(el,this.id);
}
var obj = {
id : "awesome"
}
[1,2,3].forEach(foo,obj);
//1 awesome 2 awesome 3 awesome

E:new绑定

 function foo (a) {
this.a = a;
}
var bar = new foo(2);
console.info(bar.a); //

F:显示绑定的优先级高于隐式绑定;new绑定的优先级高于显示绑定

8、对象 -- 可计算属性名(ES6)

 var prefix = "foo";
var myObject = {
[prefix + "bar"] : "hello",
[prefix + "baz"] : "world"
}
myObject["foobar"]; //hello
myObject["foobaz"]; //world

9、对象 -- 浅复制(ES6)

function anotherFunction(){}
var anotherObject = {
c : true
}
var anotherArray = [];
var myObject = {
a : 2,
b : anotherObject,
c : anotherArray,
d : anotherFunction
}
//执行浅复制
var newObj = Object.assign({},myObject);
newObj.a; //
newObj.b === anotherObject ; //true

注意:Object.assign()使用的是=操作符,所有源对象属性的一些特性(比如writable)不会被复制到目标对象

深复制与浅复制:浅复制是复制出的新对象还是引用,深复制还需要复制引用的函数

10、数组遍历 --- ES6

 var myArray = [1,2,3];
for(var v of myArray){
console.info(v);
}
//
//
//

直接遍历数组的值而不是数组下标

原理:每次都会调用next()方法,该方法可以进行数组、对象……的遍历,不仅仅只是遍历数组而已

11、对象属性设置与屏蔽 --- ES6

var anotherObject = {
a : 2
} var myObject = Object.create("anotherObject"); anotherObject.a; //= 2
myObject.a; //= 2 anotherObject.hasOwnProperty("a"); //true
myObject.hasOwnProperty("a"); //false myObject.a++; //隐式屏蔽 anotherObject.a; //
myObject.a; //
myObject.hasOwnProperty("a"); //true
myObject.a++ 看起来应该是查找并增加anotherObject.a属性,但是++操作相当于myObject.a = myObject.a + 1.所以++操作首先会通过[[Prototype]]查找属性a并从anotherObject.a中
获取当前属性值2,然后给这个值+1,接着用[[put]]将值3赋给myObject中新建的屏蔽属性a 12、创建一个合适的关联对象
要创建一个合适的关联对象,我们必须使用Object.create(),而不是使用具有副作用的Foo(),这样做的唯一缺点就是需要创建一个新对象,然后把旧对象抛弃掉,不能直接修改已有的默认对象。 在ES-6之前,修改对象的[[prototype]]关联,我们只能通过设置._proto_属性实现,但是该方法并不是标准,并且无法兼容所有浏览器。
ES-6添加了辅助函数Object.setPrototypeOf(..)
 //ES-6之前
Bar.prototype = Object.create(Foo.prototype); //ES-6之后
Object.setPrototypeOf(Bar.prototype,Foo.prototype);
 

《你不知道的JavaScript -- 上卷》笔记 --- 基于ES6新标准的更多相关文章

  1. 你不知道的JavaScript上卷笔记

    你不知道的JavaScript上卷笔记 前言 You don't know JavaScript是github上一个系列文章   初看到这一标题的时候,感觉怎么老外也搞标题党,用这种冲突性比较强的题目 ...

  2. 【你不知道的javaScript 上卷 笔记3】javaScript中的声明提升表现

    console.log( a ); var a = 2; 执行输出undefined a = 2; var a; console.log( a ); 执行输出2 说明:javaScript 运行时在编 ...

  3. 【你不知道的javaScript 上卷 笔记7】javaScript中对象的[[Prototype]]机制

    [[Prototype]]机制 [[Prototype]]是对象内部的隐试属性,指向一个内部的链接,这个链接的作用是:如果在对象上没有找到需要的属性或者方法引用,引擎就 会继续在 [[Prototyp ...

  4. 【你不知道的javaScript 上卷 笔记6】javaScript中的对象相关内容

    一.创建一个对象的语法 var myObj = { key: value // ... };//字面量 var myObj = new Object(); //new myObj.key = valu ...

  5. 【你不知道的javaScript 上卷 笔记5】javaScript中的this词法

    function foo() { console.log( a ); } function bar() { var a = 3; foo(); } var a = 2; bar(); 上面这段代码为什 ...

  6. 【你不知道的javaScript 上卷 笔记4】javaScript 中闭包的一些运用

    什么是闭包 闭包是javaScript语言的一种特性,在 javaScript 中以函数作为承接单元.当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行. fun ...

  7. 【你不知道的javaScript 上卷 笔记2】 javaScript 的作用域规则

    一.什么是词法作用域? 词法作用域是在定义词法阶段的作用域,就是由代码变量和作用域块写在哪里决定的,基本上词法分析器在处理代码时会保持作用域不变. 二.词法作用域特点 完全由写代码期间函数所声明的位置 ...

  8. 【你不知道的javaScript 上卷 笔记1】 javaScript 是如何工作的?

    一.什么是作用域? 作用域是用来存储变量以及方便寻找变量的一套规则. 二.javaScript 编译过程(编译发生在代码执行前的几微妙) 分词/词法分析(Tokenizing/Lexing)-> ...

  9. 《你不知道的 JavaScript 上卷》 学习笔记

    第一部分: 作用域和闭包 一.作用域 1. 作用域:存储变量并且查找变量的规则 2. 源代码在执行之前(编译)会经历三个步骤: 分词/此法分析:将代码字符串分解成有意义的代码块(词法单元) 解析/语法 ...

随机推荐

  1. HTML中超出文本使用省略号替代的CSS样式

    a{ display: block; /*定义显示形式*/ overflow: hidden; /*截取超出字符*/ text-overflow: ellipsis; /*超出字符以…代替*/ whi ...

  2. 解决Spring MVC @ResponseBody返回中文字符串乱码问题

    spring mvc使用的默认处理字符串编码为ISO-8859-1 解决方法: 第一种方法: 对于需要返回字符串的方法添加注解,如下: @RequestMapping(value="/use ...

  3. Web jquery表格组件 JQGrid 的使用 - 全部代码

    系列索引 Web jquery表格组件 JQGrid 的使用 - 从入门到精通 开篇及索引 Web jquery表格组件 JQGrid 的使用 - 4.JQGrid参数.ColModel API.事件 ...

  4. 关于application/x-www-form-urlencoded等字符编码的解释说明

    在Form元素的语法中,EncType表明提交数据的格式 用 Enctype 属性指定将数据回发到服务器时浏览器使用的编码类型. 下边是说明: application/x-www-form-urlen ...

  5. eclipse中 linked resource的使用

    一.关于linked resource   eclipse 中的linkded resources 是指存放在项目所在位置以外某个地方的文件或者文件夹:这些特定的资源必须有一个项目作为他们的父资源.l ...

  6. U盘安装Windows 7 + Ubuntu 14 双系统笔记

    第一个系统是Windows 7系统,现在采用U盘安装 Ubuntu 14,实现双系统,主要会用到3个软件: 1.DiskGenius - 磁盘修复.分区.调整分区工具,点击下载: 用这个工具先腾出一个 ...

  7. Windows中explorer(图形壳)

    explorer是Windows程序管理器或者文件资源管理器. 用于管理Windows图形壳.(桌面和文件管理.) 删除该程序会导致Windows图形界面无法使用. explorer.exe进程是微软 ...

  8. python之路二

    .pyc是个什么鬼? 1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存 ...

  9. Eclipse自动编译问题

    今天遇到一个很郁闷的问题,在程序中修改了一个String字符串,结果打断点是发现,还是修改之前的值,一点都没有变,最终发现该类在tomcat中的class的大小一直都没有变,只有修改时间在变,这才意识 ...

  10. C# 异步编程小结

    APM 异步编程模型,Asynchronous Programming Model EAP 基于事件的异步编程模式,Event-based Asynchronous Pattern TAP 基于任务的 ...