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);
 

最新文章

  1. linux中vi编辑器的使用
  2. easyui提交表单数据的时候如何防止二次提交
  3. JavaScript中伪协议 javascript:研究
  4. Codeforces Round #198 (Div. 2) C. Tourist Problem (数学+dp)
  5. Android---控制设备照相机
  6. BFS求最短路 Abbottt&#39;s Revenge UVa 816
  7. SpringCloud的DataRest(三)
  8. 力扣算法题—052N皇后问题2
  9. 【学习总结】之 3Blue1Brown系列
  10. 解决Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 问题
  11. 今天讲座的感悟--java
  12. ViewBag &amp; ViewData
  13. [专贴]Xshell 以及 shell 的快捷键
  14. python3 IEDriver抓取时报数据
  15. Spring学习13-中IOC(工厂模式)和AOP(代理模式)的详细解释
  16. mysqlsla 安装
  17. 35、def func(a,b=[]) 这种写法有什么坑?
  18. 剑指Offer——删除链表中重复的结点
  19. [ARC 066] Tutorial
  20. 使用Access作数据库

热门文章

  1. TAC Beta版本 冲冲冲!!!
  2. maven的eclise配置
  3. js读书笔记
  4. 如何接触学习java
  5. margin和padding的区别
  6. [Unity3d]游戏中子弹碰撞的处理
  7. UI第十四节——UIAlertController
  8. 如何给外部引用的js文件传递参数
  9. Unity3D代码旋转
  10. 记录一下两个比较常用的md5加密算法